This is an automated email from the ASF dual-hosted git repository.
gian 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 cef1d031759 add hold metrics to StorageMonitor, fix some issues with
StorageLocation (#19217)
cef1d031759 is described below
commit cef1d031759a96132345c1a8587b6f19aa1e3b25
Author: Clint Wylie <[email protected]>
AuthorDate: Fri Mar 27 14:48:10 2026 -0700
add hold metrics to StorageMonitor, fix some issues with StorageLocation
(#19217)
---
.../druid/segment/loading/StorageLocation.java | 184 ++++++++++++++-------
.../loading/VirtualStorageLocationStats.java | 15 ++
.../druid/server/metrics/StorageMonitor.java | 4 +
.../SegmentLocalCacheManagerConcurrencyTest.java | 28 ++--
.../druid/segment/loading/StorageLocationTest.java | 22 ++-
5 files changed, 179 insertions(+), 74 deletions(-)
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 4cd8039d7bc..fff6516e067 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
@@ -34,6 +34,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Phaser;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReadWriteLock;
@@ -119,6 +120,8 @@ public class StorageLocation
private final AtomicLong currSizeBytes = new AtomicLong(0);
private final AtomicLong currStaticSizeBytes = new AtomicLong(0);
private final AtomicLong currWeakSizeBytes = new AtomicLong(0);
+ private final AtomicLong currHoldCount = new AtomicLong(0);
+ private final AtomicLong currHoldBytes = new AtomicLong(0);
private final AtomicReference<StaticStats> staticStats = new
AtomicReference<>();
private final AtomicReference<WeakStats> weakStats = new AtomicReference<>();
@@ -272,9 +275,7 @@ public class StorageLocation
unmountReclaimed(reclaimResult);
if (reclaimResult.isSuccess()) {
staticCacheEntries.put(entry.getId(), entry);
- currSizeBytes.getAndAdd(entry.getSize());
- currStaticSizeBytes.getAndAdd(entry.getSize());
- staticStats.getAndUpdate(s -> s.load(entry.getSize()));
+ trackLoad(entry);
}
return reclaimResult.isSuccess();
}
@@ -351,6 +352,7 @@ public class StorageLocation
WeakCacheEntry existingEntry = weakCacheEntries.get(entryId);
if (existingEntry != null && existingEntry.hold()) {
existingEntry.visited = true;
+ trackWeakHold(existingEntry);
weakStats.getAndUpdate(s -> s.hit(existingEntry.cacheEntry.getSize()));
return new ReservationHold<>(
(T) existingEntry.cacheEntry,
@@ -388,6 +390,7 @@ public class StorageLocation
WeakCacheEntry retryExistingEntry = weakCacheEntries.get(entryId);
if (retryExistingEntry != null && retryExistingEntry.hold()) {
retryExistingEntry.visited = true;
+ trackWeakHold(retryExistingEntry);
weakStats.getAndUpdate(s ->
s.hit(retryExistingEntry.cacheEntry.getSize()));
return new ReservationHold<>(
(T) retryExistingEntry.cacheEntry,
@@ -403,6 +406,7 @@ public class StorageLocation
newWeakEntry.hold();
linkNewWeakEntry(newWeakEntry);
weakCacheEntries.put(newEntry.getId(), newWeakEntry);
+ trackWeakHold(newWeakEntry);
weakStats.getAndUpdate(s -> s.load(newEntry.getSize()));
hold = new ReservationHold<>(
(T) newEntry,
@@ -431,9 +435,7 @@ public class StorageLocation
if (staticCacheEntries.containsKey(entry.getId())) {
final CacheEntry toRemove = staticCacheEntries.remove(entry.getId());
toRemove.unmount();
- currSizeBytes.getAndAdd(-entry.getSize());
- currStaticSizeBytes.getAndAdd(-entry.getSize());
- staticStats.getAndUpdate(s -> s.drop(entry.getSize()));
+ trackDrop(entry);
}
}
finally {
@@ -443,7 +445,7 @@ public class StorageLocation
/**
* Creates a release runnable for a {@link WeakCacheEntry} that handles
immediate eviction when configured.
- * If {@link #evictImmediately} is true and there are no more holds after
releasing, the entry is immediately
+ * If {@link #areWeakEntriesEphemeral} is true and there are no more holds
after releasing, the entry is immediately
* evicted from the cache. For new entries (isNewEntry=true), unmounted
entries are also removed.
*/
private Runnable createWeakEntryReleaseRunnable(
@@ -453,6 +455,7 @@ public class StorageLocation
{
return () -> {
weakEntry.release();
+ trackWeakRelease(weakEntry);
if (!isNewEntry && !areWeakEntriesEphemeral) {
// No need to consider removal from weakCacheEntries on hold release.
@@ -503,8 +506,7 @@ public class StorageLocation
hand = newWeakEntry;
}
head = newWeakEntry;
- currWeakSizeBytes.getAndAdd(newWeakEntry.cacheEntry.getSize());
- currSizeBytes.getAndAdd(newWeakEntry.cacheEntry.getSize());
+ trackWeakLoad(newWeakEntry);
}
/**
@@ -530,8 +532,7 @@ public class StorageLocation
}
toRemove.prev = null;
toRemove.next = null;
- currSizeBytes.getAndAdd(-toRemove.cacheEntry.getSize());
- currWeakSizeBytes.getAndAdd(-toRemove.cacheEntry.getSize());
+ trackWeakEvict(toRemove);
}
/**
@@ -564,11 +565,26 @@ public class StorageLocation
{
List<WeakCacheEntry> evicted = new ArrayList<>();
long bytesReclaimed = 0;
+ long sizeToReclaim = 0;
+ long currFreeSpace = 0;
+ boolean freeSpaceConstrained = false;
if (availableSizeBytes() < entry.getSize()) {
- long sizeToReclaim = entry.getSize() - availableSizeBytes();
+ sizeToReclaim = entry.getSize() - availableSizeBytes();
+ }
+
+ if (freeSpaceToKeep > 0) {
+ currFreeSpace = path.getFreeSpace();
+ long diskNeed = (freeSpaceToKeep + entry.getSize()) - currFreeSpace;
+ if (diskNeed > sizeToReclaim) {
+ sizeToReclaim = diskNeed;
+ freeSpaceConstrained = true;
+ }
+ }
+
+ if (sizeToReclaim > 0) {
final ReclaimResult result = reclaim(sizeToReclaim);
if (!result.isSuccess()) {
- final String msg = StringUtils.format(
+ String msg = StringUtils.format(
"Cache entry[%s:%,d] too large for storage[%s:%,d/%,d]",
entry.getId(),
entry.getSize(),
@@ -576,45 +592,33 @@ public class StorageLocation
availableSizeBytes(),
maxSizeBytes
);
+ if (freeSpaceConstrained) {
+ // append additional information if constrained by free space
+ msg = StringUtils.format(
+ "%s to maintain suggested freeSpace[%d], current freeSpace is
[%d].",
+ msg,
+ freeSpaceToKeep,
+ currFreeSpace
+ );
+ }
+
+ // only warn when this is false for static entries
if (weak) {
log.debug(msg);
} else {
log.warn(msg);
}
+
+ // make a new failed result with the total size we were trying to
free, since the size on
+ // reclaim result returned from reclaim method is the 'size left' it
needed to reclaim when
+ // it failed. Note result.getEvictions() will always be empty for a
failed result
return ReclaimResult.failed(sizeToReclaim);
}
bytesReclaimed += result.bytesReclaimed;
evicted.addAll(result.getEvictions());
}
- if (freeSpaceToKeep > 0) {
- long currFreeSpace = path.getFreeSpace();
- if ((freeSpaceToKeep + entry.getSize()) > currFreeSpace) {
- final ReclaimResult result = reclaim(freeSpaceToKeep +
entry.getSize());
- if (!result.isSuccess()) {
- final String msg = StringUtils.format(
- "Cache entry[%s:%,d] too large for storage[%s:%,d/%,d] to
maintain suggested freeSpace[%d], current freeSpace is [%d].",
- entry.getId(),
- entry.getSize(),
- getPath(),
- availableSizeBytes(),
- maxSizeBytes,
- freeSpaceToKeep,
- currFreeSpace
- );
- if (weak) {
- log.debug(msg);
- } else {
- log.warn(msg);
- }
- return ReclaimResult.failed(freeSpaceToKeep + entry.getSize());
- }
- bytesReclaimed += result.bytesReclaimed;
- evicted.addAll(result.getEvictions());
- }
- }
-
- return new ReclaimResult(true, entry.getSize(), bytesReclaimed, evicted);
+ return ReclaimResult.success(entry.getSize(), bytesReclaimed, evicted);
}
@GuardedBy("lock")
@@ -625,6 +629,9 @@ public class StorageLocation
weakCacheEntries.computeIfAbsent(
removed.cacheEntry.getId(),
cacheEntryIdentifier -> {
+ // we evicted this entry from the weak cache no matter what if
it was here
+ weakStats.getAndUpdate(s ->
s.evict(removed.cacheEntry.getSize()));
+ // .. but make sure the same identifier wasn't moved to a static
load before we actually unmount it
if (!staticCacheEntries.containsKey(cacheEntryIdentifier)) {
removed.unmount();
weakStats.getAndUpdate(WeakStats::unmount);
@@ -636,23 +643,50 @@ public class StorageLocation
}
}
- public int getWeakEntryCount()
+ private void trackLoad(CacheEntry entry)
{
- lock.readLock().lock();
- try {
- return weakCacheEntries.size();
- }
- finally {
- lock.readLock().unlock();
- }
+ currSizeBytes.getAndAdd(entry.getSize());
+ currStaticSizeBytes.getAndAdd(entry.getSize());
+ staticStats.getAndUpdate(s -> s.load(entry.getSize()));
+ }
+
+ private void trackDrop(CacheEntry entry)
+ {
+ currSizeBytes.getAndAdd(-entry.getSize());
+ currStaticSizeBytes.getAndAdd(-entry.getSize());
+ staticStats.getAndUpdate(s -> s.drop(entry.getSize()));
+ }
+
+ private void trackWeakLoad(WeakCacheEntry entry)
+ {
+ currSizeBytes.getAndAdd(entry.cacheEntry.getSize());
+ currWeakSizeBytes.getAndAdd(entry.cacheEntry.getSize());
+ }
+
+ private void trackWeakEvict(WeakCacheEntry entry)
+ {
+ currSizeBytes.getAndAdd(-entry.cacheEntry.getSize());
+ currWeakSizeBytes.getAndAdd(-entry.cacheEntry.getSize());
+ }
+
+ private void trackWeakHold(WeakCacheEntry entry)
+ {
+ currHoldCount.getAndIncrement();
+ currHoldBytes.getAndAdd(entry.cacheEntry.getSize());
+ }
+
+ private void trackWeakRelease(WeakCacheEntry entry)
+ {
+ currHoldCount.getAndDecrement();
+ currHoldBytes.getAndAdd(-entry.cacheEntry.getSize());
}
@VisibleForTesting
- public long getActiveWeakHolds()
+ public int getWeakEntryCount()
{
lock.readLock().lock();
try {
- return
weakCacheEntries.values().stream().filter(WeakCacheEntry::isHeld).count();
+ return weakCacheEntries.size();
}
finally {
lock.readLock().unlock();
@@ -683,6 +717,8 @@ public class StorageLocation
currSizeBytes.set(0);
currWeakSizeBytes.set(0);
currStaticSizeBytes.set(0);
+ currHoldCount.set(0);
+ currHoldBytes.set(0);
resetStaticStats();
resetWeakStats();
}
@@ -699,7 +735,7 @@ public class StorageLocation
public WeakStats resetWeakStats()
{
- return weakStats.getAndSet(new WeakStats(currWeakSizeBytes));
+ return weakStats.getAndSet(new WeakStats(currWeakSizeBytes, currHoldCount,
currHoldBytes));
}
/**
@@ -724,6 +760,9 @@ public class StorageLocation
private ReclaimResult reclaimHelper(long sizeToReclaim, List<WeakCacheEntry>
droppedEntries)
{
if (head == null) {
+ // unlikely for droppedEntries to be anything other than empty in
practice since this would mean we removed
+ // everything and still didn't free enough space, but better safe than
sorry
+ restorePartialReclaimedEntries(droppedEntries);
return ReclaimResult.failed(sizeToReclaim);
}
long sizeFreed = 0;
@@ -757,7 +796,6 @@ public class StorageLocation
);
}
unlinkWeakEntry(removed);
- weakStats.getAndUpdate(s -> s.evict(removed.cacheEntry.getSize()));
removed.next = null;
removed.prev = null;
droppedEntries.add(removed);
@@ -775,14 +813,20 @@ public class StorageLocation
return reclaimHelper(sizeToReclaim - sizeFreed, droppedEntries);
}
if (sizeFreed >= sizeToReclaim) {
- return new ReclaimResult(true, sizeToReclaim, sizeFreed, droppedEntries);
+ return ReclaimResult.success(sizeToReclaim, sizeFreed, droppedEntries);
}
+ restorePartialReclaimedEntries(droppedEntries);
+ return ReclaimResult.failed(sizeToReclaim);
+ }
+
+ @GuardedBy("lock")
+ private void restorePartialReclaimedEntries(List<WeakCacheEntry>
droppedEntries)
+ {
// if we didn't free up enough space, return everything we removed to the
cache
for (WeakCacheEntry entry : droppedEntries) {
linkNewWeakEntry(entry);
weakCacheEntries.put(entry.cacheEntry.getId(), entry);
}
- return ReclaimResult.failed(sizeToReclaim);
}
public long availableSizeBytes()
@@ -802,6 +846,11 @@ public class StorageLocation
public static final class ReclaimResult
{
+ public static ReclaimResult success(long spaceRequired, long
bytesReclaimed, List<WeakCacheEntry> evictions)
+ {
+ return new ReclaimResult(true, spaceRequired, bytesReclaimed, evictions);
+ }
+
public static ReclaimResult failed(long spaceRequired)
{
return new ReclaimResult(false, spaceRequired, 0, List.of());
@@ -812,7 +861,7 @@ public class StorageLocation
private final long bytesReclaimed;
private final List<WeakCacheEntry> evictions;
- ReclaimResult(
+ private ReclaimResult(
boolean success,
long spaceRequired,
long bytesReclaimed,
@@ -934,6 +983,7 @@ public class StorageLocation
{
private final TEntry entry;
private final Runnable releaseHold;
+ private final AtomicBoolean closed = new AtomicBoolean(false);
public ReservationHold(TEntry entry, Runnable releaseHold)
{
@@ -949,7 +999,9 @@ public class StorageLocation
@Override
public void close()
{
- releaseHold.run();
+ if (closed.compareAndSet(false, true)) {
+ releaseHold.run();
+ }
}
}
@@ -1014,6 +1066,8 @@ public class StorageLocation
public static final class WeakStats implements VirtualStorageLocationStats
{
private final AtomicLong sizeUsed;
+ private final AtomicLong holdCount;
+ private final AtomicLong holdBytes;
private final AtomicLong loadCount = new AtomicLong(0);
private final AtomicLong loadBytes = new AtomicLong(0);
private final AtomicLong rejectionCount = new AtomicLong(0);
@@ -1023,9 +1077,11 @@ public class StorageLocation
private final AtomicLong evictionBytes = new AtomicLong(0);
private final AtomicLong unmountCount = new AtomicLong(0);
- public WeakStats(AtomicLong sizeUsed)
+ public WeakStats(AtomicLong sizeUsed, AtomicLong holdCount, AtomicLong
holdBytes)
{
this.sizeUsed = sizeUsed;
+ this.holdCount = holdCount;
+ this.holdBytes = holdBytes;
}
public WeakStats hit(long size)
@@ -1067,6 +1123,18 @@ public class StorageLocation
return sizeUsed.get();
}
+ @Override
+ public long getHoldCount()
+ {
+ return holdCount.get();
+ }
+
+ @Override
+ public long getHoldBytes()
+ {
+ return holdBytes.get();
+ }
+
@Override
public long getHitCount()
{
diff --git
a/server/src/main/java/org/apache/druid/segment/loading/VirtualStorageLocationStats.java
b/server/src/main/java/org/apache/druid/segment/loading/VirtualStorageLocationStats.java
index 9f5b5689bf2..2405071c464 100644
---
a/server/src/main/java/org/apache/druid/segment/loading/VirtualStorageLocationStats.java
+++
b/server/src/main/java/org/apache/druid/segment/loading/VirtualStorageLocationStats.java
@@ -27,11 +27,26 @@ public interface VirtualStorageLocationStats
*/
long getUsedBytes();
+ /**
+ * Number of active holds on cache entries, indicating active usage at the
time this measurement collection was
+ * created.
+ */
+ long getHoldCount();
+
+ /**
+ * Number of bytes from active holds on cache entries, indicating active
usage at the time this measurement
+ * collection was created.
+ */
+ long getHoldBytes();
+
/**
* Number of operations for which an entry was already present during the
measurement period
*/
long getHitCount();
+ /**
+ * Number of bytes used by operations on entries which were already present
during the measurement period
+ */
long getHitBytes();
/**
diff --git
a/server/src/main/java/org/apache/druid/server/metrics/StorageMonitor.java
b/server/src/main/java/org/apache/druid/server/metrics/StorageMonitor.java
index 6ddbd6f587b..4a08b8edb5b 100644
--- a/server/src/main/java/org/apache/druid/server/metrics/StorageMonitor.java
+++ b/server/src/main/java/org/apache/druid/server/metrics/StorageMonitor.java
@@ -51,6 +51,8 @@ public class StorageMonitor extends AbstractMonitor
public static final String DROP_COUNT = "storage/drop/count";
public static final String DROP_BYTES = "storage/drop/bytes";
public static final String VSF_USED_BYTES = "storage/virtual/used/bytes";
+ public static final String VSF_HOLD_COUNT = "storage/virtual/hold/count";
+ public static final String VSF_HOLD_BYTES = "storage/virtual/hold/bytes";
public static final String VSF_HIT_COUNT = "storage/virtual/hit/count";
public static final String VSF_HIT_BYTES = "storage/virtual/hit/bytes";
public static final String VSF_LOAD_COUNT = "storage/virtual/load/count";
@@ -93,6 +95,8 @@ public class StorageMonitor extends AbstractMonitor
final ServiceMetricEvent.Builder builder = builderSupplier.get()
.setDimension(LOCATION_DIMENSION, location.getKey());
emitter.emit(builder.setMetric(VSF_USED_BYTES,
weakStats.getUsedBytes()));
+ emitter.emit(builder.setMetric(VSF_HOLD_COUNT,
weakStats.getHoldCount()));
+ emitter.emit(builder.setMetric(VSF_HOLD_BYTES,
weakStats.getHoldBytes()));
emitter.emit(builder.setMetric(VSF_HIT_COUNT,
weakStats.getHitCount()));
emitter.emit(builder.setMetric(VSF_HIT_BYTES,
weakStats.getHitBytes()));
emitter.emit(builder.setMetric(VSF_LOAD_COUNT,
weakStats.getLoadCount()));
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 89f87403c3a..95debe8f75e 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
@@ -416,15 +416,15 @@ class SegmentLocalCacheManagerConcurrencyTest
Assertions.assertTrue(t instanceof TimeoutException || t instanceof
ExecutionException, t.toString());
}
Thread.sleep(20);
- Assertions.assertEquals(0, location.getActiveWeakHolds());
- Assertions.assertEquals(0, location2.getActiveWeakHolds());
+ Assertions.assertEquals(0, location.getWeakStats().getHoldCount());
+ Assertions.assertEquals(0, location2.getWeakStats().getHoldCount());
currentBatch.clear();
}
}
- Assertions.assertEquals(0, location.getActiveWeakHolds());
- Assertions.assertEquals(0, location2.getActiveWeakHolds());
+ Assertions.assertEquals(0, location.getWeakStats().getHoldCount());
+ Assertions.assertEquals(0, location2.getWeakStats().getHoldCount());
Assertions.assertTrue(4 >= location.getWeakEntryCount());
Assertions.assertTrue(4 >= location2.getWeakEntryCount());
// 5 because __drop path
@@ -482,8 +482,8 @@ class SegmentLocalCacheManagerConcurrencyTest
}
Thread.sleep(5);
}
- Assertions.assertEquals(0, location.getActiveWeakHolds());
- Assertions.assertEquals(0, location2.getActiveWeakHolds());
+ Assertions.assertEquals(0, location.getWeakStats().getHoldCount());
+ Assertions.assertEquals(0, location2.getWeakStats().getHoldCount());
currentBatch.clear();
}
}
@@ -551,8 +551,8 @@ class SegmentLocalCacheManagerConcurrencyTest
}
}
- Assertions.assertEquals(0, location.getActiveWeakHolds());
- Assertions.assertEquals(0, location2.getActiveWeakHolds());
+ Assertions.assertEquals(0, location.getWeakStats().getHoldCount());
+ Assertions.assertEquals(0, location2.getWeakStats().getHoldCount());
totalSuccess += success;
totalEmpty += empty;
totalRows += rows;
@@ -759,8 +759,8 @@ class SegmentLocalCacheManagerConcurrencyTest
}
Thread.sleep(5);
}
- Assertions.assertEquals(0, location.getActiveWeakHolds());
- Assertions.assertEquals(0, location2.getActiveWeakHolds());
+ Assertions.assertEquals(0, location.getWeakStats().getHoldCount());
+ Assertions.assertEquals(0, location2.getWeakStats().getHoldCount());
currentBatch.clear();
}
}
@@ -787,8 +787,8 @@ class SegmentLocalCacheManagerConcurrencyTest
}
Assertions.assertEquals(iterations, totalSuccess);
Assertions.assertEquals(0, totalFailures);
- Assertions.assertEquals(0, location.getActiveWeakHolds());
- Assertions.assertEquals(0, location2.getActiveWeakHolds());
+ Assertions.assertEquals(0, location.getWeakStats().getHoldCount());
+ Assertions.assertEquals(0, location2.getWeakStats().getHoldCount());
Assertions.assertTrue(4 >= location.getWeakEntryCount());
Assertions.assertTrue(4 >= location2.getWeakEntryCount());
// 5 because __drop path
@@ -798,8 +798,8 @@ class SegmentLocalCacheManagerConcurrencyTest
private void assertNoLooseEnds()
{
- Assertions.assertEquals(0, location.getActiveWeakHolds());
- Assertions.assertEquals(0, location2.getActiveWeakHolds());
+ Assertions.assertEquals(0, location.getWeakStats().getHoldCount());
+ Assertions.assertEquals(0, location2.getWeakStats().getHoldCount());
Assertions.assertTrue(4 >= location.getWeakEntryCount());
Assertions.assertTrue(4 >= location2.getWeakEntryCount());
// 5 because __drop path
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 1c0babacb55..30a4b69b97d 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
@@ -194,10 +194,14 @@ class StorageLocationTest
final Closer closer = Closer.create();
Assertions.assertNotNull(closer.register(location.addWeakReservationHold(entry1.getId(),
() -> entry1)));
Assertions.assertNotNull(closer.register(location.addWeakReservationHold(entry2.getId(),
() -> entry2)));
+ Assertions.assertEquals(2, location.getWeakStats().getHoldCount());
+ Assertions.assertEquals(50, location.getWeakStats().getHoldBytes());
Assertions.assertTrue(location.reserveWeak(entry3));
Assertions.assertTrue(location.reserveWeak(entry4));
Assertions.assertEquals(100, location.currentWeakSizeBytes());
+ Assertions.assertEquals(2, location.getWeakStats().getHoldCount());
+ Assertions.assertEquals(50, location.getWeakStats().getHoldBytes());
Assertions.assertTrue(location.isWeakReserved(entry1.getId()));
Assertions.assertTrue(location.isWeakReserved(entry2.getId()));
Assertions.assertTrue(location.isWeakReserved(entry3.getId()));
@@ -206,6 +210,9 @@ class StorageLocationTest
Assertions.assertNotNull(closer.register(location.addWeakReservationHold(entry5.getId(),
() -> entry5)));
Assertions.assertEquals(100, location.currentWeakSizeBytes());
+ Assertions.assertEquals(3, location.getWeakStats().getHoldCount());
+ Assertions.assertEquals(75, location.getWeakStats().getHoldBytes());
+
Assertions.assertTrue(location.isWeakReserved(entry1.getId()));
Assertions.assertTrue(location.isWeakReserved(entry2.getId()));
@@ -222,7 +229,12 @@ class StorageLocationTest
Assertions.assertTrue(location.isWeakReserved(entry5.getId()));
Assertions.assertTrue(location.isWeakReserved(entry6.getId()));
- Assertions.assertTrue(location.reserveWeak(entry7));
+ Assertions.assertEquals(3, location.getWeakStats().getHoldCount());
+ Assertions.assertEquals(75, location.getWeakStats().getHoldBytes());
+
+
Assertions.assertNotNull(closer.register(location.addWeakReservationHold(entry7.getId(),
() -> entry7)));
+ Assertions.assertEquals(4, location.getWeakStats().getHoldCount());
+ Assertions.assertEquals(100, location.getWeakStats().getHoldBytes());
Assertions.assertTrue(location.isWeakReserved(entry1.getId()));
Assertions.assertTrue(location.isWeakReserved(entry2.getId()));
@@ -232,6 +244,10 @@ class StorageLocationTest
Assertions.assertFalse(location.isWeakReserved(entry6.getId()));
Assertions.assertTrue(location.isWeakReserved(entry7.getId()));
+ // all storage is held, cannot reserve
+ Assertions.assertFalse(location.reserveWeak(entry8));
+
+ // release holds
CloseableUtils.closeAndWrapExceptions(closer);
Assertions.assertTrue(location.reserveWeak(entry8));
@@ -244,6 +260,8 @@ class StorageLocationTest
Assertions.assertTrue(location.isWeakReserved(entry7.getId()));
Assertions.assertTrue(location.isWeakReserved(entry8.getId()));
Assertions.assertEquals(100, location.currentWeakSizeBytes());
+ Assertions.assertEquals(0, location.getWeakStats().getHoldCount());
+ Assertions.assertEquals(0, location.getWeakStats().getHoldBytes());
}
@Test
@@ -366,7 +384,7 @@ class StorageLocationTest
}
}
- Assertions.assertEquals(0, loc.getActiveWeakHolds());
+ Assertions.assertEquals(0, loc.getWeakStats().getHoldCount());
}
@Test
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]