v2 has better naming for 3/5, fix test for sha256 in 5/5 Thanks to René and Junio for feedback so far. Eric Wong (5): speed up alt_odb_usable() with many alternates avoid strlen via strbuf_addstr in link_alt_odb_entry make object_directory.loose_objects_subdir_seen a bitmap oidcpy_with_padding: constify `src' arg oidtree: a crit-bit tree for odb_loose_cache Makefile | 3 + alloc.c | 6 ++ alloc.h | 1 + cbtree.c | 167 ++++++++++++++++++++++++++++++++++++++++ cbtree.h | 56 ++++++++++++++ hash.h | 2 +- object-file.c | 69 ++++++++++------- object-name.c | 28 +++---- object-store.h | 24 +++++- object.c | 2 + oidtree.c | 94 ++++++++++++++++++++++ oidtree.h | 29 +++++++ t/helper/test-oidtree.c | 47 +++++++++++ t/helper/test-tool.c | 1 + t/helper/test-tool.h | 1 + t/t0069-oidtree.sh | 52 +++++++++++++ 16 files changed, 533 insertions(+), 49 deletions(-) create mode 100644 cbtree.c create mode 100644 cbtree.h create mode 100644 oidtree.c create mode 100644 oidtree.h create mode 100644 t/helper/test-oidtree.c create mode 100755 t/t0069-oidtree.sh Interdiff against v1: diff --git a/object-file.c b/object-file.c index d33b84c4a4..6c397fb4f1 100644 --- a/object-file.c +++ b/object-file.c @@ -2463,16 +2463,17 @@ struct oidtree *odb_loose_cache(struct object_directory *odb, { int subdir_nr = oid->hash[0]; struct strbuf buf = STRBUF_INIT; - size_t BM_SIZE = sizeof(odb->loose_objects_subdir_seen[0]) * CHAR_BIT; + size_t word_bits = bitsizeof(odb->loose_objects_subdir_seen[0]); + size_t word_index = subdir_nr / word_bits; + size_t mask = 1 << (subdir_nr % word_bits); uint32_t *bitmap; - uint32_t bit = 1 << (subdir_nr % BM_SIZE); if (subdir_nr < 0 || - subdir_nr >= ARRAY_SIZE(odb->loose_objects_subdir_seen) * BM_SIZE) + subdir_nr >= bitsizeof(odb->loose_objects_subdir_seen)) BUG("subdir_nr out of range"); - bitmap = &odb->loose_objects_subdir_seen[subdir_nr / BM_SIZE]; - if (*bitmap & bit) + bitmap = &odb->loose_objects_subdir_seen[word_index]; + if (*bitmap & mask) return &odb->loose_objects_cache; strbuf_addstr(&buf, odb->path); @@ -2480,7 +2481,7 @@ struct oidtree *odb_loose_cache(struct object_directory *odb, append_loose_object, NULL, NULL, &odb->loose_objects_cache); - *bitmap |= bit; + *bitmap |= mask; strbuf_release(&buf); return &odb->loose_objects_cache; } diff --git a/t/helper/test-oidtree.c b/t/helper/test-oidtree.c index 44bb2e7c29..e0da13eea3 100644 --- a/t/helper/test-oidtree.c +++ b/t/helper/test-oidtree.c @@ -13,6 +13,7 @@ int cmd__oidtree(int argc, const char **argv) struct oidtree ot = OIDTREE_INIT; struct strbuf line = STRBUF_INIT; int nongit_ok; + int algo = GIT_HASH_UNKNOWN; setup_git_directory_gently(&nongit_ok); @@ -21,20 +22,21 @@ int cmd__oidtree(int argc, const char **argv) struct object_id oid; if (skip_prefix(line.buf, "insert ", &arg)) { - if (get_oid_hex(arg, &oid)) - die("not a hexadecimal oid: %s", arg); + if (get_oid_hex_any(arg, &oid) == GIT_HASH_UNKNOWN) + die("insert not a hexadecimal oid: %s", arg); + algo = oid.algo; oidtree_insert(&ot, &oid); } else if (skip_prefix(line.buf, "contains ", &arg)) { if (get_oid_hex(arg, &oid)) - die("not a hexadecimal oid: %s", arg); + die("contains not a hexadecimal oid: %s", arg); printf("%d\n", oidtree_contains(&ot, &oid)); } else if (skip_prefix(line.buf, "each ", &arg)) { - char buf[GIT_SHA1_HEXSZ + 1] = { '0' }; + char buf[GIT_MAX_HEXSZ + 1] = { '0' }; memset(&oid, 0, sizeof(oid)); memcpy(buf, arg, strlen(arg)); - buf[GIT_SHA1_HEXSZ] = 0; + buf[hash_algos[algo].hexsz] = 0; get_oid_hex_any(buf, &oid); - oid.algo = GIT_HASH_SHA1; + oid.algo = algo; oidtree_each(&ot, &oid, strlen(arg), print_oid, NULL); } else if (!strcmp(line.buf, "destroy")) oidtree_destroy(&ot); diff --git a/t/t0069-oidtree.sh b/t/t0069-oidtree.sh index bb4229210c..0594f57c81 100755 --- a/t/t0069-oidtree.sh +++ b/t/t0069-oidtree.sh @@ -10,9 +10,9 @@ echoid () { do echo "$1" shift - done | awk -v prefix="$prefix" '{ + done | awk -v prefix="$prefix" -v ZERO_OID=$ZERO_OID '{ printf("%s%s", prefix, $0); - need = 40 - length($0); + need = length(ZERO_OID) - length($0); for (i = 0; i < need; i++) printf("0"); printf "\n";