Add internal API for note iteration

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>
This commit is contained in:
Shawn O. Pearce 2010-11-04 18:46:19 -07:00
parent 3e2b9b691e
commit 3728918d72
3 changed files with 85 additions and 0 deletions

View File

@ -46,9 +46,12 @@
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 @@ ObjectId get(AnyObjectId objId, ObjectReader or) throws IOException {
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 @@ ObjectId get(AnyObjectId objId, ObjectReader or) throws IOException {
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 {

View File

@ -47,6 +47,8 @@
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 @@ ObjectId get(AnyObjectId objId, ObjectReader or) {
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);

View 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;