]> source.dussan.org Git - jgit.git/commitdiff
Move WorkingTreeIterator inherited state into an object 26/1926/1
authorShawn O. Pearce <spearce@spearce.org>
Fri, 19 Nov 2010 01:04:10 +0000 (17:04 -0800)
committerShawn O. Pearce <spearce@spearce.org>
Fri, 19 Nov 2010 01:06:12 +0000 (17:06 -0800)
Instead of copying up to 4 fields from the parent iterator each time a
child iterator is initialized and used, construct a single state
object that contains the 4 fields, and pass that one state object
through to the child.  This makes it easier to add additional state
fields that must be inherited, at the slight expense of an extra
object allocation per TreeWalk, and an extra level of field
indirection whenever the options, nameEncoder, or read buffer is
required by the iterator.

Change-Id: Ic4603c33b772d7a45f9c81140537d51945688fcb
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java

index b292c3cdd34564d675394db43064029cdb2bde81..ac3a83104c984d3916b50166bc91d55e6ddd18b1 100644 (file)
@@ -90,7 +90,7 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
        protected static final Entry[] EOF = {};
 
        /** Size we perform file IO in if we have to read and hash a file. */
-       private static final int BUFFER_SIZE = 2048;
+       static final int BUFFER_SIZE = 2048;
 
        /**
         * Maximum size of files which may be read fully into memory for performance
@@ -98,21 +98,15 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
         */
        private static final long MAXIMUM_FILE_SIZE_TO_READ_FULLY = 65536;
 
+       /** Inherited state of this iterator, describing working tree, etc. */
+       private final IteratorState state;
+
        /** The {@link #idBuffer()} for the current entry. */
        private byte[] contentId;
 
        /** Index within {@link #entries} that {@link #contentId} came from. */
        private int contentIdFromPtr;
 
-       /** Buffer used to perform {@link #contentId} computations. */
-       private byte[] contentReadBuffer;
-
-       /** Digest computer for {@link #contentId} computations. */
-       private MessageDigest contentDigest;
-
-       /** File name character encoder. */
-       private final CharsetEncoder nameEncoder;
-
        /** List of entries obtained from the subclass. */
        private Entry[] entries;
 
@@ -125,9 +119,6 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
        /** If there is a .gitignore file present, the parsed rules from it. */
        private IgnoreNode ignoreNode;
 
-       /** Options used to process the working tree. */
-       private final WorkingTreeOptions options;
-
        /**
         * Create a new iterator with no parent.
         *
@@ -136,8 +127,7 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
         */
        protected WorkingTreeIterator(WorkingTreeOptions options) {
                super();
-               nameEncoder = Constants.CHARSET.newEncoder();
-               this.options = options;
+               state = new IteratorState(options);
        }
 
        /**
@@ -160,8 +150,7 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
        protected WorkingTreeIterator(final String prefix,
                        WorkingTreeOptions options) {
                super(prefix);
-               nameEncoder = Constants.CHARSET.newEncoder();
-               this.options = options;
+               state = new IteratorState(options);
        }
 
        /**
@@ -172,8 +161,7 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
         */
        protected WorkingTreeIterator(final WorkingTreeIterator p) {
                super(p);
-               nameEncoder = p.nameEncoder;
-               options = p.options;
+               state = p.state;
        }
 
        /**
@@ -222,21 +210,6 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
                return zeroid;
        }
 
-       private void initializeDigestAndReadBuffer() {
-               if (contentDigest != null)
-                       return;
-
-               if (parent == null) {
-                       contentReadBuffer = new byte[BUFFER_SIZE];
-                       contentDigest = Constants.newMessageDigest();
-               } else {
-                       final WorkingTreeIterator p = (WorkingTreeIterator) parent;
-                       p.initializeDigestAndReadBuffer();
-                       contentReadBuffer = p.contentReadBuffer;
-                       contentDigest = p.contentDigest;
-               }
-       }
-
        private static final byte[] digits = { '0', '1', '2', '3', '4', '5', '6',
                        '7', '8', '9' };
 
@@ -249,7 +222,7 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
                        if (is == null)
                                return zeroid;
                        try {
-                               initializeDigestAndReadBuffer();
+                               state.initializeDigestAndReadBuffer();
 
                                final long len = e.getLength();
                                if (!mightNeedCleaning(e))
@@ -299,7 +272,7 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
        }
 
        private boolean mightNeedCleaning(Entry entry) {
-               switch (options.getAutoCRLF()) {
+               switch (getOptions().getAutoCRLF()) {
                case FALSE:
                default:
                        return false;
@@ -339,7 +312,7 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
         * @return working tree options
         */
        public WorkingTreeOptions getOptions() {
-               return options;
+               return state.options;
        }
 
        @Override
@@ -520,6 +493,7 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
                entries = list;
                int i, o;
 
+               final CharsetEncoder nameEncoder = state.nameEncoder;
                for (i = 0, o = 0; i < entries.length; i++) {
                        final Entry e = entries[i];
                        if (e == null)
@@ -678,6 +652,9 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
        }
 
        private byte[] computeHash(InputStream in, long length) throws IOException {
+               final MessageDigest contentDigest = state.contentDigest;
+               final byte[] contentReadBuffer = state.contentReadBuffer;
+
                contentDigest.reset();
                contentDigest.update(hblob);
                contentDigest.update((byte) ' ');
@@ -857,4 +834,30 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
                        return r.getRules().isEmpty() ? null : r;
                }
        }
+
+       private static final class IteratorState {
+               /** Options used to process the working tree. */
+               final WorkingTreeOptions options;
+
+               /** File name character encoder. */
+               final CharsetEncoder nameEncoder;
+
+               /** Digest computer for {@link #contentId} computations. */
+               MessageDigest contentDigest;
+
+               /** Buffer used to perform {@link #contentId} computations. */
+               byte[] contentReadBuffer;
+
+               IteratorState(WorkingTreeOptions options) {
+                       this.options = options;
+                       this.nameEncoder = Constants.CHARSET.newEncoder();
+               }
+
+               void initializeDigestAndReadBuffer() {
+                       if (contentDigest == null) {
+                               contentDigest = Constants.newMessageDigest();
+                               contentReadBuffer = new byte[BUFFER_SIZE];
+                       }
+               }
+       }
 }