Skip to content

Commit 540cdc1

Browse files
pks-tgitster
authored andcommitted
pack-bitmap: avoid traversal of objects referenced by uninteresting tag
When preparing the bitmap walk, we first establish the set of of have and want objects by iterating over the set of pending objects: if an object is marked as uninteresting, it's declared as an object we already have, otherwise as an object we want. These two sets are then used to compute which transitively referenced objects we need to obtain. One special case here are tag objects: when a tag is requested, we resolve it to its first not-tag object and add both resolved objects as well as the tag itself into either the have or want set. Given that the uninteresting-property always propagates to referenced objects, it is clear that if the tag is uninteresting, so are its children and vice versa. But we fail to propagate the flag, which effectively means that referenced objects will always be interesting except for the case where they have already been marked as uninteresting explicitly. This mislabeling does not impact correctness: we now have it in our "wants" set, and given that we later do an `AND NOT` of the bitmaps of "wants" and "haves" sets it is clear that the result must be the same. But we now start to needlessly traverse the tag's referenced objects in case it is uninteresting, even though we know that each referenced object will be uninteresting anyway. In the worst case, this can lead to a complete graph walk just to establish that we do not care for any object. Fix the issue by propagating the `UNINTERESTING` flag to pointees of tag objects and add a benchmark with negative revisions to p5310. This shows some nice performance benefits, tested with linux.git: Test HEAD~ HEAD --------------------------------------------------------------------------------------------------------------- 5310.3: repack to disk 193.18(181.46+16.42) 194.61(183.41+15.83) +0.7% 5310.4: simulated clone 25.93(24.88+1.05) 25.81(24.73+1.08) -0.5% 5310.5: simulated fetch 2.64(5.30+0.69) 2.59(5.16+0.65) -1.9% 5310.6: pack to file (bitmap) 58.75(57.56+6.30) 58.29(57.61+5.73) -0.8% 5310.7: rev-list (commits) 1.45(1.18+0.26) 1.46(1.22+0.24) +0.7% 5310.8: rev-list (objects) 15.35(14.22+1.13) 15.30(14.23+1.07) -0.3% 5310.9: rev-list with tag negated via --not --all (objects) 22.49(20.93+1.56) 0.11(0.09+0.01) -99.5% 5310.10: rev-list with negative tag (objects) 0.61(0.44+0.16) 0.51(0.35+0.16) -16.4% 5310.11: rev-list count with blob:none 12.15(11.19+0.96) 12.18(11.19+0.99) +0.2% 5310.12: rev-list count with blob:limit=1k 17.77(15.71+2.06) 17.75(15.63+2.12) -0.1% 5310.13: rev-list count with tree:0 1.69(1.31+0.38) 1.68(1.28+0.39) -0.6% 5310.14: simulated partial clone 20.14(19.15+0.98) 19.98(18.93+1.05) -0.8% 5310.16: clone (partial bitmap) 12.78(13.89+1.07) 12.72(13.99+1.01) -0.5% 5310.17: pack to file (partial bitmap) 42.07(45.44+2.72) 41.44(44.66+2.80) -1.5% 5310.18: rev-list with tree filter (partial bitmap) 0.44(0.29+0.15) 0.46(0.32+0.14) +4.5% While most benchmarks are probably in the range of noise, the newly added 5310.9 and 5310.10 benchmarks consistenly perform better. Signed-off-by: Patrick Steinhardt <[email protected]>. Signed-off-by: Junio C Hamano <[email protected]>
1 parent 94f6e3e commit 540cdc1

File tree

2 files changed

+15
-0
lines changed

2 files changed

+15
-0
lines changed

pack-bitmap.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -969,6 +969,7 @@ struct bitmap_index *prepare_bitmap_walk(struct rev_info *revs,
969969
object_list_insert(object, &wants);
970970

971971
object = parse_object_or_die(get_tagged_oid(tag), NULL);
972+
object->flags |= (tag->object.flags & UNINTERESTING);
972973
}
973974

974975
if (object->flags & UNINTERESTING)

t/perf/p5310-pack-bitmaps.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ test_expect_success 'setup bitmap config' '
1515
git config pack.writebitmaps true
1616
'
1717

18+
# we need to create the tag up front such that it is covered by the repack and
19+
# thus by generated bitmaps.
20+
test_expect_success 'create tags' '
21+
git tag --message="tag pointing to HEAD" perf-tag HEAD
22+
'
23+
1824
test_perf 'repack to disk' '
1925
git repack -ad
2026
'
@@ -43,6 +49,14 @@ test_perf 'rev-list (objects)' '
4349
git rev-list --all --use-bitmap-index --objects >/dev/null
4450
'
4551

52+
test_perf 'rev-list with tag negated via --not --all (objects)' '
53+
git rev-list perf-tag --not --all --use-bitmap-index --objects >/dev/null
54+
'
55+
56+
test_perf 'rev-list with negative tag (objects)' '
57+
git rev-list HEAD --not perf-tag --use-bitmap-index --objects >/dev/null
58+
'
59+
4660
test_perf 'rev-list count with blob:none' '
4761
git rev-list --use-bitmap-index --count --objects --all \
4862
--filter=blob:none >/dev/null

0 commit comments

Comments
 (0)