Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1155,7 +1155,7 @@ public String getSource()
}
};

// Mistmatched stream strings test
// Mismatched stream strings test
MatcherAssert.assertThat(
assertThrows(DruidException.class, () -> originalSpec.validateSpecUpdateTo(proposedSpecDiffSource)),
new DruidExceptionMatcher(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -779,7 +779,7 @@ private ReclaimResult reclaimHelper(long sizeToReclaim, List<WeakCacheEntry> dro
}
// if we didn't free up enough space, return everything we removed to the cache
for (WeakCacheEntry entry : droppedEntries) {
linkNewWeakEntry(new WeakCacheEntry(entry.cacheEntry));
linkNewWeakEntry(entry);
weakCacheEntries.put(entry.cacheEntry.getId(), entry);
}
return ReclaimResult.failed(sizeToReclaim);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,33 @@ public void testReserveWeakExistsConcurrency() throws ExecutionException, Interr
Assertions.assertEquals(0, loc.getActiveWeakHolds());
}

@Test
public void testReclaimRestoreDoesNotCreateZombieEntries()
{
StorageLocation location = new StorageLocation(tempDir, 100L, null);
CacheEntry entry1 = new TestCacheEntry("1", 10);
CacheEntry entry2 = new TestCacheEntry("2", 90);
CacheEntry entry3 = new TestCacheEntry("3", 20);

location.reserveWeak(entry1);
// hold entry2 so it cannot be evicted by reclaim
StorageLocation.ReservationHold<?> hold2 = location.addWeakReservationHold(
entry2.getId(),
() -> entry2
);

// must free 20 bytes but can only evict entry1 (10). Fails and restores entry1
// where the bug was a mismatch caused by creating a new entry in the list but re-using the old entry for the map.
Assertions.assertFalse(location.reserveWeak(entry3));

// the hand pointer reaches the new entry1, removes the old entry1 from the map which is a zombie, then wraps around
// to the same zombie entry1 again since its head — at which point the map no longer contains the ID and the defensive exception was
// thrown.
Assertions.assertFalse(location.reserveWeak(entry3));

hold2.close();
}

@SuppressWarnings({"GuardedBy", "FieldAccessNotGuarded"})
private void verifyLoc(long maxSize, StorageLocation loc)
{
Expand Down
Loading