summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/BitmapIndexTest.java85
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BitmapIndexImpl.java16
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/BitmapIndex.java52
3 files changed, 152 insertions, 1 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/BitmapIndexTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/BitmapIndexTest.java
new file mode 100644
index 0000000000..ee4fa8bcc7
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/BitmapIndexTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2024, Google Inc. and others
+ *
+ * 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.lib;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+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.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.junit.Before;
+import org.junit.Test;
+
+public class BitmapIndexTest extends LocalDiskRepositoryTestCase {
+
+ private static final String MAIN = "refs/heads/main";
+
+ TestRepository<FileRepository> 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());
+ }
+
+
+ @Test
+ public void listener_getBitmap_counted() throws Exception {
+ try (RevWalk rw = repo.getRevWalk();
+ ObjectReader or = rw.getObjectReader()) {
+ BitmapLookupCounter counter = new BitmapLookupCounter();
+ BitmapIndex bitmapIndex = or.getBitmapIndex();
+ bitmapIndex.addBitmapLookupListener(counter);
+
+ bitmapIndex.getBitmap(tipWithBitmap);
+ bitmapIndex.getBitmap(tipWithBitmap);
+ bitmapIndex.getBitmap(ObjectId.zeroId());
+
+ assertEquals(2, counter.bitmapFound);
+ assertEquals(1, counter.bitmapNotFound);
+ }
+ }
+
+ private static class BitmapLookupCounter
+ implements BitmapIndex.BitmapLookupListener {
+ int bitmapFound = 0;
+
+ int bitmapNotFound = 0;
+
+ @Override
+ public void onBitmapFound(AnyObjectId oid) {
+ bitmapFound += 1;
+ }
+
+ @Override
+ public void onBitmapNotFound(AnyObjectId oid) {
+ bitmapNotFound += 1;
+ }
+ }
+} \ No newline at end of file
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BitmapIndexImpl.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BitmapIndexImpl.java
index 8d8c6a0455..5602158d2d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BitmapIndexImpl.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BitmapIndexImpl.java
@@ -38,6 +38,8 @@ public class BitmapIndexImpl implements BitmapIndex {
final int indexObjectCount;
+ private BitmapLookupListener listener = BitmapLookupListener.NOOP;
+
/**
* Creates a BitmapIndex that is back by Compressed bitmaps.
*
@@ -57,8 +59,11 @@ public class BitmapIndexImpl implements BitmapIndex {
@Override
public CompressedBitmap getBitmap(AnyObjectId objectId) {
EWAHCompressedBitmap compressed = packIndex.getBitmap(objectId);
- if (compressed == null)
+ if (compressed == null) {
+ listener.onBitmapNotFound(objectId);
return null;
+ }
+ listener.onBitmapFound(objectId);
return new CompressedBitmap(compressed, this);
}
@@ -67,6 +72,15 @@ public class BitmapIndexImpl implements BitmapIndex {
return new CompressedBitmapBuilder(this);
}
+ @Override
+ public void addBitmapLookupListener(BitmapLookupListener listener) {
+ if (listener == null) {
+ throw new IllegalArgumentException(
+ "Use NOOP instance for no listener"); // @NON-NLS-1@
+ }
+ this.listener = listener;
+ }
+
int findPosition(AnyObjectId objectId) {
int position = packIndex.findPosition(objectId);
if (position < 0) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BitmapIndex.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BitmapIndex.java
index 97b5847f91..acaa6335d4 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BitmapIndex.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BitmapIndex.java
@@ -40,6 +40,58 @@ public interface BitmapIndex {
BitmapBuilder newBitmapBuilder();
/**
+ * Report the results of {@link #getBitmap(AnyObjectId)}
+ *
+ * @since 6.8
+ */
+ interface BitmapLookupListener {
+
+ /**
+ * This object has a bitmap in the index
+ *
+ * @param oid
+ * object id
+ */
+ void onBitmapFound(AnyObjectId oid);
+
+ /**
+ * This object does not have a bitmap in the index
+ *
+ * @param oid
+ * object id
+ */
+ void onBitmapNotFound(AnyObjectId oid);
+
+ /**
+ * No-op instance
+ */
+ BitmapLookupListener NOOP = new BitmapLookupListener() {
+ @Override
+ public void onBitmapFound(AnyObjectId oid) {
+ // Nothing to do
+ }
+
+ @Override
+ public void onBitmapNotFound(AnyObjectId oid) {
+ // Nothing to do
+ }
+ };
+ }
+
+ /**
+ * Report to this listener whether {@link #getBitmap(AnyObjectId)} finds a
+ * commit.
+ *
+ * @param listener
+ * instance listening to lookup events in the index. Never null.
+ * Set to {@link BitmapLookupListener#NOOP} to disable.
+ * @since 6.8
+ */
+ default void addBitmapLookupListener(BitmapLookupListener listener) {
+ // Empty implementation for API compatibility
+ }
+
+ /**
* A bitmap representation of ObjectIds that can be iterated to return the
* underlying {@code ObjectId}s or operated on with other {@code Bitmap}s.
*/