pack-bitmap: save "have" bitmap from walk
authorJeff King <peff@peff.net>
Tue, 21 Aug 2018 19:07:01 +0000 (15:07 -0400)
committerJunio C Hamano <gitster@pobox.com>
Tue, 21 Aug 2018 19:33:39 +0000 (12:33 -0700)
When we do a bitmap walk, we save the result, which
represents (WANTs & ~HAVEs); i.e., every object we care
about visiting in our walk. However, we throw away the
haves bitmap, which can sometimes be useful, too. Save it
and provide an access function so code which has performed a
walk can query it.

A few notes on the accessor interface:

- the bitmap code calls these "haves" because it grew out
of the want/have negotiation for fetches. But really,
these are simply the objects that would be flagged
UNINTERESTING in a regular traversal. Let's use that
more universal nomenclature for the external module
interface. We may want to change the internal naming
inside the bitmap code, but that's outside the scope of
this patch.

- it still uses a bare "sha1" rather than "oid". That's
true of all of the bitmap code. And in this particular
instance, our caller in pack-objects is dealing with the
bare sha1 that comes from a packed REF_DELTA (we're
pointing directly to the mmap'd pack on disk). That's
something we'll have to deal with as we transition to a
new hash, but we can wait and see how the caller ends up
being fixed and adjust this interface accordingly.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
pack-bitmap.c
pack-bitmap.h
index f0a1937a1cc5fbb13fc705df8d193a43a0648198..c3231ef9ef2d57ce21ebe8db64401af95a0bb6e6 100644 (file)
@@ -86,6 +86,9 @@ struct bitmap_index {
        /* Bitmap result of the last performed walk */
        struct bitmap *result;
 
+       /* "have" bitmap from the last performed walk */
+       struct bitmap *haves;
+
        /* Version of the bitmap index */
        unsigned int version;
 
@@ -759,8 +762,8 @@ struct bitmap_index *prepare_bitmap_walk(struct rev_info *revs)
                bitmap_and_not(wants_bitmap, haves_bitmap);
 
        bitmap_git->result = wants_bitmap;
+       bitmap_git->haves = haves_bitmap;
 
-       bitmap_free(haves_bitmap);
        return bitmap_git;
 
 cleanup:
@@ -1114,5 +1117,25 @@ void free_bitmap_index(struct bitmap_index *b)
        free(b->ext_index.objects);
        free(b->ext_index.hashes);
        bitmap_free(b->result);
+       bitmap_free(b->haves);
        free(b);
 }
+
+int bitmap_has_sha1_in_uninteresting(struct bitmap_index *bitmap_git,
+                                    const unsigned char *sha1)
+{
+       int pos;
+
+       if (!bitmap_git)
+               return 0; /* no bitmap loaded */
+       if (!bitmap_git->result)
+               BUG("failed to perform bitmap walk before querying");
+       if (!bitmap_git->haves)
+               return 0; /* walk had no "haves" */
+
+       pos = bitmap_position_packfile(bitmap_git, sha1);
+       if (pos < 0)
+               return 0;
+
+       return bitmap_get(bitmap_git->haves, pos);
+}
index 8a04741e1253b0ba801445a76ceb8e4937121f73..c633bf523898db8d261f5c3f8098c3e843ca9c21 100644 (file)
@@ -53,6 +53,13 @@ int rebuild_existing_bitmaps(struct bitmap_index *, struct packing_data *mapping
                             khash_sha1 *reused_bitmaps, int show_progress);
 void free_bitmap_index(struct bitmap_index *);
 
+/*
+ * After a traversal has been performed on the bitmap_index, this can be
+ * queried to see if a particular object was reachable from any of the
+ * objects flagged as UNINTERESTING.
+ */
+int bitmap_has_sha1_in_uninteresting(struct bitmap_index *, const unsigned char *sha1);
+
 void bitmap_writer_show_progress(int show);
 void bitmap_writer_set_checksum(unsigned char *sha1);
 void bitmap_writer_build_type_index(struct packing_data *to_pack,