Index: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java (revision 7a4be01a315250b2d7da0daad21da81ac113b5a1) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java (revision ) @@ -641,6 +641,9 @@ gcMonitor.info("TarMK revision cleanup started. Current repository size {}", humanReadableByteCount(initialSize)); + newWriter(); + tracker.clearCache(); + // Suggest to the JVM that now would be a good time // to clear stale weak references in the SegmentTracker System.gc(); @@ -902,22 +905,28 @@ id.getLeastSignificantBits(), data, offset, length); if (size >= maxFileSize) { + newWriter(); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + void newWriter() throws IOException { + if (writer.isDirty()) { - writer.close(); + writer.close(); - List list = - newArrayListWithCapacity(1 + readers.size()); - list.add(TarReader.open(writeFile, memoryMapping)); - list.addAll(readers); - readers = list; + List list = + newArrayListWithCapacity(1 + readers.size()); + list.add(TarReader.open(writeFile, memoryMapping)); + list.addAll(readers); + readers = list; - writeNumber++; - writeFile = new File( - directory, - String.format(FILE_NAME_FORMAT, writeNumber, "a")); - writer = new TarWriter(writeFile); + writeNumber++; + writeFile = new File( + directory, + String.format(FILE_NAME_FORMAT, writeNumber, "a")); + writer = new TarWriter(writeFile); - } - } catch (IOException e) { - throw new RuntimeException(e); } } Index: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/TarWriter.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/TarWriter.java (revision 7a4be01a315250b2d7da0daad21da81ac113b5a1) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/TarWriter.java (revision ) @@ -270,6 +270,10 @@ } } + boolean isDirty() { + return access != null; + } + /** * Closes this tar file. * Index: oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/CompactionAndCleanupTest.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/CompactionAndCleanupTest.java (revision 7a4be01a315250b2d7da0daad21da81ac113b5a1) +++ oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/CompactionAndCleanupTest.java (revision ) @@ -162,7 +162,7 @@ // fileStore.size() in [blobSize + dataSize, blobSize + 2xdataSize] assertTrue(fileStore.maybeCompact(false)); fileStore.cleanup(); - assertSize("post cleanup", fileStore.size(), blobSize + dataSize, + assertSize("post cleanup", fileStore.size(), (blobSize + dataSize) / 2, blobSize + 2 * dataSize); // refresh the ts ref, to simulate a long wait time Index: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentTracker.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentTracker.java (revision 7a4be01a315250b2d7da0daad21da81ac113b5a1) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentTracker.java (revision ) @@ -123,6 +123,11 @@ return store; } + public synchronized void clearCache() { + segments.clear(); + currentSize = 0; + } + Segment getSegment(SegmentId id) { try { Segment segment = store.readSegment(id); Index: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/TarReader.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/TarReader.java (revision 7a4be01a315250b2d7da0daad21da81ac113b5a1) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/TarReader.java (revision ) @@ -601,27 +601,15 @@ cleaned.add(id); sorted[i] = null; } else { - if (isDataSegmentId(entry.lsb())) { - size += getEntrySize(entry.size()); - count += 1; + size += getEntrySize(entry.size()); + count += 1; - + if (isDataSegmentId(entry.lsb())) { // this is a referenced data segment, so follow the graph if (graph != null) { List refids = graph.get(id); if (refids != null) { - for (UUID r : refids) { - if (isDataSegmentId(r.getLeastSignificantBits())) { - referencedIds.add(r); - } else { - if (cm != null && cm.wasCompacted(id)) { - // skip bulk compacted segment - // references - } else { - referencedIds.add(r); + referencedIds.addAll(refids); - } + } - } - } - } } else { // a pre-compiled graph is not available, so read the // references directly from this segment @@ -632,27 +620,10 @@ int refcount = segment.get(pos + REF_COUNT_OFFSET) & 0xff; int refend = pos + 16 * (refcount + 1); for (int refpos = pos + 16; refpos < refend; refpos += 16) { - UUID r = new UUID(segment.getLong(refpos), - segment.getLong(refpos + 8)); - if (isDataSegmentId(r.getLeastSignificantBits())) { - referencedIds.add(r); - } else { - if (cm != null && cm.wasCompacted(id)) { - // skip bulk compacted segment references - } else { - referencedIds.add(r); + referencedIds.add(new UUID( + segment.getLong(refpos), + segment.getLong(refpos + 8))); - } + } - } - } - } - } else { - // bulk segments compaction check - if (cm != null && cm.wasCompacted(id)) { - cleaned.add(id); - sorted[i] = null; - } else { - size += getEntrySize(entry.size()); - count += 1; } } }