]> source.dussan.org Git - jgit.git/commitdiff
Add internal API for note iteration 53/1853/4
authorShawn O. Pearce <spearce@spearce.org>
Fri, 5 Nov 2010 01:46:19 +0000 (18:46 -0700)
committerShawn O. Pearce <spearce@spearce.org>
Fri, 12 Nov 2010 22:01:28 +0000 (14:01 -0800)
Some algorithms need to be able to iterate through all notes within a
particular bucket, such as when splitting or combining a bucket.
Exposing an Iterator<Note> makes this traversal possible.

For a LeafBucket the iteration is simple, its over the sorted array of
elements.  For FanoutBucket its a bit more complex as the iteration
needs to union the iterators of each fanout bucket, lazily loading any
buckets that aren't already in-memory.

Change-Id: I3d5279b11984f44dcf0ddb14a82a4b4e51d4632d
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
org.eclipse.jgit/src/org/eclipse/jgit/notes/FanoutBucket.java
org.eclipse.jgit/src/org/eclipse/jgit/notes/LeafBucket.java
org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteBucket.java

index 20856769000af258f9551015b0aa2c9e7668c4a0..5d35355ba9e702e3645e55796b3b15c8fb4630f5 100644 (file)
@@ -46,9 +46,12 @@ package org.eclipse.jgit.notes;
 import static org.eclipse.jgit.lib.FileMode.TREE;
 
 import java.io.IOException;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
 
 import org.eclipse.jgit.lib.AbbreviatedObjectId;
 import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.MutableObjectId;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.ObjectInserter;
 import org.eclipse.jgit.lib.ObjectReader;
@@ -107,6 +110,54 @@ class FanoutBucket extends InMemoryNoteBucket {
                return b != null ? b.get(objId, or) : null;
        }
 
+       @Override
+       Iterator<Note> iterator(AnyObjectId objId, final ObjectReader reader)
+                       throws IOException {
+               final MutableObjectId id = new MutableObjectId();
+               id.fromObjectId(objId);
+
+               return new Iterator<Note>() {
+                       private int cell;
+
+                       private Iterator<Note> itr;
+
+                       public boolean hasNext() {
+                               if (itr != null && itr.hasNext())
+                                       return true;
+
+                               for (; cell < table.length; cell++) {
+                                       NoteBucket b = table[cell];
+                                       if (b == null)
+                                               continue;
+
+                                       try {
+                                               id.setByte(prefixLen >> 1, cell);
+                                               itr = b.iterator(id, reader);
+                                       } catch (IOException err) {
+                                               throw new RuntimeException(err);
+                                       }
+
+                                       if (itr.hasNext()) {
+                                               cell++;
+                                               return true;
+                                       }
+                               }
+                               return false;
+                       }
+
+                       public Note next() {
+                               if (hasNext())
+                                       return itr.next();
+                               else
+                                       throw new NoSuchElementException();
+                       }
+
+                       public void remove() {
+                               throw new UnsupportedOperationException();
+                       }
+               };
+       }
+
        @Override
        InMemoryNoteBucket set(AnyObjectId noteOn, AnyObjectId noteData,
                        ObjectReader or) throws IOException {
@@ -193,6 +244,12 @@ class FanoutBucket extends InMemoryNoteBucket {
                        return load(objId, or).get(objId, or);
                }
 
+               @Override
+               Iterator<Note> iterator(AnyObjectId objId, ObjectReader reader)
+                               throws IOException {
+                       return load(objId, reader).iterator(objId, reader);
+               }
+
                @Override
                InMemoryNoteBucket set(AnyObjectId noteOn, AnyObjectId noteData,
                                ObjectReader or) throws IOException {
index 40be45f433f62e65ccbbcee5c43702507a67c5ec..67bb3c8a046227c841bf750f7cee7028e4a44232 100644 (file)
@@ -47,6 +47,8 @@ import static org.eclipse.jgit.lib.Constants.OBJECT_ID_STRING_LENGTH;
 import static org.eclipse.jgit.lib.FileMode.REGULAR_FILE;
 
 import java.io.IOException;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
 
 import org.eclipse.jgit.lib.AnyObjectId;
 import org.eclipse.jgit.lib.ObjectId;
@@ -103,6 +105,28 @@ class LeafBucket extends InMemoryNoteBucket {
                return 0 <= idx ? notes[idx].getData() : null;
        }
 
+       @Override
+       Iterator<Note> iterator(AnyObjectId objId, ObjectReader reader) {
+               return new Iterator<Note>() {
+                       private int idx;
+
+                       public boolean hasNext() {
+                               return idx < cnt;
+                       }
+
+                       public Note next() {
+                               if (hasNext())
+                                       return notes[idx++];
+                               else
+                                       throw new NoSuchElementException();
+                       }
+
+                       public void remove() {
+                               throw new UnsupportedOperationException();
+                       }
+               };
+       }
+
        InMemoryNoteBucket set(AnyObjectId noteOn, AnyObjectId noteData,
                        ObjectReader or) throws IOException {
                int p = search(noteOn);
index f5465148a8814dec87ee5813ec13a4c9c30102c7..e13067cc12a0f7bfcbe46486d89776e2d6a75122 100644 (file)
@@ -44,6 +44,7 @@
 package org.eclipse.jgit.notes;
 
 import java.io.IOException;
+import java.util.Iterator;
 
 import org.eclipse.jgit.lib.AnyObjectId;
 import org.eclipse.jgit.lib.ObjectId;
@@ -60,6 +61,9 @@ abstract class NoteBucket {
        abstract ObjectId get(AnyObjectId objId, ObjectReader reader)
                        throws IOException;
 
+       abstract Iterator<Note> iterator(AnyObjectId objId, ObjectReader reader)
+                       throws IOException;
+
        abstract InMemoryNoteBucket set(AnyObjectId noteOn, AnyObjectId noteData,
                        ObjectReader reader) throws IOException;