diff --git oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java index 7dd4667..c93fef8 100644 --- oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java +++ oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java @@ -314,7 +314,21 @@ public class FileStore implements SegmentStore, Closeable { } } - long initialSize = size(); + long initialSize = 0; + + fileStoreLock.readLock().lock(); + try { + if (writeFile != null) { + initialSize = writeFile.length(); + } + + for (TarReader reader : readers) { + initialSize += reader.size(); + } + } finally { + fileStoreLock.readLock().unlock(); + } + this.approximateSize = new AtomicLong(initialSize); this.stats = new FileStoreStats(builder.getStatsProvider(), this, initialSize); @@ -582,18 +596,9 @@ public class FileStore implements SegmentStore, Closeable { } public final long size() { - fileStoreLock.readLock().lock(); - try { - long size = writeFile != null ? writeFile.length() : 0; - for (TarReader reader : readers) { - size += reader.size(); - } - return size; - } finally { - fileStoreLock.readLock().unlock(); - } + return approximateSize.get(); } - + public int readerCount(){ fileStoreLock.readLock().lock(); try { @@ -760,6 +765,7 @@ public class FileStore implements SegmentStore, Closeable { List oldReaders = newArrayList(); fileStoreLock.writeLock().lock(); try { + approximateSize.set(0); // Replace current list of reader with the cleaned readers taking care not to lose // any new reader that might have come in through concurrent calls to newWriter() List newReaders = newArrayList(); @@ -768,14 +774,22 @@ public class FileStore implements SegmentStore, Closeable { TarReader newReader = cleaned.get(reader); if (newReader != null) { newReaders.add(newReader); + + //increase repository size by the size of currently known reader + approximateSize.addAndGet(newReader.size()); } + if (newReader != reader) { oldReaders.add(reader); } } else { + // increase repository size by the size of the new reader obtained via newWriter() + approximateSize.addAndGet(reader.size()); newReaders.add(reader); } } + + approximateSize.addAndGet(writeFile.length()); readers = newReaders; } finally { fileStoreLock.writeLock().unlock(); @@ -793,7 +807,6 @@ public class FileStore implements SegmentStore, Closeable { } long finalSize = size(); - approximateSize.set(finalSize); stats.reclaimed(initialSize - finalSize); // FIXME OAK-4106: Reclaimed size reported by FileStore.cleanup is off gcListener.cleaned(initialSize - finalSize, finalSize); @@ -1389,7 +1402,7 @@ public class FileStore implements SegmentStore, Closeable { } private void checkDiskSpace() { - long repositoryDiskSpace = approximateSize.get(); + long repositoryDiskSpace = size(); long availableDiskSpace = directory.getFreeSpace(); boolean updated = gcOptions.isDiskSpaceSufficient(repositoryDiskSpace, availableDiskSpace); boolean previous = sufficientDiskSpace.getAndSet(updated); diff --git oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/CompactionAndCleanupIT.java oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/CompactionAndCleanupIT.java index b002b9f..1114832 100644 --- oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/CompactionAndCleanupIT.java +++ oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/CompactionAndCleanupIT.java @@ -353,7 +353,7 @@ public class CompactionAndCleanupIT { fileStore.compact(); fileStore.cleanup(); long size2 = fileStore.size(); - assertSize("with compacted binaries", size2, 0, size1 - blobSize); + assertSize("with compacted binaries", size2, 0, (size1 - blobSize) * 11 / 10); } finally { fileStore.close(); }