diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/fs/CachingSpaceUsageSource.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/fs/CachingSpaceUsageSource.java index 9b9719386b39..683f4393a1ac 100644 --- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/fs/CachingSpaceUsageSource.java +++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/fs/CachingSpaceUsageSource.java @@ -51,6 +51,7 @@ public class CachingSpaceUsageSource implements SpaceUsageSource { private long cachedUsedSpace; private long cachedAvailable; private long cachedCapacity; + private SpaceUsageSource cachedUsage; private final Duration refresh; private final SpaceUsageSource source; private final SpaceUsagePersistence persistence; @@ -104,7 +105,15 @@ public long getUsedSpace() { @Override public SpaceUsageSource snapshot() { try (AutoCloseableLock ignored = lock.readLock(null, null)) { - return new Fixed(cachedCapacity, cachedAvailable, cachedUsedSpace); + if (cachedUsage != null) { + return cachedUsage; + } + } + try (AutoCloseableLock ignored = lock.writeLock(null, null)) { + if (cachedUsage == null) { + cachedUsage = new Fixed(cachedCapacity, cachedAvailable, cachedUsedSpace); + } + return cachedUsage; } } @@ -119,6 +128,7 @@ public void incrementUsedSpace(long usedSpace) { change = Math.min(current, usedSpace); cachedAvailable -= change; cachedUsedSpace += change; + cachedUsage = null; } if (change != usedSpace) { @@ -138,6 +148,7 @@ public void decrementUsedSpace(long reclaimedSpace) { change = Math.min(current, reclaimedSpace); cachedUsedSpace -= change; cachedAvailable += change; + cachedUsage = null; } if (change != reclaimedSpace) { @@ -202,6 +213,7 @@ private void updateAvailable() { try (AutoCloseableLock ignored = lock.writeLock(null, null)) { cachedAvailable = available; cachedCapacity = capacity; + cachedUsage = null; } } @@ -215,6 +227,7 @@ private void updateCachedValues(long used) { cachedAvailable = available; cachedCapacity = capacity; cachedUsedSpace = used; + cachedUsage = null; } } diff --git a/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/fs/TestCachingSpaceUsageSource.java b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/fs/TestCachingSpaceUsageSource.java index b84ca130f27c..52d6e09dfe33 100644 --- a/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/fs/TestCachingSpaceUsageSource.java +++ b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/fs/TestCachingSpaceUsageSource.java @@ -161,6 +161,7 @@ void decrementUsedSpaceMoreThanCurrent() { assertEquals(0, subject.getUsedSpace()); // available and used change by same amount (in opposite directions) assertEquals(original.getAvailable() + original.getUsedSpace(), subject.getAvailable()); + assertSnapshotIsUpToDate(subject); } @Test @@ -179,6 +180,14 @@ void decrementAvailableSpaceMoreThanCurrent() { assertEquals(0, subject.getAvailable()); // available and used change by same amount (in opposite directions) assertEquals(original.getUsedSpace() + original.getAvailable(), subject.getUsedSpace()); + assertSnapshotIsUpToDate(subject); + } + + private static void assertSnapshotIsUpToDate(SpaceUsageSource subject) { + SpaceUsageSource snapshot = subject.snapshot(); + assertEquals(subject.getCapacity(), snapshot.getCapacity()); + assertEquals(subject.getAvailable(), snapshot.getAvailable()); + assertEquals(subject.getUsedSpace(), snapshot.getUsedSpace()); } private static long missingInitialValue() { @@ -238,6 +247,7 @@ private static void assertAvailableWasUpdated(SpaceUsageSource source, assertEquals(source.getCapacity(), subject.getCapacity()); assertEquals(source.getAvailable(), subject.getAvailable()); + assertSnapshotIsUpToDate(subject); } private static void assertSubjectWasRefreshed(SpaceUsageSource source,