Bug
RamCache.clear() performs two separate mutations — this.map.clear() then this.queue.clear() — with no lock held across both operations.
Root Cause
The clear() method does:
this.map.clear()
this.queue.clear()
Between step 1 and step 2, a concurrent write() call can insert a new entry into both map and queue. After queue.clear() runs, the map has the new entry but the queue doesn't — they are permanently out of sync.
Race Condition Walkthrough
- Thread A (clear): map.clear() -> map is now empty
- Thread B (write): map.put(id, queue.enqueue(...)) -> entry added to both
- Thread A (clear): queue.clear() -> removes B's entry from queue only
Result: map contains the new entry but queue does not. Subsequent access() calls find the node in the map, try to queue.remove(node), get null back — silent cache miss for data that is actually present.
Proposed Fix
Minimal fix (add synchronized to clear()):
@Override
public synchronized void clear() {
if (this.capacity() <= 0 || this.map.isEmpty()) {
return;
}
this.map.clear();
this.queue.clear();
}
Complete fix — introduce a ReadWriteLock:
- clear() acquires the write lock
- write(), access(), remove() acquire the read lock
Files to Touch
| File |
Change |
| RamCache.java |
Add synchronization to clear() |
Test Impact
1 test file needs a new concurrent test:
- CacheTest.java (in hugegraph-test module)
No existing tests should break — adding synchronized is purely additive.
Acceptance Criteria
Bug
RamCache.clear() performs two separate mutations — this.map.clear() then this.queue.clear() — with no lock held across both operations.
Root Cause
The
clear()method does:this.map.clear()this.queue.clear()Between step 1 and step 2, a concurrent write() call can insert a new entry into both map and queue. After queue.clear() runs, the map has the new entry but the queue doesn't — they are permanently out of sync.
Race Condition Walkthrough
Result: map contains the new entry but queue does not. Subsequent access() calls find the node in the map, try to queue.remove(node), get null back — silent cache miss for data that is actually present.
Proposed Fix
Minimal fix (add synchronized to clear()):
Complete fix — introduce a ReadWriteLock:
Files to Touch
Test Impact
1 test file needs a new concurrent test:
No existing tests should break — adding synchronized is purely additive.
Acceptance Criteria