Skip to content

Commit

Permalink
Fixes #10211 - NPE in ArrayByteBufferPool.findOldestEntry() (#10212)
Browse files Browse the repository at this point in the history
* Fixes #10211 - NPE in ArrayByteBufferPool.findOldestEntry()

Fixed algorithm to check for oldest entry to avoid NPE.
Added comments for clarity.

Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
  • Loading branch information
sbordet committed Aug 2, 2023
1 parent 86312f1 commit 30ed83f
Showing 1 changed file with 19 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,8 @@ private void evict(boolean direct, long excess)

while (totalClearedCapacity < excess)
{
// Run through all the buckets to avoid removing
// the buffers only from the first bucket(s).
for (RetainedBucket bucket : buckets)
{
RetainedBucket.Entry oldestEntry = findOldestEntry(now, bucket);
Expand All @@ -390,13 +392,14 @@ private void evict(boolean direct, long excess)

if (oldestEntry.remove())
{
int clearedCapacity = oldestEntry.getPooled().capacity();
RetainableByteBuffer buffer = oldestEntry.getPooled();
int clearedCapacity = buffer.capacity();
if (direct)
_currentDirectMemory.addAndGet(-clearedCapacity);
else
_currentHeapMemory.addAndGet(-clearedCapacity);
totalClearedCapacity += clearedCapacity;
removed(oldestEntry.getPooled());
removed(buffer);
}
// else a concurrent thread evicted the same entry -> do not account for its capacity.
}
Expand Down Expand Up @@ -430,18 +433,25 @@ public void dump(Appendable out, String indent) throws IOException

private Pool<RetainableByteBuffer>.Entry findOldestEntry(long now, Pool<RetainableByteBuffer> bucket)
{
// This method may be in the hot path, do not use Java streams.

RetainedBucket.Entry oldestEntry = null;
RetainableByteBuffer oldestBuffer = null;
long oldestAge = 0;
for (RetainedBucket.Entry entry : bucket.values())
{
if (oldestEntry != null)
RetainableByteBuffer buffer = entry.getPooled();
// A null buffer means the entry is reserved
// but not acquired yet, try the next.
if (buffer != null)
{
long entryAge = NanoTime.elapsed(entry.getPooled().getLastUpdate(), now);
if (entryAge > NanoTime.elapsed(oldestEntry.getPooled().getLastUpdate(), now))
long age = NanoTime.elapsed(buffer.getLastUpdate(), now);
if (oldestBuffer == null || age > oldestAge)
{
oldestEntry = entry;
}
else
{
oldestEntry = entry;
oldestBuffer = buffer;
oldestAge = age;
}
}
}
return oldestEntry;
Expand Down

0 comments on commit 30ed83f

Please sign in to comment.