Author: frm
Date: Tue Apr 11 08:02:33 2017
New Revision: 1790937

URL: http://svn.apache.org/viewvc?rev=1790937&view=rev
Log:
OAK-6052 - Add comments to clarify some critical parts of the implementation

Modified:
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/TarFiles.java

Modified: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/TarFiles.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/TarFiles.java?rev=1790937&r1=1790936&r2=1790937&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/TarFiles.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/TarFiles.java
 Tue Apr 11 08:02:33 2017
@@ -218,12 +218,29 @@ class TarFiles implements Closeable {
 
     private final IOMonitor ioMonitor;
 
+    /**
+     * Guards access to the {@link #readers} and {@link #writer} references.
+     */
     private final ReadWriteLock lock = new ReentrantReadWriteLock();
 
+    /**
+     * Points to the first node of the linked list of TAR readers. Every node 
in
+     * the linked list is immutable. Thus, you need to to hold {@link #lock}
+     * while reading the value of the reference, but you can release it before
+     * iterating through the list.
+     */
     private Node readers;
 
+    /**
+     * The currently used TAR writer. Its access is protected by {@link #lock}.
+     */
     private TarWriter writer;
 
+    /**
+     * If {@code true}, a user requested this instance to close. This flag is
+     * used in long running, background operations - like {@link
+     * #cleanup(Supplier, Predicate)} - to be responsive to termination.
+     */
     private volatile boolean shutdown;
 
     private TarFiles(Builder builder) throws IOException {
@@ -233,6 +250,12 @@ class TarFiles implements Closeable {
         Map<Integer, Map<Character, File>> map = 
collectFiles(builder.directory);
         Integer[] indices = map.keySet().toArray(new Integer[map.size()]);
         Arrays.sort(indices);
+
+        // TAR readers are stored in descending index order. The following loop
+        // iterates the indices in ascending order, but prepends - instead of
+        // appending - the corresponding TAR readers to the linked list. This
+        // results in a properly ordered linked list.
+
         for (Integer index : indices) {
             TarReader r;
             if (builder.readOnly) {
@@ -451,6 +474,16 @@ class TarFiles implements Closeable {
         }
     }
 
+    /**
+     * Creates a new TAR writer with a higher index number, reopens the 
previous
+     * TAR writer as a TAR reader, and adds the TAR reader to the linked list.
+     * <p>
+     * This method must be invoked while holding {@link #lock} in write mode,
+     * because it modifies the references {@link #writer} and {@link #readers}.
+     *
+     * @throws IOException If an error occurs while operating on the TAR 
readers
+     *                     or the TAR writer.
+     */
     private void newWriter() throws IOException {
         TarWriter newWriter = writer.createNextGeneration();
         if (newWriter == writer) {
@@ -521,23 +554,66 @@ class TarFiles implements Closeable {
 
             Node swept = null;
             Node n = readers;
+
+            // The following loops creates a modified version of `readers` and
+            // saves it into `swept`. Some TAR readers in `readers` have been
+            // swept by the previous code and must be replaced with a slimmer
+            // TAR reader with the same index but a higher generation.
+
             while (n != null) {
                 if (cleaned.containsKey(n.reader)) {
+
+                    // We distinguish three cases. First, the original TAR
+                    // reader is unmodified. This happens with no content or 
not
+                    // enough content could be swept from the original TAR
+                    // reader. Second, some content could be swept from the
+                    // original TAR reader and a new TAR reader with the same
+                    // index and a higher generation was created. Third, all 
the
+                    // content from the original TAR reader could be swept.
+
                     TarReader r = cleaned.get(n.reader);
+
                     if (r != null) {
+
+                        // We are either in the first or in the second case.
+                        // Save the TAR reader (either the original or the one
+                        // with a higher generation) in the resulting linked 
list.
+
                         swept = new Node(r, swept);
                         reclaimed += r.size();
                     }
+
                     if (r != n.reader) {
+
+                        // We are either in the second or third case. Save the
+                        // original TAR reader in a list of TAR readers that
+                        // will be closed at the end of this methods.
+
                         closeables = new Node(n.reader, closeables);
                     }
                 } else {
+
+                    // This reader was not involved in the mark-and-sweep. This
+                    // might happen in iterations of this loop successive to 
the
+                    // first, when we re-read `readers` and recompute `swept`
+                    // all over again.
+
                     swept = new Node(n.reader, swept);
                 }
                 n = n.next;
             }
+
+            // `swept` is in the reverse order because we prepended new nodes
+            // to it. We have to reverse it before we save it into `readers`.
+
             swept = reverse(swept);
 
+            // Following is a compare-and-set operation. We based the
+            // computation of `swept` of a specific value of `readers`. If
+            // `readers` is still the same as the one we started with, we just
+            // update `readers` and exit from the loop. Otherwise, we read the
+            // value of `readers` and recompute `swept` based on this value.
+
             lock.writeLock().lock();
             try {
                 if (this.readers == readers) {


Reply via email to