]> source.dussan.org Git - jgit.git/commitdiff
Scan through all merged reftables for max/min update indices 67/159767/2
authorMinh Thai <mthai@google.com>
Fri, 20 Mar 2020 06:10:41 +0000 (23:10 -0700)
committerMinh Thai <mthai@google.com>
Fri, 20 Mar 2020 18:12:34 +0000 (11:12 -0700)
Since reftables might have update index ranges that are overlapped.

Change-Id: I8f8215b99a0a978d4dd0155dbaf33e5e06ea8202
Signed-off-by: Minh Thai <mthai@google.com>
org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/MergedReftableTest.java
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/MergedReftable.java

index 2a2aeb592fba238a47116d9ece370d912839a881..a246ac9e9c1b180117569881e599aaacba605646 100644 (file)
@@ -286,6 +286,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(
index 18c013fd8d20e9dc2e6b02e75aa4d71081d4f6c4..36335153a13b55bd961925045c3068de43997fbd 100644 (file)
@@ -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} */