summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMinh Thai <mthai@google.com>2020-03-19 23:10:41 -0700
committerMinh Thai <mthai@google.com>2020-03-20 11:12:34 -0700
commit06748c205c44bb4eaf6015387112de97f566c6a2 (patch)
tree6f36c14840bdfbc26bf11160bebd7780b4ea483c
parent7d3b6308fc2e44e8ae462d56fb2f1aa61012fb35 (diff)
downloadjgit-06748c205c44bb4eaf6015387112de97f566c6a2.tar.gz
jgit-06748c205c44bb4eaf6015387112de97f566c6a2.zip
Scan through all merged reftables for max/min update indices
Since reftables might have update index ranges that are overlapped. Change-Id: I8f8215b99a0a978d4dd0155dbaf33e5e06ea8202 Signed-off-by: Minh Thai <mthai@google.com>
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/MergedReftableTest.java117
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/MergedReftable.java24
2 files changed, 137 insertions, 4 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/MergedReftableTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/MergedReftableTest.java
index 2a2aeb592f..a246ac9e9c 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/MergedReftableTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/MergedReftableTest.java
@@ -287,6 +287,123 @@ public class MergedReftableTest {
}
@Test
+ public void nonOverlappedUpdateIndices() throws IOException {
+ ByteArrayOutputStream buf = new ByteArrayOutputStream();
+ ReftableWriter writer = new ReftableWriter(buf)
+ .setMinUpdateIndex(1)
+ .setMaxUpdateIndex(2)
+ .begin();
+ writer.writeRef(ref("refs/heads/a", 1), 1);
+ writer.writeRef(ref("refs/heads/b", 2), 2);
+ writer.finish();
+ byte[] base = buf.toByteArray();
+
+ buf = new ByteArrayOutputStream();
+ writer = new ReftableWriter(buf)
+ .setMinUpdateIndex(3)
+ .setMaxUpdateIndex(4)
+ .begin();
+ writer.writeRef(ref("refs/heads/a", 10), 3);
+ writer.writeRef(ref("refs/heads/b", 20), 4);
+ writer.finish();
+ byte[] delta = buf.toByteArray();
+
+ MergedReftable mr = merge(base, delta);
+ assertEquals(1, mr.minUpdateIndex());
+ assertEquals(4, mr.maxUpdateIndex());
+
+ try (RefCursor rc = mr.allRefs()) {
+ assertTrue(rc.next());
+ assertEquals("refs/heads/a", rc.getRef().getName());
+ assertEquals(id(10), rc.getRef().getObjectId());
+ assertEquals(3, rc.getRef().getUpdateIndex());
+
+ assertTrue(rc.next());
+ assertEquals("refs/heads/b", rc.getRef().getName());
+ assertEquals(id(20), rc.getRef().getObjectId());
+ assertEquals(4, rc.getRef().getUpdateIndex());
+ }
+ }
+
+ @Test
+ public void overlappedUpdateIndices() throws IOException {
+ ByteArrayOutputStream buf = new ByteArrayOutputStream();
+ ReftableWriter writer = new ReftableWriter(buf)
+ .setMinUpdateIndex(1)
+ .setMaxUpdateIndex(3)
+ .begin();
+ writer.writeRef(ref("refs/heads/a", 1), 1);
+ writer.writeRef(ref("refs/heads/b", 2), 3);
+ writer.finish();
+ byte[] base = buf.toByteArray();
+
+ buf = new ByteArrayOutputStream();
+ writer = new ReftableWriter(buf)
+ .setMinUpdateIndex(2)
+ .setMaxUpdateIndex(4)
+ .begin();
+ writer.writeRef(ref("refs/heads/a", 10), 2);
+ writer.writeRef(ref("refs/heads/b", 20), 4);
+ writer.finish();
+ byte[] delta = buf.toByteArray();
+
+ MergedReftable mr = merge(base, delta);
+ assertEquals(1, mr.minUpdateIndex());
+ assertEquals(4, mr.maxUpdateIndex());
+
+ try (RefCursor rc = mr.allRefs()) {
+ assertTrue(rc.next());
+ assertEquals("refs/heads/a", rc.getRef().getName());
+ assertEquals(id(10), rc.getRef().getObjectId());
+ assertEquals(2, rc.getRef().getUpdateIndex());
+
+ assertTrue(rc.next());
+ assertEquals("refs/heads/b", rc.getRef().getName());
+ assertEquals(id(20), rc.getRef().getObjectId());
+ assertEquals(4, rc.getRef().getUpdateIndex());
+ }
+ }
+
+ @Test
+ public void enclosedUpdateIndices() throws IOException {
+ ByteArrayOutputStream buf = new ByteArrayOutputStream();
+ ReftableWriter writer = new ReftableWriter(buf)
+ .setMinUpdateIndex(1)
+ .setMaxUpdateIndex(4)
+ .begin();
+ writer.writeRef(ref("refs/heads/a", 1), 1);
+ writer.writeRef(ref("refs/heads/b", 20), 4);
+ writer.finish();
+ byte[] base = buf.toByteArray();
+
+ buf = new ByteArrayOutputStream();
+ writer = new ReftableWriter(buf)
+ .setMinUpdateIndex(2)
+ .setMaxUpdateIndex(3)
+ .begin();
+ writer.writeRef(ref("refs/heads/a", 10), 2);
+ writer.writeRef(ref("refs/heads/b", 2), 3);
+ writer.finish();
+ byte[] delta = buf.toByteArray();
+
+ MergedReftable mr = merge(base, delta);
+ assertEquals(1, mr.minUpdateIndex());
+ assertEquals(4, mr.maxUpdateIndex());
+
+ try (RefCursor rc = mr.allRefs()) {
+ assertTrue(rc.next());
+ assertEquals("refs/heads/a", rc.getRef().getName());
+ assertEquals(id(10), rc.getRef().getObjectId());
+ assertEquals(2, rc.getRef().getUpdateIndex());
+
+ assertTrue(rc.next());
+ assertEquals("refs/heads/b", rc.getRef().getName());
+ assertEquals(id(20), rc.getRef().getObjectId());
+ assertEquals(4, rc.getRef().getUpdateIndex());
+ }
+ }
+
+ @Test
public void compaction() throws IOException {
List<Ref> delta1 = Arrays.asList(
ref("refs/heads/next", 4),
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/MergedReftable.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/MergedReftable.java
index 18c013fd8d..36335153a1 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/MergedReftable.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/MergedReftable.java
@@ -61,8 +61,16 @@ public class MergedReftable extends Reftable {
*/
@Override
public long maxUpdateIndex() throws IOException {
- return tables.length > 0 ? tables[tables.length - 1].maxUpdateIndex()
- : 0;
+ if (tables.length == 0) {
+ return 0;
+ }
+ long maxUpdateIndex = tables[tables.length - 1].maxUpdateIndex();
+ for (int i = tables.length - 2; i >= 0; i--) {
+ if (maxUpdateIndex < tables[i].maxUpdateIndex()) {
+ maxUpdateIndex = tables[i].maxUpdateIndex();
+ }
+ }
+ return maxUpdateIndex;
}
/**
@@ -70,8 +78,16 @@ public class MergedReftable extends Reftable {
*/
@Override
public long minUpdateIndex() throws IOException {
- return tables.length > 0 ? tables[0].minUpdateIndex()
- : 0;
+ if (tables.length == 0) {
+ return 0;
+ }
+ long minUpdateIndex = tables[0].minUpdateIndex();
+ for (int i = 0; i < tables.length - 1; i++) {
+ if (tables[i].minUpdateIndex() < minUpdateIndex) {
+ minUpdateIndex = tables[i].minUpdateIndex();
+ }
+ }
+ return minUpdateIndex;
}
/** {@inheritDoc} */