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


Reply via email to