Author: jukka
Date: Fri Mar 14 15:20:56 2014
New Revision: 1577567
URL: http://svn.apache.org/r1577567
Log:
OAK-631: SegmentMK: Implement garbage collection
Fix SegmentWriter.prepare() to correctly track existing segment and root
references
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java?rev=1577567&r1=1577566&r2=1577567&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java
Fri Mar 14 15:20:56 2014
@@ -27,7 +27,7 @@ import static com.google.common.collect.
import static com.google.common.collect.Lists.newArrayListWithExpectedSize;
import static com.google.common.collect.Maps.newHashMap;
import static com.google.common.collect.Maps.newLinkedHashMap;
-import static com.google.common.collect.Sets.newTreeSet;
+import static com.google.common.collect.Sets.newIdentityHashSet;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyMap;
import static java.util.Collections.nCopies;
@@ -46,7 +46,6 @@ import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
-import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -197,47 +196,30 @@ public class SegmentWriter {
checkArgument(size >= 0);
checkNotNull(ids);
+ int rootcount = roots.size() + 1;
int refcount = segment.getRefCount();
- int newcount = refcount;
-
- Set<SegmentId> segmentIds = newTreeSet();
+ Set<SegmentId> segmentIds = newIdentityHashSet();
for (RecordId recordId : ids) {
- segmentIds.add(recordId.getSegmentId());
+ SegmentId segmentId = recordId.getSegmentId();
+ if (segmentId != segment.getSegmentId()) {
+ segmentIds.add(segmentId);
+ } else if (roots.containsKey(recordId)) {
+ rootcount--;
+ }
}
- segmentIds.remove(segment.getSegmentId());
-
- int refid = 1;
- Iterator<SegmentId> iterator = segmentIds.iterator();
- while (refid < refcount && iterator.hasNext()) {
- SegmentId segmentId = iterator.next();
- long msb = segmentId.getMostSignificantBits();
- while (refid < refcount
- && segment.readLong(refid * 16) < msb) {
- refid++;
- }
- long lsb = segmentId.getLeastSignificantBits();
- while (refid < refcount
- && segment.readLong(refid * 16) == msb
- && segment.readLong(refid * 16 + 8) < lsb) {
- refid++;
- }
- if (refid < refcount
- && segment.readLong(refid * 16) == msb
- && segment.readLong(refid * 16 + 8) == lsb) {
- // that segment is already referenced, so no new entry needed
- } else {
- newcount++;
+ if (!segmentIds.isEmpty()) {
+ for (int refid = 1; refid < refcount; refid++) {
+ segmentIds.remove(segment.getRefId(refid));
}
+ refcount += segmentIds.size();
}
- int rootcount = roots.size() + 1;
-
int recordSize = Segment.align(size + ids.size() *
Segment.RECORD_ID_BYTES);
- int headerSize = Segment.align(newcount * 16 + rootcount * 3);
+ int headerSize = Segment.align(refcount * 16 + rootcount * 3);
int segmentSize = headerSize + recordSize + length;
if (segmentSize > buffer.length - 1
|| rootcount > 0xffff
- || newcount > Segment.SEGMENT_REFERENCE_LIMIT) {
+ || refcount > Segment.SEGMENT_REFERENCE_LIMIT) {
flush();
}