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 c44eb23725c virtual storage improvements (#18683)
c44eb23725c is described below

commit c44eb23725c53c1cc4cf3444aeec6e697d1225a3
Author: Clint Wylie <[email protected]>
AuthorDate: Fri Oct 24 11:54:14 2025 -0700

    virtual storage improvements (#18683)
    
    changes:
    * in virtual storage mode, it is now impossible for a segment to be 
'missing' after a caller has obtained a `DataSegment`. Now, the caller can 
still mount and use a segment (downloading it if necessary) even if the 
coordinator has issued a drop command
    * to support there being no such thing as a missing segment in vsf mode, 
drops of weakly held cache entries in a storage location are now a no-op. 
instead, these cache entries will remain on disk until an eviction needs to 
reclaim the space for some other entry
---
 .../segment/loading/SegmentLocalCacheManager.java  |  81 ++++++++++++++-
 .../druid/segment/loading/StorageLocation.java     |  37 +++++--
 .../SegmentLocalCacheManagerConcurrencyTest.java   |  42 +++++++-
 .../loading/SegmentLocalCacheManagerTest.java      | 110 ++++++++++++++++++++-
 .../druid/segment/loading/StorageLocationTest.java |  31 +++---
 5 files changed, 269 insertions(+), 32 deletions(-)

diff --git 
a/server/src/main/java/org/apache/druid/segment/loading/SegmentLocalCacheManager.java
 
b/server/src/main/java/org/apache/druid/segment/loading/SegmentLocalCacheManager.java
index 104304dce6a..67c30e779e7 100644
--- 
a/server/src/main/java/org/apache/druid/segment/loading/SegmentLocalCacheManager.java
+++ 
b/server/src/main/java/org/apache/druid/segment/loading/SegmentLocalCacheManager.java
@@ -62,6 +62,7 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
 import java.util.concurrent.locks.Lock;
 import java.util.function.Supplier;
 
@@ -284,12 +285,38 @@ public class SegmentLocalCacheManager implements 
SegmentCacheManager
   {
     final File segmentInfoCacheFile = new File(getEffectiveInfoDir(), 
segment.getId().toString());
     if (!segmentInfoCacheFile.exists()) {
-      jsonMapper.writeValue(segmentInfoCacheFile, segment);
+      FileUtils.writeAtomically(
+          segmentInfoCacheFile,
+          out -> {
+            jsonMapper.writeValue(out, segment);
+            return null;
+          }
+      );
     }
   }
 
   @Override
   public void removeInfoFile(final DataSegment segment)
+  {
+    final Runnable delete = () -> deleteSegmentInfoFile(segment);
+    final SegmentCacheEntryIdentifier entryId = new 
SegmentCacheEntryIdentifier(segment.getId());
+    boolean isCached = false;
+    // defer deleting until the unmount operation of the cache entry, if 
possible, so that if the process stops before
+    // the segment files are deleted, they can be properly managed on startup 
(since the info entry still exists)
+    for (StorageLocation location : locations) {
+      final SegmentCacheEntry cacheEntry = location.getCacheEntry(entryId);
+      if (cacheEntry != null) {
+        isCached = isCached || cacheEntry.setOnUnmount(delete);
+      }
+    }
+
+    // otherwise we are probably deleting for cleanup reasons, so try it 
anyway if it wasn't present in any location
+    if (!isCached) {
+      delete.run();
+    }
+  }
+
+  private void deleteSegmentInfoFile(DataSegment segment)
   {
     final File segmentInfoCacheFile = new File(getEffectiveInfoDir(), 
segment.getId().toString());
     if (!segmentInfoCacheFile.delete()) {
@@ -310,7 +337,6 @@ public class SegmentLocalCacheManager implements 
SegmentCacheManager
           location.addWeakReservationHoldIfExists(cacheEntryIdentifier);
       try {
         if (hold != null) {
-
           if (hold.getEntry().isMounted()) {
             Optional<Segment> segment = hold.getEntry().acquireReference();
             if (segment.isPresent()) {
@@ -362,6 +388,16 @@ public class SegmentLocalCacheManager implements 
SegmentCacheManager
           );
           try {
             if (hold != null) {
+              // write the segment info file if it doesn't exist. this can 
happen if we are loading after a drop
+              final File segmentInfoCacheFile = new 
File(getEffectiveInfoDir(), dataSegment.getId().toString());
+              if (!segmentInfoCacheFile.exists()) {
+                FileUtils.writeAtomically(segmentInfoCacheFile, out -> {
+                  jsonMapper.writeValue(out, dataSegment);
+                  return null;
+                });
+                hold.getEntry().setOnUnmount(() -> 
deleteSegmentInfoFile(dataSegment));
+              }
+
               return new AcquireSegmentAction(
                   makeOnDemandLoadSupplier(hold.getEntry(), location),
                   hold
@@ -421,7 +457,23 @@ public class SegmentLocalCacheManager implements 
SegmentCacheManager
   public void load(final DataSegment dataSegment) throws 
SegmentLoadingException
   {
     if (config.isVirtualStorage()) {
-      // no-op, we'll do a load when someone asks for the segment
+      // virtual storage doesn't do anything with loading immediately, but 
check to see if the segment is already cached
+      // and if so, clear out the onUnmount action
+      final ReferenceCountingLock lock = lock(dataSegment);
+      synchronized (lock) {
+        try {
+          final SegmentCacheEntryIdentifier cacheEntryIdentifier = new 
SegmentCacheEntryIdentifier(dataSegment.getId());
+          for (StorageLocation location : locations) {
+            final SegmentCacheEntry cacheEntry = 
location.getCacheEntry(cacheEntryIdentifier);
+            if (cacheEntry != null) {
+              cacheEntry.clearOnUnmount();
+            }
+          }
+        }
+        finally {
+          unlock(dataSegment, lock);
+        }
+      }
       return;
     }
     final SegmentCacheEntry cacheEntry = new SegmentCacheEntry(dataSegment);
@@ -456,6 +508,7 @@ public class SegmentLocalCacheManager implements 
SegmentCacheManager
             final SegmentCacheEntry entry = location.getCacheEntry(id);
             if (entry != null) {
               entry.lazyLoadCallback = loadFailed;
+              entry.clearOnUnmount();
               entry.mount(location);
             }
           }
@@ -658,6 +711,7 @@ public class SegmentLocalCacheManager implements 
SegmentCacheManager
             final SegmentCacheEntry entry = 
location.getCacheEntry(cacheEntry.id);
             if (entry != null) {
               entry.lazyLoadCallback = segmentLoadFailCallback;
+              entry.clearOnUnmount();
               entry.mount(location);
               return entry;
             }
@@ -679,6 +733,7 @@ public class SegmentLocalCacheManager implements 
SegmentCacheManager
           final SegmentCacheEntry entry = 
location.getCacheEntry(cacheEntry.id);
           if (entry != null) {
             entry.lazyLoadCallback = segmentLoadFailCallback;
+            entry.clearOnUnmount();
             entry.mount(location);
             return entry;
           }
@@ -771,6 +826,7 @@ public class SegmentLocalCacheManager implements 
SegmentCacheManager
     private StorageLocation location;
     private File storageDir;
     private ReferenceCountedSegmentProvider referenceProvider;
+    private final AtomicReference<Runnable> onUnmount = new 
AtomicReference<>();
 
     private SegmentCacheEntry(final DataSegment dataSegment)
     {
@@ -921,6 +977,11 @@ public class SegmentLocalCacheManager implements 
SegmentCacheManager
             storageDir = null;
             location = null;
           }
+
+          final Runnable onUnmountRunnable = onUnmount.get();
+          if (onUnmountRunnable != null) {
+            onUnmountRunnable.run();
+          }
         }
       }
       finally {
@@ -936,6 +997,20 @@ public class SegmentLocalCacheManager implements 
SegmentCacheManager
       return referenceProvider.acquireReference();
     }
 
+    public synchronized boolean setOnUnmount(Runnable runnable)
+    {
+      if (location == null) {
+        return false;
+      }
+      onUnmount.set(runnable);
+      return true;
+    }
+
+    public synchronized void clearOnUnmount()
+    {
+      onUnmount.set(null);
+    }
+
     public void loadIntoPageCache()
     {
       if (!isMounted()) {
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 15a9f6eb477..5d51de581a4 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
@@ -419,23 +419,18 @@ public class StorageLocation
   }
 
   /**
-   * Removes an item from {@link #staticCacheEntries} or {@link 
#weakCacheEntries}, reducing {@link #currSizeBytes}
-   * by {@link CacheEntry#getSize()}
+   * Removes an item from {@link #staticCacheEntries}, reducing {@link 
#currSizeBytes} by {@link CacheEntry#getSize()}.
+   * If the cache entry exists in {@link #weakCacheEntries}, it is left in 
place to be removed by
+   * {@link #reclaim(long)} instead.
    */
   public void release(CacheEntry entry)
   {
     lock.writeLock().lock();
     try {
-
       if (staticCacheEntries.containsKey(entry.getId())) {
         final CacheEntry toRemove = staticCacheEntries.remove(entry.getId());
         toRemove.unmount();
         currSizeBytes.getAndAdd(-entry.getSize());
-      } else if (weakCacheEntries.containsKey(entry.getId())) {
-        final WeakCacheEntry toRemove = weakCacheEntries.remove(entry.getId());
-        unlinkWeakEntry(toRemove);
-        toRemove.unmount();
-        stats.get().unmount();
       }
     }
     finally {
@@ -615,6 +610,32 @@ public class StorageLocation
     }
   }
 
+  /**
+   * Unmounts all static and weakly held cache entries and resets stats and 
size tracking. Currently only for testing.
+   */
+  @VisibleForTesting
+  public void reset()
+  {
+    lock.writeLock().lock();
+    try {
+      for (CacheEntry entry : staticCacheEntries.values()) {
+        entry.unmount();
+      }
+      staticCacheEntries.clear();
+      while (head != null) {
+        head.unmount();
+        head = head.next;
+      }
+      weakCacheEntries.clear();
+    }
+    finally {
+      lock.writeLock().unlock();
+    }
+    currSizeBytes.set(0);
+    currWeakSizeBytes.set(0);
+    resetStats();
+  }
+
   public Stats getStats()
   {
     return stats.get();
diff --git 
a/server/src/test/java/org/apache/druid/segment/loading/SegmentLocalCacheManagerConcurrencyTest.java
 
b/server/src/test/java/org/apache/druid/segment/loading/SegmentLocalCacheManagerConcurrencyTest.java
index 298e9ad0a04..366b3cbbc33 100644
--- 
a/server/src/test/java/org/apache/druid/segment/loading/SegmentLocalCacheManagerConcurrencyTest.java
+++ 
b/server/src/test/java/org/apache/druid/segment/loading/SegmentLocalCacheManagerConcurrencyTest.java
@@ -27,6 +27,7 @@ import com.google.common.collect.ImmutableMap;
 import org.apache.druid.error.DruidException;
 import org.apache.druid.jackson.DefaultObjectMapper;
 import org.apache.druid.java.util.common.DateTimes;
+import org.apache.druid.java.util.common.FileUtils;
 import org.apache.druid.java.util.common.Intervals;
 import org.apache.druid.java.util.common.StringUtils;
 import org.apache.druid.java.util.common.concurrent.Execs;
@@ -78,6 +79,8 @@ class SegmentLocalCacheManagerConcurrencyTest
 
   private File localSegmentCacheFolder;
   private File otherLocalSegmentCacheFolder;
+  private SegmentLoaderConfig loaderConfig;
+  private SegmentLoaderConfig vsfLoaderConfig;
   private SegmentLocalCacheManager manager;
   private SegmentLocalCacheManager virtualStorageManager;
   private StorageLocation location;
@@ -127,8 +130,21 @@ class SegmentLocalCacheManagerConcurrencyTest
     locations.add(locationConfig);
     locations.add(locationConfig2);
 
-    final SegmentLoaderConfig loaderConfig = new 
SegmentLoaderConfig().withLocations(locations);
-    final SegmentLoaderConfig vsfLoaderConfig = new SegmentLoaderConfig()
+    loaderConfig = new SegmentLoaderConfig()
+    {
+      @Override
+      public List<StorageLocationConfig> getLocations()
+      {
+        return locations;
+      }
+
+      @Override
+      public File getInfoDir()
+      {
+        return new File(tempDir, "info");
+      }
+    };
+    vsfLoaderConfig = new SegmentLoaderConfig()
     {
       @Override
       public List<StorageLocationConfig> getLocations()
@@ -147,6 +163,12 @@ class SegmentLocalCacheManagerConcurrencyTest
       {
         return Runtime.getRuntime().availableProcessors();
       }
+
+      @Override
+      public File getInfoDir()
+      {
+        return new File(tempDir, "info");
+      }
     };
     final List<StorageLocation> storageLocations = 
loaderConfig.toStorageLocations();
     location = storageLocations.get(0);
@@ -165,6 +187,8 @@ class SegmentLocalCacheManagerConcurrencyTest
         TestIndex.INDEX_IO,
         jsonMapper
     );
+    manager.getCachedSegments();
+    virtualStorageManager.getCachedSegments();
     executorService = Execs.multiThreaded(
         10,
         "segment-loader-local-cache-manager-concurrency-test-%d"
@@ -346,10 +370,10 @@ class SegmentLocalCacheManagerConcurrencyTest
     final File localStorageFolder = new File(tempDir, "local_storage_folder");
 
     final Interval interval = Intervals.of("2019-01-01/P1D");
-
     makeSegmentsToLoad(segmentCount, localStorageFolder, interval, 
segmentsToWeakLoad);
 
     for (boolean sleepy : new boolean[]{true, false}) {
+      // use different segments for each run, otherwise the 2nd run is all 
cache hits
       testWeakLoad(iterations, segmentCount, concurrentReads, true, sleepy, 
true);
     }
   }
@@ -562,8 +586,8 @@ class SegmentLocalCacheManagerConcurrencyTest
     for (DataSegment segment : segmentsToWeakLoad) {
       virtualStorageManager.drop(segment);
     }
-    location.resetStats();
-    location2.resetStats();
+    location.reset();
+    location2.reset();
     for (int i = 0; i < iterations; i++) {
       int segment = random ? ThreadLocalRandom.current().nextInt(segmentCount) 
: i % segmentCount;
       currentBatch.add(segmentsToWeakLoad.get(segment));
@@ -619,6 +643,14 @@ class SegmentLocalCacheManagerConcurrencyTest
     }
 
     assertNoLooseEnds();
+
+    try {
+      FileUtils.deleteDirectory(location.getPath());
+      FileUtils.deleteDirectory(location2.getPath());
+    }
+    catch (IOException e) {
+      throw new RuntimeException(e);
+    }
   }
 
   private BatchResult testWeakBatch(int iteration, List<DataSegment> 
currentBatch, boolean sleepy)
diff --git 
a/server/src/test/java/org/apache/druid/segment/loading/SegmentLocalCacheManagerTest.java
 
b/server/src/test/java/org/apache/druid/segment/loading/SegmentLocalCacheManagerTest.java
index 04eafa41ed7..290de1934f2 100644
--- 
a/server/src/test/java/org/apache/druid/segment/loading/SegmentLocalCacheManagerTest.java
+++ 
b/server/src/test/java/org/apache/druid/segment/loading/SegmentLocalCacheManagerTest.java
@@ -893,6 +893,17 @@ public class SegmentLocalCacheManagerTest extends 
InitializedNullHandlingTest
       {
         return true;
       }
+
+      @Override
+      public File getInfoDir()
+      {
+        try {
+          return tmpFolder.newFolder();
+        }
+        catch (IOException e) {
+          throw new RuntimeException(e);
+        }
+      }
     };
     final List<StorageLocation> storageLocations = 
loaderConfig.toStorageLocations();
     SegmentLocalCacheManager manager = new SegmentLocalCacheManager(
@@ -920,7 +931,8 @@ public class SegmentLocalCacheManagerTest extends 
InitializedNullHandlingTest
     segmentAction.close();
 
     manager.drop(segmentToLoad);
-    Assert.assertNull(manager.getSegmentFiles(segmentToLoad));
+    // drop doesn't really drop, segments hang out until evicted
+    Assert.assertNotNull(manager.getSegmentFiles(segmentToLoad));
 
     // can actually load them again because load doesn't really do anything
     AcquireSegmentAction segmentActionAfterDrop = 
manager.acquireSegment(segmentToLoad);
@@ -952,6 +964,17 @@ public class SegmentLocalCacheManagerTest extends 
InitializedNullHandlingTest
       {
         return true;
       }
+
+      @Override
+      public File getInfoDir()
+      {
+        try {
+          return tmpFolder.newFolder();
+        }
+        catch (IOException e) {
+          throw new RuntimeException(e);
+        }
+      }
     };
     final List<StorageLocation> storageLocations = 
loaderConfig.toStorageLocations();
     SegmentLocalCacheManager manager = new SegmentLocalCacheManager(
@@ -979,7 +1002,8 @@ public class SegmentLocalCacheManagerTest extends 
InitializedNullHandlingTest
     segmentAction.close();
 
     manager.drop(segmentToBootstrap);
-    Assert.assertNull(manager.getSegmentFiles(segmentToBootstrap));
+    // drop doesn't really drop, segments hang out until evicted
+    Assert.assertNotNull(manager.getSegmentFiles(segmentToBootstrap));
 
     // can actually load them again because bootstrap doesn't really do 
anything unless the segment is already
     // present in the cache
@@ -1072,6 +1096,88 @@ public class SegmentLocalCacheManagerTest extends 
InitializedNullHandlingTest
     Assert.assertNull(manager.getSegmentFiles(segmentToLoad));
   }
 
+  @Test
+  public void testGetSegmentVirtualStorageMountAfterDrop() throws Exception
+  {
+    final StorageLocationConfig locationConfig = new 
StorageLocationConfig(localSegmentCacheDir, 10L, null);
+    final SegmentLoaderConfig loaderConfig = new SegmentLoaderConfig()
+    {
+      @Override
+      public List<StorageLocationConfig> getLocations()
+      {
+        return ImmutableList.of(locationConfig);
+      }
+
+      @Override
+      public boolean isVirtualStorage()
+      {
+        return true;
+      }
+
+      @Override
+      public File getInfoDir()
+      {
+        try {
+          return tmpFolder.newFolder();
+        }
+        catch (IOException e) {
+          throw new RuntimeException(e);
+        }
+      }
+    };
+    final List<StorageLocation> storageLocations = 
loaderConfig.toStorageLocations();
+    SegmentLocalCacheManager manager = new SegmentLocalCacheManager(
+        storageLocations,
+        loaderConfig,
+        new LeastBytesUsedStorageLocationSelectorStrategy(storageLocations),
+        TestHelper.getTestIndexIO(jsonMapper, ColumnConfig.DEFAULT),
+        jsonMapper
+    );
+
+    final DataSegment segmentToLoad = 
makeTestDataSegment(segmentDeepStorageDir);
+    createSegmentZipInLocation(segmentDeepStorageDir, TEST_DATA_RELATIVE_PATH);
+
+    manager.load(segmentToLoad);
+    Assert.assertNull(manager.getSegmentFiles(segmentToLoad));
+    
Assert.assertFalse(manager.acquireCachedSegment(segmentToLoad).isPresent());
+    AcquireSegmentAction segmentAction = manager.acquireSegment(segmentToLoad);
+
+    // now drop it before we actually load it, but dropping a weakly held 
reference does not remove the entry from the
+    // cache, deferring it until eviction
+    manager.drop(segmentToLoad);
+
+    // however, we also have a hold, so it will not be evicted
+    final DataSegment cannotLoad = makeTestDataSegment(segmentDeepStorageDir, 
1, TEST_DATA_RELATIVE_PATH_2);
+    Assert.assertThrows(DruidException.class, () -> 
manager.acquireSegment(cannotLoad));
+
+    // and we can still mount and use the segment we are holding
+    ReferenceCountedObjectProvider<Segment> referenceProvider = 
segmentAction.getSegmentFuture().get();
+    Assert.assertNotNull(referenceProvider);
+    Optional<Segment> theSegment = referenceProvider.acquireReference();
+    Assert.assertTrue(theSegment.isPresent());
+    Assert.assertNotNull(manager.getSegmentFiles(segmentToLoad));
+    Assert.assertEquals(segmentToLoad.getId(), theSegment.get().getId());
+    Assert.assertEquals(segmentToLoad.getInterval(), 
theSegment.get().getDataInterval());
+    theSegment.get().close();
+    segmentAction.close();
+    Assert.assertNotNull(manager.getSegmentFiles(segmentToLoad));
+
+    // now that the hold has been released, we can load the other segment and 
evict the one that was held
+    createSegmentZipInLocation(segmentDeepStorageDir, 
TEST_DATA_RELATIVE_PATH_2);
+    manager.load(cannotLoad);
+    AcquireSegmentAction segmentActionAfterDrop = 
manager.acquireSegment(cannotLoad);
+    ReferenceCountedObjectProvider<Segment> referenceProviderDrop = 
segmentActionAfterDrop.getSegmentFuture().get();
+    Optional<Segment> theSegmentAfterDrop = 
referenceProviderDrop.acquireReference();
+    Assert.assertTrue(theSegmentAfterDrop.isPresent());
+    Assert.assertNotNull(manager.getSegmentFiles(cannotLoad));
+    Assert.assertEquals(cannotLoad.getId(), theSegmentAfterDrop.get().getId());
+    Assert.assertEquals(cannotLoad.getInterval(), 
theSegmentAfterDrop.get().getDataInterval());
+    Assert.assertNull(manager.getSegmentFiles(segmentToLoad));
+
+    theSegmentAfterDrop.get().close();
+    segmentActionAfterDrop.close();
+  }
+
   @Test
   public void testIfTombstoneIsLoaded() throws IOException, 
SegmentLoadingException
   {
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 a1d459d1ec1..be10cd93cf0 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
@@ -106,10 +106,11 @@ class StorageLocationTest
     location.release(entry2);
     location.release(entry3);
     location.release(entry4);
-    Assertions.assertFalse(location.isWeakReserved(entry1.getId()));
-    Assertions.assertFalse(location.isWeakReserved(entry2.getId()));
-    Assertions.assertFalse(location.isWeakReserved(entry3.getId()));
-    Assertions.assertFalse(location.isWeakReserved(entry4.getId()));
+    // release does not remove weak entries
+    Assertions.assertTrue(location.isWeakReserved(entry1.getId()));
+    Assertions.assertTrue(location.isWeakReserved(entry2.getId()));
+    Assertions.assertTrue(location.isWeakReserved(entry3.getId()));
+    Assertions.assertTrue(location.isWeakReserved(entry4.getId()));
   }
 
   @Test
@@ -133,10 +134,11 @@ class StorageLocationTest
     location.release(entry3);
     location.release(entry2);
     location.release(entry1);
-    Assertions.assertFalse(location.isWeakReserved(entry1.getId()));
-    Assertions.assertFalse(location.isWeakReserved(entry2.getId()));
-    Assertions.assertFalse(location.isWeakReserved(entry3.getId()));
-    Assertions.assertFalse(location.isWeakReserved(entry4.getId()));
+    // release does not remove weak entries
+    Assertions.assertTrue(location.isWeakReserved(entry1.getId()));
+    Assertions.assertTrue(location.isWeakReserved(entry2.getId()));
+    Assertions.assertTrue(location.isWeakReserved(entry3.getId()));
+    Assertions.assertTrue(location.isWeakReserved(entry4.getId()));
   }
 
   @Test
@@ -167,12 +169,13 @@ class StorageLocationTest
       location.release(entry);
       entries.remove(toRemove);
     }
-    Assertions.assertFalse(location.isWeakReserved(entry1.getId()));
-    Assertions.assertFalse(location.isWeakReserved(entry2.getId()));
-    Assertions.assertFalse(location.isWeakReserved(entry3.getId()));
-    Assertions.assertFalse(location.isWeakReserved(entry4.getId()));
-    Assertions.assertEquals(0, location.currentSizeBytes());
-    Assertions.assertEquals(0, location.currentWeakSizeBytes());
+    // release does not remove weak entries
+    Assertions.assertTrue(location.isWeakReserved(entry1.getId()));
+    Assertions.assertTrue(location.isWeakReserved(entry2.getId()));
+    Assertions.assertTrue(location.isWeakReserved(entry3.getId()));
+    Assertions.assertTrue(location.isWeakReserved(entry4.getId()));
+    Assertions.assertEquals(100, location.currentSizeBytes());
+    Assertions.assertEquals(100, location.currentWeakSizeBytes());
   }
 
   @Test


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

Reply via email to