From 8ea5409ec18a6e2a6238948fa5af13b9b26b1955 Mon Sep 17 00:00:00 2001 From: Ivan Frade Date: Mon, 20 Nov 2023 13:18:37 -0800 Subject: [PATCH] BitmapWalkerTest: New test for the walker Change-Id: I414f5bdd86e5623d7669fa187df19e06acd02cef --- .../jgit/revwalk/BitmapWalkerTest.java | 161 ++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmapWalkerTest.java diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmapWalkerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmapWalkerTest.java new file mode 100644 index 000000000..a59a71d19 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmapWalkerTest.java @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2023, Google Inc. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0 which is available at + * https://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +package org.eclipse.jgit.revwalk; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.util.List; + +import org.eclipse.jgit.internal.storage.file.FileRepository; +import org.eclipse.jgit.internal.storage.file.GC; +import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase; +import org.eclipse.jgit.junit.TestRepository; +import org.eclipse.jgit.lib.AnyObjectId; +import org.eclipse.jgit.lib.BitmapIndex; +import org.eclipse.jgit.lib.BitmapIndex.Bitmap; +import org.eclipse.jgit.lib.BitmapIndex.BitmapBuilder; +import org.eclipse.jgit.lib.BitmapIndex.BitmapLookupListener; +import org.eclipse.jgit.lib.NullProgressMonitor; +import org.eclipse.jgit.lib.ObjectReader; +import org.junit.Before; +import org.junit.Test; + +public class BitmapWalkerTest extends LocalDiskRepositoryTestCase { + + private static final String MAIN = "refs/heads/main"; + + TestRepository repo; + + RevCommit tipWithBitmap; + + @Override + @Before + public void setUp() throws Exception { + super.setUp(); + FileRepository db = createWorkRepository(); + repo = new TestRepository<>(db); + + RevCommit base = repo.commit().create(); + RevCommit one = repo.commit().parent(base).create(); + tipWithBitmap = repo.commit().parent(one).create(); + repo.update(MAIN, tipWithBitmap); + + GC gc = new GC(repo.getRepository()); + gc.setAuto(false); + gc.gc().get(); + + assertNotNull(repo.getRevWalk().getObjectReader().getBitmapIndex()); + } + + private static class BitmapWalkCounter implements BitmapLookupListener { + int withBitmap; + + int withoutBitmap; + + @Override + public void onBitmapFound(AnyObjectId oid) { + withBitmap += 1; + } + + @Override + public void onBitmapNotFound(AnyObjectId oid) { + withoutBitmap += 1; + } + } + + @Test + public void counters_bitmapAtTip() throws Exception { + try (RevWalk rw = repo.getRevWalk(); + ObjectReader or = rw.getObjectReader()) { + BitmapWalkCounter counter = new BitmapWalkCounter(); + BitmapIndex bitmapIndex = or.getBitmapIndex(); + bitmapIndex.addBitmapLookupListener(counter); + BitmapWalker bw = new BitmapWalker(rw.toObjectWalkWithSameObjects(), + bitmapIndex, NullProgressMonitor.INSTANCE); + BitmapBuilder bitmap = bw.findObjects(List.of(tipWithBitmap), null, + true); + // First commit has a tree, so in total 4 objects + assertEquals(4, bitmap.cardinality()); + assertEquals(1, counter.withBitmap); + assertEquals(0, counter.withoutBitmap); + assertEquals(0, bw.getCountOfBitmapIndexMisses()); + } + } + + @Test + public void counters_bitmapAfterAStep() throws Exception { + System.out.println("Old tip: " + tipWithBitmap); + RevCommit newTip = repo.commit().parent(tipWithBitmap).create(); + System.out.println("New tip: " + newTip); + try (RevWalk rw = repo.getRevWalk(); + ObjectReader or = rw.getObjectReader()) { + BitmapWalkCounter counter = new BitmapWalkCounter(); + BitmapIndex bitmapIndex = or.getBitmapIndex(); + bitmapIndex.addBitmapLookupListener(counter); + BitmapWalker bw = new BitmapWalker(rw.toObjectWalkWithSameObjects(), + bitmapIndex, NullProgressMonitor.INSTANCE); + + bw.findObjects(List.of(newTip), null, true); + + assertEquals(1, counter.withBitmap); + // It checks bitmap before marking as interesting, and again in the + // walk + assertEquals(2, counter.withoutBitmap); + assertEquals(1, bw.getCountOfBitmapIndexMisses()); + } + } + + @Test + public void counters_bitmapAfterThreeSteps() throws Exception { + RevCommit newOne = repo.commit().parent(tipWithBitmap).create(); + RevCommit newTwo = repo.commit().parent(newOne).create(); + RevCommit newTip = repo.commit().parent(newTwo).create(); + + try (RevWalk rw = repo.getRevWalk(); + ObjectReader or = rw.getObjectReader()) { + BitmapWalkCounter counter = new BitmapWalkCounter(); + BitmapIndex bitmapIndex = or.getBitmapIndex(); + bitmapIndex.addBitmapLookupListener(counter); + BitmapWalker bw = new BitmapWalker(rw.toObjectWalkWithSameObjects(), + bitmapIndex, NullProgressMonitor.INSTANCE); + + bw.findObjects(List.of(newTip), null, true); + + assertEquals(1, counter.withBitmap); + assertEquals(4, counter.withoutBitmap); + assertEquals(3, bw.getCountOfBitmapIndexMisses()); + } + } + + @Test + public void counters_bitmapAfterThreeStepsWithSeen() throws Exception { + RevCommit newOne = repo.commit().parent(tipWithBitmap).create(); + RevCommit newTwo = repo.commit().parent(newOne).create(); + RevCommit newTip = repo.commit().parent(newTwo).create(); + + try (RevWalk rw = repo.getRevWalk(); + ObjectReader or = rw.getObjectReader()) { + BitmapIndex bitmapIndex = or.getBitmapIndex(); + Bitmap seen = bitmapIndex.getBitmap(tipWithBitmap); + BitmapBuilder seenBB = bitmapIndex.newBitmapBuilder().or(seen); + BitmapWalkCounter counter = new BitmapWalkCounter(); + bitmapIndex.addBitmapLookupListener(counter); + BitmapWalker bw = new BitmapWalker(rw.toObjectWalkWithSameObjects(), + bitmapIndex, NullProgressMonitor.INSTANCE); + + bw.findObjects(List.of(newTip), seenBB, true); + + assertEquals(0, counter.withBitmap); + assertEquals(4, counter.withoutBitmap); + assertEquals(3, bw.getCountOfBitmapIndexMisses()); + } + } +}