9639474b6d
Sometimes a bitmap traversal still has to walk some commits manually, because those commits aren't included in the bitmap packfile (e.g., due to a push or commit since the last full repack). If we're given an object filter, we don't pass it down to this traversal. It's not necessary for correctness because the bitmap code has its own filters to post-process the bitmap result (which it must, to filter out the objects that _are_ mentioned in the bitmapped packfile). And with blob filters, there was no performance reason to pass along those filters, either. The fill-in traversal could omit them from the result, but it wouldn't save us any time to do so, since we'd still have to walk each tree entry to see if it's a blob or not. But now that we support tree filters, there's opportunity for savings. A tree:depth=0 filter means we can avoid accessing trees entirely, since we know we won't them (or any of the subtrees or blobs they point to). The new test in p5310 shows this off (the "partial bitmap" state is one where HEAD~100 and its ancestors are all in a bitmapped pack, but HEAD~100..HEAD are not). Here are the results (run against linux.git): Test HEAD^ HEAD ------------------------------------------------------------------------------------------------- [...] 5310.16: rev-list with tree filter (partial bitmap) 0.19(0.17+0.02) 0.03(0.02+0.01) -84.2% The absolute number of savings isn't _huge_, but keep in mind that we only omitted 100 first-parent links (in the version of linux.git here, that's 894 actual commits). In a more pathological case, we might have a much larger proportion of non-bitmapped commits. I didn't bother creating such a case in the perf script because the setup is expensive, and this is plenty to show the savings as a percentage. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
100 lines
2.5 KiB
Bash
Executable File
100 lines
2.5 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
test_description='Tests pack performance using bitmaps'
|
|
. ./perf-lib.sh
|
|
|
|
test_perf_large_repo
|
|
|
|
# note that we do everything through config,
|
|
# since we want to be able to compare bitmap-aware
|
|
# git versus non-bitmap git
|
|
#
|
|
# We intentionally use the deprecated pack.writebitmaps
|
|
# config so that we can test against older versions of git.
|
|
test_expect_success 'setup bitmap config' '
|
|
git config pack.writebitmaps true
|
|
'
|
|
|
|
test_perf 'repack to disk' '
|
|
git repack -ad
|
|
'
|
|
|
|
test_perf 'simulated clone' '
|
|
git pack-objects --stdout --all </dev/null >/dev/null
|
|
'
|
|
|
|
test_perf 'simulated fetch' '
|
|
have=$(git rev-list HEAD~100 -1) &&
|
|
{
|
|
echo HEAD &&
|
|
echo ^$have
|
|
} | git pack-objects --revs --stdout >/dev/null
|
|
'
|
|
|
|
test_perf 'pack to file (bitmap)' '
|
|
git pack-objects --use-bitmap-index --all pack1b </dev/null >/dev/null
|
|
'
|
|
|
|
test_perf 'rev-list (commits)' '
|
|
git rev-list --all --use-bitmap-index >/dev/null
|
|
'
|
|
|
|
test_perf 'rev-list (objects)' '
|
|
git rev-list --all --use-bitmap-index --objects >/dev/null
|
|
'
|
|
|
|
test_perf 'rev-list count with blob:none' '
|
|
git rev-list --use-bitmap-index --count --objects --all \
|
|
--filter=blob:none >/dev/null
|
|
'
|
|
|
|
test_perf 'rev-list count with blob:limit=1k' '
|
|
git rev-list --use-bitmap-index --count --objects --all \
|
|
--filter=blob:limit=1k >/dev/null
|
|
'
|
|
|
|
test_perf 'rev-list count with tree:0' '
|
|
git rev-list --use-bitmap-index --count --objects --all \
|
|
--filter=tree:0 >/dev/null
|
|
'
|
|
|
|
test_perf 'simulated partial clone' '
|
|
git pack-objects --stdout --all --filter=blob:none </dev/null >/dev/null
|
|
'
|
|
|
|
test_expect_success 'create partial bitmap state' '
|
|
# pick a commit to represent the repo tip in the past
|
|
cutoff=$(git rev-list HEAD~100 -1) &&
|
|
orig_tip=$(git rev-parse HEAD) &&
|
|
|
|
# now kill off all of the refs and pretend we had
|
|
# just the one tip
|
|
rm -rf .git/logs .git/refs/* .git/packed-refs &&
|
|
git update-ref HEAD $cutoff &&
|
|
|
|
# and then repack, which will leave us with a nice
|
|
# big bitmap pack of the "old" history, and all of
|
|
# the new history will be loose, as if it had been pushed
|
|
# up incrementally and exploded via unpack-objects
|
|
git repack -Ad &&
|
|
|
|
# and now restore our original tip, as if the pushes
|
|
# had happened
|
|
git update-ref HEAD $orig_tip
|
|
'
|
|
|
|
test_perf 'clone (partial bitmap)' '
|
|
git pack-objects --stdout --all </dev/null >/dev/null
|
|
'
|
|
|
|
test_perf 'pack to file (partial bitmap)' '
|
|
git pack-objects --use-bitmap-index --all pack2b </dev/null >/dev/null
|
|
'
|
|
|
|
test_perf 'rev-list with tree filter (partial bitmap)' '
|
|
git rev-list --use-bitmap-index --count --objects --all \
|
|
--filter=tree:0 >/dev/null
|
|
'
|
|
|
|
test_done
|