Author: jukka
Date: Mon Jan 20 21:43:24 2014
New Revision: 1559834
URL: http://svn.apache.org/r1559834
Log:
OAK-631: SegmentMK: Implement garbage collection
Add SegmentIdFactory.getReferencedSegmentIds() and some simple test cases.
Added:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/SegmentIdFactoryTest.java
(with props)
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/AbstractStore.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentIdFactory.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/AbstractStore.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/AbstractStore.java?rev=1559834&r1=1559833&r2=1559834&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/AbstractStore.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/AbstractStore.java
Mon Jan 20 21:43:24 2014
@@ -62,6 +62,10 @@ public abstract class AbstractStore impl
}
}
+ protected Set<UUID> getReferencedSegmentIds() {
+ return factory.getReferencedSegmentIds();
+ }
+
protected Segment createSegment(UUID segmentId, ByteBuffer data) {
return new Segment(this, factory, segmentId, data);
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentIdFactory.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentIdFactory.java?rev=1559834&r1=1559833&r2=1559834&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentIdFactory.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentIdFactory.java
Mon Jan 20 21:43:24 2014
@@ -18,6 +18,7 @@ package org.apache.jackrabbit.oak.plugin
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Lists.newLinkedList;
+import static com.google.common.collect.Sets.newHashSetWithExpectedSize;
import java.lang.ref.WeakReference;
import java.security.SecureRandom;
@@ -25,6 +26,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
+import java.util.Set;
import java.util.UUID;
/**
@@ -81,6 +83,35 @@ public class SegmentIdFactory {
Collections.<List<WeakReference<UUID>>>nCopies(1024, null));
/**
+ * Returns all segment identifiers that are currently referenced in memory.
+ *
+ * @return referenced segment identifiers
+ */
+ synchronized Set<UUID> getReferencedSegmentIds() {
+ Set<UUID> set = newHashSetWithExpectedSize(uuids.size());
+
+ for (int i = 0; i < uuids.size(); i++) {
+ List<WeakReference<UUID>> list = uuids.get(i);
+ if (list != null) {
+ Iterator<WeakReference<UUID>> iterator = list.iterator();
+ while (iterator.hasNext()) {
+ UUID uuid = iterator.next().get();
+ if (uuid == null) {
+ iterator.remove();
+ } else {
+ set.add(uuid);
+ }
+ }
+ if (list.isEmpty()) {
+ uuids.set(i, null);
+ }
+ }
+ }
+
+ return set;
+ }
+
+ /**
*
* @param msb
* @param lsb
Added:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/SegmentIdFactoryTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/SegmentIdFactoryTest.java?rev=1559834&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/SegmentIdFactoryTest.java
(added)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/SegmentIdFactoryTest.java
Mon Jan 20 21:43:24 2014
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.segment;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+import static
org.apache.jackrabbit.oak.plugins.segment.SegmentIdFactory.isBulkSegmentId;
+import static
org.apache.jackrabbit.oak.plugins.segment.SegmentIdFactory.isDataSegmentId;
+
+import java.util.Set;
+import java.util.UUID;
+
+import org.junit.Test;
+
+public class SegmentIdFactoryTest {
+
+ private final SegmentIdFactory factory = new SegmentIdFactory();
+
+ @Test
+ public void segmentIdType() {
+ assertTrue(isDataSegmentId(factory.newDataSegmentId()));
+ assertTrue(isBulkSegmentId(factory.newBulkSegmentId()));
+
+ assertFalse(isBulkSegmentId(factory.newDataSegmentId()));
+ assertFalse(isDataSegmentId(factory.newBulkSegmentId()));
+ }
+
+ @Test
+ public void internedSegmentIds() {
+ assertTrue(factory.getSegmentId(0, 0) == factory.getSegmentId(0, 0));
+ assertTrue(factory.getSegmentId(1, 2) == factory.getSegmentId(1, 2));
+ assertTrue(factory.getSegmentId(1, 2) != factory.getSegmentId(3, 4));
+ }
+
+ @Test
+ public void referencedSegmentIds() throws InterruptedException {
+ UUID a = factory.newDataSegmentId();
+ UUID b = factory.newBulkSegmentId();
+ UUID c = factory.newDataSegmentId();
+
+ Set<UUID> ids = factory.getReferencedSegmentIds();
+ assertTrue(ids.contains(a));
+ assertTrue(ids.contains(b));
+ assertTrue(ids.contains(c));
+
+ // the returned set is a snapshot in time, not continuously updated
+ assertFalse(ids.contains(factory.newBulkSegmentId()));
+ }
+
+ /**
+ * This test can't be enabled in general, as gc() contract is too
+ * weak for this to work reliably. But it's a good manual check for
+ * the correct operation of the tracking of segment id references.
+ */
+ // @Test
+ public void garbageCollection() {
+ UUID a = factory.newDataSegmentId();
+ UUID b = factory.newBulkSegmentId();
+
+ // generate lots of garbage copies of an UUID to get the
+ // garbage collector to reclaim also the original instance
+ for (int i = 0; i < 1000000; i++) {
+ a = new UUID(
+ a.getMostSignificantBits(), a.getLeastSignificantBits());
+ }
+ System.gc();
+
+ // now the original UUID should no longer be present
+ Set<UUID> ids = factory.getReferencedSegmentIds();
+ assertFalse(ids.contains(a));
+ assertTrue(ids.contains(b));
+ }
+
+}
Propchange:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/SegmentIdFactoryTest.java
------------------------------------------------------------------------------
svn:eol-style = native