dao-jun opened a new issue, #4318:
URL: https://github.com/apache/bookkeeper/issues/4318

   **BUG REPORT**
   
   ***Describe the bug***
   
   
[ConcurrentLongHashMap](https://github.com/apache/bookkeeper/blob/master/bookkeeper-server/src/main/java/org/apache/bookkeeper/util/collections/ConcurrentLongHashMap.java),
 
[ConcurrentLongHashSet](https://github.com/apache/bookkeeper/blob/master/bookkeeper-server/src/main/java/org/apache/bookkeeper/util/collections/ConcurrentLongHashSet.java),[ConcurrentLongLongHashMap](https://github.com/apache/bookkeeper/blob/master/bookkeeper-server/src/main/java/org/apache/bookkeeper/util/collections/ConcurrentLongLongHashMap.java),
 
[ConcurrentLongLongPairHashMap](https://github.com/apache/bookkeeper/blob/master/bookkeeper-server/src/main/java/org/apache/bookkeeper/util/collections/ConcurrentLongLongPairHashMap.java),[ConcurrentOpenHashMap](https://github.com/apache/bookkeeper/blob/master/bookkeeper-server/src/main/java/org/apache/bookkeeper/util/collections/ConcurrentOpenHashMap.java)
 and 
[ConcurrentOpenHashSet](https://github.com/apache/bookkeeper/blob/master/bookkeeper-server/src/main/java/
 org/apache/bookkeeper/util/collections/ConcurrentOpenHashSet.java) 
   has the same issue refers to 
https://github.com/apache/bookkeeper/issues/4316.
   
   This issue caused by their `rehash` method, the inner class `Section` 
extends `StampedLock` for the purpose of performance optimization.
   
   We read entry from array without requires `lock` as following code(copy from 
ConcurrentLongHashMap) to optimize `read` operations:
   ```java
           V get(long key, int keyHash) {
               int bucket = keyHash;
   
               long stamp = tryOptimisticRead();
               boolean acquiredLock = false;
   
               try {
                   while (true) {
                       int capacity = this.capacity;
                       bucket = signSafeMod(bucket, capacity);
   
                       // First try optimistic locking
                       long storedKey = keys[bucket];
                       V storedValue = values[bucket];
                       // ignore.....
                       }
                    // ignore...
                    }
                   // ignore....
   ```
   
   The problem is 
   ```java
                       int capacity = this.capacity;
                       bucket = signSafeMod(bucket, capacity);
   ```
   and 
   ```java
                       // First try optimistic locking
                       long storedKey = keys[bucket];
                       V storedValue = values[bucket];
   ```
   are *not* in an atomic scope.
   
   If `rehash` method triggered in an async thread *after* calculating `bucket` 
and finished *before* read entry from the array, we can read incorrect values 
from arrays.
   
   Before https://github.com/apache/bookkeeper/pull/3074, it will only lead to 
read incorrect values, but https://github.com/apache/bookkeeper/pull/3074 
introduces `shrink`, the new arrays' capital can be smaller than before, so 
`ArrayIndexOutOfBoundsExeception` happens.
   
   
   The issue can be fixed with a same pattern, see 
https://github.com/apache/bookkeeper/pull/4317/files#diff-1214718241c7ea351d22fa5806ba112c64d64183fe2f091976d6165c4573d05a
   
   ***To Reproduce***
   
   Steps to reproduce the behavior:
   1. Go to '...'
   2. Click on '....'
   3. Scroll down to '....'
   4. See error
   
   ***Expected behavior***
   
   A clear and concise description of what you expected to happen.
   
   ***Screenshots***
   
   If applicable, add screenshots to help explain your problem.
   
   ***Additional context***
   
   Add any other context about the problem here.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to