Author: frm
Date: Fri Apr 7 11:06:31 2017
New Revision: 1790534
URL: http://svn.apache.org/viewvc?rev=1790534&view=rev
Log:
OAK-6052 - Add counted reference implementation
Added:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/Reference.java
(with props)
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/ReferenceTest.java
(with props)
Added:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/Reference.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/Reference.java?rev=1790534&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/Reference.java
(added)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/Reference.java
Fri Apr 7 11:06:31 2017
@@ -0,0 +1,106 @@
+/*
+ * 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.segment.file;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Represents a counted reference to a closeable object.
+ * <p>
+ * This class enables reference counting for an instance. The instance should
+ * always be accessed through a reference ({@link #get()}), which guarantees
+ * that the underlying instance remains live during its usage.
+ * <p>
+ * When a reference is not needed, it should be closed. If the closed reference
+ * is the last reference to the underlying object, the the underlying object is
+ * closed. If other references to the underlying object are around, the object
+ * is kept alive.
+ * <p>
+ * Given a reference to an object, it is possible to create a new reference to
+ * it using the {@link #reference()} method.
+ * <p>
+ * References are thread safe. This allows to safely share an object between
+ * multiple threads. Every thread gets its own reference to the same underlying
+ * object, and closes it when the reference is not needed anymore. The
+ * underlying object will automatically be closed by the last thread using the
+ * resource.
+ *
+ * @param <T> The type of the underlying object.
+ */
+class Reference<T extends Closeable> implements Closeable {
+
+ /**
+ * Create a new reference to an underlying object.
+ *
+ * @param instance The underlying object.
+ * @param <T> The type of the underlying object.
+ * @return An instance of {@link Reference}.
+ */
+ static <T extends Closeable> Reference<T> of(final T instance) {
+ return new Reference<>(checkNotNull(instance));
+ }
+
+ private final AtomicInteger references = new AtomicInteger(1);
+
+ private final T instance;
+
+ private Reference(T instance) {
+ this.instance = instance;
+ }
+
+ /**
+ * Get the underlying object referenced from this instance.
+ *
+ * @return The underlying object.
+ */
+ public T get() {
+ return instance;
+ }
+
+ /**
+ * Create a new reference to the underlying object.
+ * <p>
+ * The instance must be explicitly closed for the underlying object to be
+ * closed. Failing to close all the references prevents the underlying
+ * object from being closed.
+ *
+ * @return An instance of {@link Reference}.
+ */
+ public Reference<T> reference() {
+ references.incrementAndGet();
+ return this;
+ }
+
+ /**
+ * Disposes this reference. If this instance is the last reference to the
+ * underlying object, the underlying object will be disposed of as well.
+ *
+ * @throws IOException If an error occurs when closing the underlying
+ * object.
+ */
+ public void close() throws IOException {
+ if (references.decrementAndGet() == 0) {
+ instance.close();
+ }
+ }
+
+}
Propchange:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/Reference.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/ReferenceTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/ReferenceTest.java?rev=1790534&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/ReferenceTest.java
(added)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/ReferenceTest.java
Fri Apr 7 11:06:31 2017
@@ -0,0 +1,43 @@
+/*
+ * 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.segment.file;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import java.io.Closeable;
+
+import org.junit.Test;
+
+public class ReferenceTest {
+
+ @Test
+ public void testReference() throws Exception {
+ Closeable c = mock(Closeable.class);
+ Reference<Closeable> r1 = Reference.of(c);
+ Reference<Closeable> r2 = r1.reference();
+ verify(c, never()).close();
+ r2.close();
+ verify(c, never()).close();
+ r1.close();
+ verify(c, times(1)).close();
+ }
+
+}
Propchange:
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/ReferenceTest.java
------------------------------------------------------------------------------
svn:eol-style = native