You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by lh...@apache.org on 2024/06/03 16:44:14 UTC

(pulsar) 03/03: [improve][ml] RangeCache refactoring follow-up: use StampedLock instead of synchronized (#22818)

This is an automated email from the ASF dual-hosted git repository.

lhotari pushed a commit to branch branch-3.3
in repository https://gitbox.apache.org/repos/asf/pulsar.git

commit d4114688ff60d1877f3164538d0b289938133a14
Author: Lari Hotari <lh...@users.noreply.github.com>
AuthorDate: Mon Jun 3 19:40:50 2024 +0300

    [improve][ml] RangeCache refactoring follow-up: use StampedLock instead of synchronized (#22818)
    
    (cherry picked from commit 208d8a53be20a95613703f0a11527ca9735e7bf8)
---
 .../apache/bookkeeper/mledger/util/RangeCache.java | 49 ++++++++++++++++------
 1 file changed, 37 insertions(+), 12 deletions(-)

diff --git a/managed-ledger/src/main/java/org/apache/bookkeeper/mledger/util/RangeCache.java b/managed-ledger/src/main/java/org/apache/bookkeeper/mledger/util/RangeCache.java
index 45295d71906..2f2b161a306 100644
--- a/managed-ledger/src/main/java/org/apache/bookkeeper/mledger/util/RangeCache.java
+++ b/managed-ledger/src/main/java/org/apache/bookkeeper/mledger/util/RangeCache.java
@@ -31,6 +31,7 @@ import java.util.Map;
 import java.util.concurrent.ConcurrentNavigableMap;
 import java.util.concurrent.ConcurrentSkipListMap;
 import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.locks.StampedLock;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.bookkeeper.mledger.util.RangeCache.ValueWithKeyValidation;
 import org.apache.commons.lang3.tuple.Pair;
@@ -75,6 +76,7 @@ public class RangeCache<Key extends Comparable<Key>, Value extends ValueWithKeyV
                 return new EntryWrapper(recyclerHandle);
             }
         };
+        private final StampedLock lock = new StampedLock();
         private K key;
         private V value;
         long size;
@@ -85,27 +87,50 @@ public class RangeCache<Key extends Comparable<Key>, Value extends ValueWithKeyV
 
         static <K, V> EntryWrapper<K, V> create(K key, V value, long size) {
             EntryWrapper<K, V> entryWrapper = RECYCLER.get();
-            synchronized (entryWrapper) {
-                entryWrapper.key = key;
-                entryWrapper.value = value;
-                entryWrapper.size = size;
-            }
+            long stamp = entryWrapper.lock.writeLock();
+            entryWrapper.key = key;
+            entryWrapper.value = value;
+            entryWrapper.size = size;
+            entryWrapper.lock.unlockWrite(stamp);
             return entryWrapper;
         }
 
-        synchronized K getKey() {
-            return key;
+        K getKey() {
+            long stamp = lock.tryOptimisticRead();
+            K localKey = key;
+            if (!lock.validate(stamp)) {
+                stamp = lock.readLock();
+                localKey = key;
+                lock.unlockRead(stamp);
+            }
+            return localKey;
         }
 
-        synchronized V getValue(K key) {
-            if (this.key != key) {
+        V getValue(K key) {
+            long stamp = lock.tryOptimisticRead();
+            K localKey = this.key;
+            V localValue = this.value;
+            if (!lock.validate(stamp)) {
+                stamp = lock.readLock();
+                localKey = this.key;
+                localValue = this.value;
+                lock.unlockRead(stamp);
+            }
+            if (localKey != key) {
                 return null;
             }
-            return value;
+            return localValue;
         }
 
-        synchronized long getSize() {
-            return size;
+        long getSize() {
+            long stamp = lock.tryOptimisticRead();
+            long localSize = size;
+            if (!lock.validate(stamp)) {
+                stamp = lock.readLock();
+                localSize = size;
+                lock.unlockRead(stamp);
+            }
+            return localSize;
         }
 
         void recycle() {