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

cwylie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git


The following commit(s) were added to refs/heads/master by this push:
     new 7f001d8a09e fix vsf bug when restoring entries on a failed reclaim 
(#19160)
7f001d8a09e is described below

commit 7f001d8a09ef2e434f184e1b046814d3d4db4615
Author: Clint Wylie <[email protected]>
AuthorDate: Mon Mar 16 09:22:11 2026 -0700

    fix vsf bug when restoring entries on a failed reclaim (#19160)
---
 .../SeekableStreamSupervisorSpecTest.java          |  2 +-
 .../druid/segment/loading/StorageLocation.java     |  2 +-
 .../druid/segment/loading/StorageLocationTest.java | 27 ++++++++++++++++++++++
 3 files changed, 29 insertions(+), 2 deletions(-)

diff --git 
a/indexing-service/src/test/java/org/apache/druid/indexing/seekablestream/supervisor/SeekableStreamSupervisorSpecTest.java
 
b/indexing-service/src/test/java/org/apache/druid/indexing/seekablestream/supervisor/SeekableStreamSupervisorSpecTest.java
index baa5ca24050..f0bdac00a8c 100644
--- 
a/indexing-service/src/test/java/org/apache/druid/indexing/seekablestream/supervisor/SeekableStreamSupervisorSpecTest.java
+++ 
b/indexing-service/src/test/java/org/apache/druid/indexing/seekablestream/supervisor/SeekableStreamSupervisorSpecTest.java
@@ -1155,7 +1155,7 @@ public class SeekableStreamSupervisorSpecTest extends 
SeekableStreamSupervisorTe
       }
     };
 
-    // Mistmatched stream strings test
+    // Mismatched stream strings test
     MatcherAssert.assertThat(
         assertThrows(DruidException.class, () -> 
originalSpec.validateSpecUpdateTo(proposedSpecDiffSource)),
         new DruidExceptionMatcher(
diff --git 
a/server/src/main/java/org/apache/druid/segment/loading/StorageLocation.java 
b/server/src/main/java/org/apache/druid/segment/loading/StorageLocation.java
index 1e7f895d2d6..4cd8039d7bc 100644
--- a/server/src/main/java/org/apache/druid/segment/loading/StorageLocation.java
+++ b/server/src/main/java/org/apache/druid/segment/loading/StorageLocation.java
@@ -779,7 +779,7 @@ public class StorageLocation
     }
     // 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);
diff --git 
a/server/src/test/java/org/apache/druid/segment/loading/StorageLocationTest.java
 
b/server/src/test/java/org/apache/druid/segment/loading/StorageLocationTest.java
index be10cd93cf0..1c0babacb55 100644
--- 
a/server/src/test/java/org/apache/druid/segment/loading/StorageLocationTest.java
+++ 
b/server/src/test/java/org/apache/druid/segment/loading/StorageLocationTest.java
@@ -369,6 +369,33 @@ class StorageLocationTest
     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)
   {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to