{"thread":{"id":"53291","subject":"[PATCH 0/4] pack-bitmap: use bitmaps for traversals with '--filter=tree:0'","startedAt":"2020-04-22T23:13:25Z","lastAt":"2020-04-24T16:54:39Z","messageCount":8,"participants":["Taylor Blau","Jeff King"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"395956","messageId":"cover.1587597151.git.me@ttaylorr.com","threadId":"53291","inReplyTo":null,"subject":"[PATCH 0/4] pack-bitmap: use bitmaps for traversals with '--filter=tree:0'","fromName":"Taylor Blau","fromEmail":"me@ttaylorr.com","sentAt":"2020-04-22T23:13:19Z","receivedAt":"2020-04-22T23:13:25Z","isPatch":true,"sender":{"key":"me@ttaylorr.com","avatar":"https://avatars.githubusercontent.com/u/301000140?v=4"},"body":"Hi,\n\nThis series contains a handful of patches to make object traversals with\n'--filter=tree:0' be bitmaps-compatible. They have been kicking around\nin GitHub's fork for some time, and we use them on every\n'--filter=tree:0' fetch.\n\nThis is a prerequisite for a future series which will introduce\nconfiguration in upload-pack to indicate which filter choices are and\naren't supported [1]. Since sending [1], GitHub's fork has grown support\nfor\n\n  [uploadpack 'filter.tree']\n    maxDepth = <n>\n\n...and so I figure that we could get this smaller series out for\ndiscussion before introducing that option, which doesn't make sense\nwithout having some faster variant of the 'tree' filter for certain\nvalues of 'n'.\n\nThanks,\nTaylor\n\n[1]: https://lore.kernel.org/git/cover.1584477196.git.me@ttaylorr.com/\n\nJeff King (2):\n  list-objects-filter: treat NULL filter_options as \"disabled\"\n  pack-bitmap: pass object filter to fill-in traversal\n\nTaylor Blau (2):\n  pack-bitmap.c: make object filtering functions generic\n  pack-bitmap.c: support 'tree:0' filtering\n\n list-objects-filter.c              |  3 ++\n pack-bitmap.c                      | 72 +++++++++++++++++++++++-------\n t/perf/p5310-pack-bitmaps.sh       | 10 +++++\n t/t6113-rev-list-bitmap-filters.sh | 21 +++++++++\n 4 files changed, 90 insertions(+), 16 deletions(-)\n\n--\n2.26.2.112.g65467a058e\n"},{"id":"395957","messageId":"ccbcb2ff0e0fc2adf6695b3785aef9b74a0c4bda.1587597151.git.me@ttaylorr.com","threadId":"53291","inReplyTo":"cover.1587597151.git.me@ttaylorr.com","subject":"[PATCH 1/4] list-objects-filter: treat NULL filter_options as \"disabled\"","fromName":"Taylor Blau","fromEmail":"me@ttaylorr.com","sentAt":"2020-04-22T23:13:24Z","receivedAt":"2020-04-22T23:13:28Z","isPatch":true,"sender":{"key":"me@ttaylorr.com","avatar":"https://avatars.githubusercontent.com/u/301000140?v=4"},"body":"From: Jeff King <peff@peff.net>\n\nIn most callers, we have an actual list_objects_filter_options struct,\nand if no filtering is desired its \"choice\" element will be\nLOFC_DISABLED. However, some code may have only a pointer to such a\nstruct which may be NULL (because _their_ callers didn't care about\nfiltering, either). Rather than forcing them to handle this explicitly\nlike:\n\n  if (filter_options)\n          traverse_commit_list_filtered(filter_options, revs,\n\t                                show_commit, show_object,\n\t\t\t\t\tshow_data, NULL);\n  else\n          traverse_commit_list(revs, show_commit, show_object,\n\t                             show_data);\n\nlet's just treat a NULL filter_options the same as LOFC_DISABLED. We\nonly need a small change, since that option struct is converted into a\nreal filter only in the \"init\" function.\n\nSigned-off-by: Jeff King <peff@peff.net>\nSigned-off-by: Taylor Blau <me@ttaylorr.com>\n---\n list-objects-filter.c | 3 +++\n 1 file changed, 3 insertions(+)\n\ndiff --git a/list-objects-filter.c b/list-objects-filter.c\nindex 1e8d4e763d..0a3ef3cab3 100644\n--- a/list-objects-filter.c\n+++ b/list-objects-filter.c\n@@ -663,6 +663,9 @@ struct filter *list_objects_filter__init(\n \n \tassert((sizeof(s_filters) / sizeof(s_filters[0])) == LOFC__COUNT);\n \n+\tif (!filter_options)\n+\t\treturn NULL;\n+\n \tif (filter_options->choice >= LOFC__COUNT)\n \t\tBUG(\"invalid list-objects filter choice: %d\",\n \t\t    filter_options->choice);\n-- \n2.26.2.112.g65467a058e\n\n"},{"id":"395958","messageId":"ec6d73d365d23cc926b98dabb1f30ee4232791db.1587597151.git.me@ttaylorr.com","threadId":"53291","inReplyTo":"cover.1587597151.git.me@ttaylorr.com","subject":"[PATCH 2/4] pack-bitmap.c: make object filtering functions generic","fromName":"Taylor Blau","fromEmail":"me@ttaylorr.com","sentAt":"2020-04-22T23:13:29Z","receivedAt":"2020-04-22T23:13:34Z","isPatch":true,"sender":{"key":"me@ttaylorr.com","avatar":"https://avatars.githubusercontent.com/u/301000140?v=4"},"body":"In 4f3bd5606a (pack-bitmap: implement BLOB_NONE filtering, 2020-02-14),\nfiltering support for bitmaps was added for the 'LOFC_BLOB_NONE' filter.\n\nIn the future, we would like to add support for filters that behave as\nif they exclude a certain type of object, for e.g., the tree depth\nfilter with depth 0.\n\nTo prepare for this, make some of the functions used for filtering more\ngeneric, such as 'find_tip_blobs' and 'filter_bitmap_blob_none' so that\nthey can work over arbitrary object types.\n\nTo that end, create 'find_tip_objects' and\n'filter_bitmap_exclude_type', and redefine the aforementioned functions\nin terms of those.\n\nSigned-off-by: Taylor Blau <me@ttaylorr.com>\n---\n pack-bitmap.c | 35 ++++++++++++++++++++++++-----------\n 1 file changed, 24 insertions(+), 11 deletions(-)\n\ndiff --git a/pack-bitmap.c b/pack-bitmap.c\nindex 49a8d10d0c..3693c9e62f 100644\n--- a/pack-bitmap.c\n+++ b/pack-bitmap.c\n@@ -715,8 +715,9 @@ static int in_bitmapped_pack(struct bitmap_index *bitmap_git,\n \treturn 0;\n }\n \n-static struct bitmap *find_tip_blobs(struct bitmap_index *bitmap_git,\n-\t\t\t\t     struct object_list *tip_objects)\n+static struct bitmap *find_tip_objects(struct bitmap_index *bitmap_git,\n+\t\t\t\t       struct object_list *tip_objects,\n+\t\t\t\t       enum object_type type)\n {\n \tstruct bitmap *result = bitmap_new();\n \tstruct object_list *p;\n@@ -724,7 +725,7 @@ static struct bitmap *find_tip_blobs(struct bitmap_index *bitmap_git,\n \tfor (p = tip_objects; p; p = p->next) {\n \t\tint pos;\n \n-\t\tif (p->item->type != OBJ_BLOB)\n+\t\tif (p->item->type != type)\n \t\t\tcontinue;\n \n \t\tpos = bitmap_position(bitmap_git, &p->item->oid);\n@@ -737,9 +738,10 @@ static struct bitmap *find_tip_blobs(struct bitmap_index *bitmap_git,\n \treturn result;\n }\n \n-static void filter_bitmap_blob_none(struct bitmap_index *bitmap_git,\n-\t\t\t\t    struct object_list *tip_objects,\n-\t\t\t\t    struct bitmap *to_filter)\n+static void filter_bitmap_exclude_type(struct bitmap_index *bitmap_git,\n+\t\t\t\t       struct object_list *tip_objects,\n+\t\t\t\t       struct bitmap *to_filter,\n+\t\t\t\t       enum object_type type)\n {\n \tstruct eindex *eindex = &bitmap_git->ext_index;\n \tstruct bitmap *tips;\n@@ -747,18 +749,21 @@ static void filter_bitmap_blob_none(struct bitmap_index *bitmap_git,\n \teword_t mask;\n \tuint32_t i;\n \n+\tif (type != OBJ_BLOB)\n+\t\tBUG(\"filter_bitmap_exclude_type: unsupported type '%d'\", type);\n+\n \t/*\n \t * The non-bitmap version of this filter never removes\n-\t * blobs which the other side specifically asked for,\n+\t * objects which the other side specifically asked for,\n \t * so we must match that behavior.\n \t */\n-\ttips = find_tip_blobs(bitmap_git, tip_objects);\n+\ttips = find_tip_objects(bitmap_git, tip_objects, type);\n \n \t/*\n \t * We can use the blob type-bitmap to work in whole words\n \t * for the objects that are actually in the bitmapped packfile.\n \t */\n-\tfor (i = 0, init_type_iterator(&it, bitmap_git, OBJ_BLOB);\n+\tfor (i = 0, init_type_iterator(&it, bitmap_git, type);\n \t     i < to_filter->word_alloc && ewah_iterator_next(&mask, &it);\n \t     i++) {\n \t\tif (i < tips->word_alloc)\n@@ -773,7 +778,7 @@ static void filter_bitmap_blob_none(struct bitmap_index *bitmap_git,\n \t */\n \tfor (i = 0; i < eindex->count; i++) {\n \t\tuint32_t pos = i + bitmap_git->pack->num_objects;\n-\t\tif (eindex->objects[i]->type == OBJ_BLOB &&\n+\t\tif (eindex->objects[i]->type == type &&\n \t\t    bitmap_get(to_filter, pos) &&\n \t\t    !bitmap_get(tips, pos))\n \t\t\tbitmap_unset(to_filter, pos);\n@@ -782,6 +787,14 @@ static void filter_bitmap_blob_none(struct bitmap_index *bitmap_git,\n \tbitmap_free(tips);\n }\n \n+static void filter_bitmap_blob_none(struct bitmap_index *bitmap_git,\n+\t\t\t\t    struct object_list *tip_objects,\n+\t\t\t\t    struct bitmap *to_filter)\n+{\n+\tfilter_bitmap_exclude_type(bitmap_git, tip_objects, to_filter,\n+\t\t\t\t   OBJ_BLOB);\n+}\n+\n static unsigned long get_size_by_pos(struct bitmap_index *bitmap_git,\n \t\t\t\t     uint32_t pos)\n {\n@@ -820,7 +833,7 @@ static void filter_bitmap_blob_limit(struct bitmap_index *bitmap_git,\n \teword_t mask;\n \tuint32_t i;\n \n-\ttips = find_tip_blobs(bitmap_git, tip_objects);\n+\ttips = find_tip_objects(bitmap_git, tip_objects, OBJ_BLOB);\n \n \tfor (i = 0, init_type_iterator(&it, bitmap_git, OBJ_BLOB);\n \t     i < to_filter->word_alloc && ewah_iterator_next(&mask, &it);\n-- \n2.26.2.112.g65467a058e\n\n"},{"id":"395959","messageId":"d42c35593c810fb3c87f67fdc5f042fc10bf2974.1587597151.git.me@ttaylorr.com","threadId":"53291","inReplyTo":"cover.1587597151.git.me@ttaylorr.com","subject":"[PATCH 3/4] pack-bitmap.c: support 'tree:0' filtering","fromName":"Taylor Blau","fromEmail":"me@ttaylorr.com","sentAt":"2020-04-22T23:13:32Z","receivedAt":"2020-04-22T23:13:38Z","isPatch":true,"sender":{"key":"me@ttaylorr.com","avatar":"https://avatars.githubusercontent.com/u/301000140?v=4"},"body":"In the previous patch, we made it easy to define other filters that\nexclude all objects of a certain type. Use that in order to implement\nbitmap-level filtering for the '--filter=tree:<n>' filter when 'n' is\nequal to 0.\n\nThe general case is not helped by bitmaps, since for values of 'n > 0',\nthe object filtering machinery requires a full-blown tree traversal in\norder to determine the depth of a given tree. Caching this is\nnon-obvious, too, since the same tree object can have a different depth\ndepending on the context (e.g., a tree was moved up in the directory\nhierarchy between two commits).\n\nBut, the 'n = 0' case can be helped, and this patch does so. Running\np5310.11 in this tree and on master with the kernel, we can see that\nthis case is helped substantially:\n\n  Test                                  master              this tree\n  --------------------------------------------------------------------------------\n  5310.11: rev-list count with tree:0   10.68(10.39+0.27)   0.06(0.04+0.01) -99.4%\n\nSigned-off-by: Taylor Blau <me@ttaylorr.com>\n---\n pack-bitmap.c                      | 25 ++++++++++++++++++++++++-\n t/perf/p5310-pack-bitmaps.sh       |  5 +++++\n t/t6113-rev-list-bitmap-filters.sh | 21 +++++++++++++++++++++\n 3 files changed, 50 insertions(+), 1 deletion(-)\n\ndiff --git a/pack-bitmap.c b/pack-bitmap.c\nindex 3693c9e62f..195ee8cad0 100644\n--- a/pack-bitmap.c\n+++ b/pack-bitmap.c\n@@ -749,7 +749,7 @@ static void filter_bitmap_exclude_type(struct bitmap_index *bitmap_git,\n \teword_t mask;\n \tuint32_t i;\n \n-\tif (type != OBJ_BLOB)\n+\tif (type != OBJ_BLOB && type != OBJ_TREE)\n \t\tBUG(\"filter_bitmap_exclude_type: unsupported type '%d'\", type);\n \n \t/*\n@@ -867,6 +867,20 @@ static void filter_bitmap_blob_limit(struct bitmap_index *bitmap_git,\n \tbitmap_free(tips);\n }\n \n+static void filter_bitmap_tree_depth(struct bitmap_index *bitmap_git,\n+\t\t\t\t     struct object_list *tip_objects,\n+\t\t\t\t     struct bitmap *to_filter,\n+\t\t\t\t     unsigned long limit)\n+{\n+\tif (limit)\n+\t\tBUG(\"filter_bitmap_tree_depth given non-zero limit\");\n+\n+\tfilter_bitmap_exclude_type(bitmap_git, tip_objects, to_filter,\n+\t\t\t\t   OBJ_TREE);\n+\tfilter_bitmap_exclude_type(bitmap_git, tip_objects, to_filter,\n+\t\t\t\t   OBJ_BLOB);\n+}\n+\n static int filter_bitmap(struct bitmap_index *bitmap_git,\n \t\t\t struct object_list *tip_objects,\n \t\t\t struct bitmap *to_filter,\n@@ -890,6 +904,15 @@ static int filter_bitmap(struct bitmap_index *bitmap_git,\n \t\treturn 0;\n \t}\n \n+\tif (filter->choice == LOFC_TREE_DEPTH &&\n+\t    filter->tree_exclude_depth == 0) {\n+\t\tif (bitmap_git)\n+\t\t\tfilter_bitmap_tree_depth(bitmap_git, tip_objects,\n+\t\t\t\t\t\t to_filter,\n+\t\t\t\t\t\t filter->tree_exclude_depth);\n+\t\treturn 0;\n+\t}\n+\n \t/* filter choice not handled */\n \treturn -1;\n }\ndiff --git a/t/perf/p5310-pack-bitmaps.sh b/t/perf/p5310-pack-bitmaps.sh\nindex 7743f4f4c9..b629a211f9 100755\n--- a/t/perf/p5310-pack-bitmaps.sh\n+++ b/t/perf/p5310-pack-bitmaps.sh\n@@ -57,6 +57,11 @@ test_perf 'rev-list count with blob:limit=1k' '\n \t\t--filter=blob:limit=1k >/dev/null\n '\n \n+test_perf 'rev-list count with tree:0' '\n+\tgit rev-list --use-bitmap-index --count --objects --all \\\n+\t\t--filter=tree:0 >/dev/null\n+'\n+\n test_perf 'simulated partial clone' '\n \tgit pack-objects --stdout --all --filter=blob:none </dev/null >/dev/null\n '\ndiff --git a/t/t6113-rev-list-bitmap-filters.sh b/t/t6113-rev-list-bitmap-filters.sh\nindex 145603f124..2b551e6fd0 100755\n--- a/t/t6113-rev-list-bitmap-filters.sh\n+++ b/t/t6113-rev-list-bitmap-filters.sh\n@@ -53,4 +53,25 @@ test_expect_success 'blob:limit filter with specified blob' '\n \ttest_bitmap_traversal expect actual\n '\n \n+test_expect_success 'tree:0 filter' '\n+\tgit rev-list --objects --filter=tree:0 HEAD >expect &&\n+\tgit rev-list --use-bitmap-index \\\n+\t\t     --objects --filter=tree:0 HEAD >actual &&\n+\ttest_bitmap_traversal expect actual\n+'\n+\n+test_expect_success 'tree:0 filter with specified blob, tree' '\n+\tgit rev-list --objects --filter=tree:0 HEAD HEAD:two.t >expect &&\n+\tgit rev-list --use-bitmap-index \\\n+\t\t     --objects --filter=tree:0 HEAD HEAD:two.t >actual &&\n+\ttest_bitmap_traversal expect actual\n+'\n+\n+test_expect_success 'tree:1 filter' '\n+\tgit rev-list --objects --filter=tree:1 HEAD >expect &&\n+\tgit rev-list --use-bitmap-index \\\n+\t\t     --objects --filter=tree:1 HEAD >actual &&\n+\ttest_cmp expect actual\n+'\n+\n test_done\n-- \n2.26.2.112.g65467a058e\n\n"},{"id":"395960","messageId":"65467a058e7dca6cf1e2db9cdab81513989b5db0.1587597151.git.me@ttaylorr.com","threadId":"53291","inReplyTo":"cover.1587597151.git.me@ttaylorr.com","subject":"[PATCH 4/4] pack-bitmap: pass object filter to fill-in traversal","fromName":"Taylor Blau","fromEmail":"me@ttaylorr.com","sentAt":"2020-04-22T23:13:35Z","receivedAt":"2020-04-22T23:13:42Z","isPatch":true,"sender":{"key":"me@ttaylorr.com","avatar":"https://avatars.githubusercontent.com/u/301000140?v=4"},"body":"From: Jeff King <peff@peff.net>\n\nSometimes a bitmap traversal still has to walk some commits manually,\nbecause those commits aren't included in the bitmap packfile (e.g., due\nto a push or commit since the last full repack). If we're given an\nobject filter, we don't pass it down to this traversal. It's not\nnecessary for correctness because the bitmap code has its own filters to\npost-process the bitmap result (which it must, to filter out the objects\nthat _are_ mentioned in the bitmapped packfile).\n\nAnd with blob filters, there was no performance reason to pass along\nthose filters, either. The fill-in traversal could omit them from the\nresult, but it wouldn't save us any time to do so, since we'd still have\nto walk each tree entry to see if it's a blob or not.\n\nBut now that we support tree filters, there's opportunity for savings. A\ntree:depth=0 filter means we can avoid accessing trees entirely, since\nwe know we won't them (or any of the subtrees or blobs they point to).\nThe new test in p5310 shows this off (the \"partial bitmap\" state is one\nwhere HEAD~100 and its ancestors are all in a bitmapped pack, but\nHEAD~100..HEAD are not). Here are the results (run against linux.git):\n\n  Test                                                  HEAD^               HEAD\n  -------------------------------------------------------------------------------------------------\n  [...]\n  5310.16: rev-list with tree filter (partial bitmap)   0.19(0.17+0.02)     0.03(0.02+0.01) -84.2%\n\nThe absolute number of savings isn't _huge_, but keep in mind that we\nonly omitted 100 first-parent links (in the version of linux.git here,\nthat's 894 actual commits). In a more pathological case, we might have a\nmuch larger proportion of non-bitmapped commits. I didn't bother\ncreating such a case in the perf script because the setup is expensive,\nand this is plenty to show the savings as a percentage.\n\nSigned-off-by: Jeff King <peff@peff.net>\nSigned-off-by: Taylor Blau <me@ttaylorr.com>\n---\n pack-bitmap.c                | 14 +++++++++-----\n t/perf/p5310-pack-bitmaps.sh |  5 +++++\n 2 files changed, 14 insertions(+), 5 deletions(-)\n\ndiff --git a/pack-bitmap.c b/pack-bitmap.c\nindex 195ee8cad0..4077e731e8 100644\n--- a/pack-bitmap.c\n+++ b/pack-bitmap.c\n@@ -506,7 +506,8 @@ static int should_include(struct commit *commit, void *_data)\n static struct bitmap *find_objects(struct bitmap_index *bitmap_git,\n \t\t\t\t   struct rev_info *revs,\n \t\t\t\t   struct object_list *roots,\n-\t\t\t\t   struct bitmap *seen)\n+\t\t\t\t   struct bitmap *seen,\n+\t\t\t\t   struct list_objects_filter_options *filter)\n {\n \tstruct bitmap *base = NULL;\n \tint needs_walk = 0;\n@@ -599,8 +600,9 @@ static struct bitmap *find_objects(struct bitmap_index *bitmap_git,\n \t\tshow_data.bitmap_git = bitmap_git;\n \t\tshow_data.base = base;\n \n-\t\ttraverse_commit_list(revs, show_commit, show_object,\n-\t\t\t\t     &show_data);\n+\t\ttraverse_commit_list_filtered(filter, revs,\n+\t\t\t\t\t      show_commit, show_object,\n+\t\t\t\t\t      &show_data, NULL);\n \t}\n \n \treturn base;\n@@ -999,7 +1001,8 @@ struct bitmap_index *prepare_bitmap_walk(struct rev_info *revs,\n \n \tif (haves) {\n \t\trevs->ignore_missing_links = 1;\n-\t\thaves_bitmap = find_objects(bitmap_git, revs, haves, NULL);\n+\t\thaves_bitmap = find_objects(bitmap_git, revs, haves, NULL,\n+\t\t\t\t\t    filter);\n \t\treset_revision_walk();\n \t\trevs->ignore_missing_links = 0;\n \n@@ -1007,7 +1010,8 @@ struct bitmap_index *prepare_bitmap_walk(struct rev_info *revs,\n \t\t\tBUG(\"failed to perform bitmap walk\");\n \t}\n \n-\twants_bitmap = find_objects(bitmap_git, revs, wants, haves_bitmap);\n+\twants_bitmap = find_objects(bitmap_git, revs, wants, haves_bitmap,\n+\t\t\t\t    filter);\n \n \tif (!wants_bitmap)\n \t\tBUG(\"failed to perform bitmap walk\");\ndiff --git a/t/perf/p5310-pack-bitmaps.sh b/t/perf/p5310-pack-bitmaps.sh\nindex b629a211f9..95379b1d4e 100755\n--- a/t/perf/p5310-pack-bitmaps.sh\n+++ b/t/perf/p5310-pack-bitmaps.sh\n@@ -95,4 +95,9 @@ test_perf 'pack to file (partial bitmap)' '\n \tgit pack-objects --use-bitmap-index --all pack2b </dev/null >/dev/null\n '\n \n+test_perf 'rev-list with tree filter (partial bitmap)' '\n+\tgit rev-list --use-bitmap-index --count --objects --all \\\n+\t\t--filter=tree:0 >/dev/null\n+'\n+\n test_done\n-- \n2.26.2.112.g65467a058e\n"},{"id":"396109","messageId":"20200424054227.GE1648190@coredump.intra.peff.net","threadId":"53291","inReplyTo":"65467a058e7dca6cf1e2db9cdab81513989b5db0.1587597151.git.me@ttaylorr.com","subject":"Re: [PATCH 4/4] pack-bitmap: pass object filter to fill-in traversal","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2020-04-24T05:42:27Z","receivedAt":"2020-04-24T05:42:29Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Apr 22, 2020 at 05:13:35PM -0600, Taylor Blau wrote:\n\n> From: Jeff King <peff@peff.net>\n> \n> Sometimes a bitmap traversal still has to walk some commits manually,\n> because those commits aren't included in the bitmap packfile (e.g., due\n> to a push or commit since the last full repack). If we're given an\n> object filter, we don't pass it down to this traversal. It's not\n> necessary for correctness because the bitmap code has its own filters to\n> post-process the bitmap result (which it must, to filter out the objects\n> that _are_ mentioned in the bitmapped packfile).\n> \n> And with blob filters, there was no performance reason to pass along\n> those filters, either. The fill-in traversal could omit them from the\n> result, but it wouldn't save us any time to do so, since we'd still have\n> to walk each tree entry to see if it's a blob or not.\n> \n> But now that we support tree filters, there's opportunity for savings. A\n> tree:depth=0 filter means we can avoid accessing trees entirely, since\n> we know we won't them (or any of the subtrees or blobs they point to).\n\ns/won't them/won't include them/ perhaps\n\n> diff --git a/t/perf/p5310-pack-bitmaps.sh b/t/perf/p5310-pack-bitmaps.sh\n> index b629a211f9..95379b1d4e 100755\n> --- a/t/perf/p5310-pack-bitmaps.sh\n> +++ b/t/perf/p5310-pack-bitmaps.sh\n> @@ -95,4 +95,9 @@ test_perf 'pack to file (partial bitmap)' '\n>  \tgit pack-objects --use-bitmap-index --all pack2b </dev/null >/dev/null\n>  '\n>  \n> +test_perf 'rev-list with tree filter (partial bitmap)' '\n> +\tgit rev-list --use-bitmap-index --count --objects --all \\\n> +\t\t--filter=tree:0 >/dev/null\n> +'\n\nThis covers perf testing of this partial-bitmap state, but we shoudl\nmake sure that we are covering correctness, too. I think so, because\nt6113 creates a similar state for all of its tests.\n\n-Peff\n"},{"id":"396110","messageId":"20200424054310.GF1648190@coredump.intra.peff.net","threadId":"53291","inReplyTo":"cover.1587597151.git.me@ttaylorr.com","subject":"Re: [PATCH 0/4] pack-bitmap: use bitmaps for traversals with '--filter=tree:0'","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2020-04-24T05:43:10Z","receivedAt":"2020-04-24T05:43:12Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Apr 22, 2020 at 05:13:19PM -0600, Taylor Blau wrote:\n\n> This series contains a handful of patches to make object traversals with\n> '--filter=tree:0' be bitmaps-compatible. They have been kicking around\n> in GitHub's fork for some time, and we use them on every\n> '--filter=tree:0' fetch.\n\nAs an author of half the patches, you can take my review with a grain of\nsalt, but these all look good to me (modulo one typo fix in a commit\nmessage).\n\n-Peff\n"},{"id":"396149","messageId":"20200424165435.GB58621@syl.local","threadId":"53291","inReplyTo":"20200424054227.GE1648190@coredump.intra.peff.net","subject":"Re: [PATCH 4/4] pack-bitmap: pass object filter to fill-in traversal","fromName":"Taylor Blau","fromEmail":"me@ttaylorr.com","sentAt":"2020-04-24T16:54:35Z","receivedAt":"2020-04-24T16:54:39Z","isPatch":true,"sender":{"key":"me@ttaylorr.com","avatar":"https://avatars.githubusercontent.com/u/301000140?v=4"},"body":"On Fri, Apr 24, 2020 at 01:42:27AM -0400, Jeff King wrote:\n> On Wed, Apr 22, 2020 at 05:13:35PM -0600, Taylor Blau wrote:\n>\n> > From: Jeff King <peff@peff.net>\n> >\n> > Sometimes a bitmap traversal still has to walk some commits manually,\n> > because those commits aren't included in the bitmap packfile (e.g., due\n> > to a push or commit since the last full repack). If we're given an\n> > object filter, we don't pass it down to this traversal. It's not\n> > necessary for correctness because the bitmap code has its own filters to\n> > post-process the bitmap result (which it must, to filter out the objects\n> > that _are_ mentioned in the bitmapped packfile).\n> >\n> > And with blob filters, there was no performance reason to pass along\n> > those filters, either. The fill-in traversal could omit them from the\n> > result, but it wouldn't save us any time to do so, since we'd still have\n> > to walk each tree entry to see if it's a blob or not.\n> >\n> > But now that we support tree filters, there's opportunity for savings. A\n> > tree:depth=0 filter means we can avoid accessing trees entirely, since\n> > we know we won't them (or any of the subtrees or blobs they point to).\n>\n> s/won't them/won't include them/ perhaps\n\nOops. Even though you wrote this patch, I clearly also should have\nproofread it more carefully before sending it to the list ;).\n\nJunio -- assuming that you are comfortable taking this series as-is (and\nplease let me know if you are not), would you mind fixing up this typo\nas you apply it?\n\n> > diff --git a/t/perf/p5310-pack-bitmaps.sh b/t/perf/p5310-pack-bitmaps.sh\n> > index b629a211f9..95379b1d4e 100755\n> > --- a/t/perf/p5310-pack-bitmaps.sh\n> > +++ b/t/perf/p5310-pack-bitmaps.sh\n> > @@ -95,4 +95,9 @@ test_perf 'pack to file (partial bitmap)' '\n> >  \tgit pack-objects --use-bitmap-index --all pack2b </dev/null >/dev/null\n> >  '\n> >\n> > +test_perf 'rev-list with tree filter (partial bitmap)' '\n> > +\tgit rev-list --use-bitmap-index --count --objects --all \\\n> > +\t\t--filter=tree:0 >/dev/null\n> > +'\n>\n> This covers perf testing of this partial-bitmap state, but we shoudl\n> make sure that we are covering correctness, too. I think so, because\n> t6113 creates a similar state for all of its tests.\n\nYeah, we are covered there. The last three tests in t6613 cover\n'--filter=tree:0', bot with and without specified objects (to make sure\nthat named objects don't get culled out by the filter), as well as the\n'--filter=tree:1', to make sure that we didn't break that.\n\n> -Peff\n\nThanks,\nTaylor\n"}]}