aboutsummaryrefslogtreecommitdiffstats
path: root/pack-objects.h
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2025-02-12 10:08:51 -0800
committerJunio C Hamano <gitster@pobox.com>2025-02-12 10:08:51 -0800
commitaae91a86fb2a71ff89a71b63ccec3a947b26ca51 (patch)
tree3bfc421ac1b1f445d22bae71a3b3524ec993fb4c /pack-objects.h
parentThe ninth batch (diff)
parentpack-objects: prevent name hash version change (diff)
downloadgit-aae91a86fb2a71ff89a71b63ccec3a947b26ca51.tar.gz
git-aae91a86fb2a71ff89a71b63ccec3a947b26ca51.zip
Merge branch 'ds/name-hash-tweaks'
"git pack-objects" and its wrapper "git repack" learned an option to use an alternative path-hash function to improve delta-base selection to produce a packfile with deeper history than window size. * ds/name-hash-tweaks: pack-objects: prevent name hash version change test-tool: add helper for name-hash values p5313: add size comparison test pack-objects: add GIT_TEST_NAME_HASH_VERSION repack: add --name-hash-version option pack-objects: add --name-hash-version option pack-objects: create new name-hash function version
Diffstat (limited to 'pack-objects.h')
-rw-r--r--pack-objects.h28
1 files changed, 28 insertions, 0 deletions
diff --git a/pack-objects.h b/pack-objects.h
index 3f6f504203..d73e3843c9 100644
--- a/pack-objects.h
+++ b/pack-objects.h
@@ -208,6 +208,34 @@ static inline uint32_t pack_name_hash(const char *name)
return hash;
}
+static inline uint32_t pack_name_hash_v2(const unsigned char *name)
+{
+ uint32_t hash = 0, base = 0, c;
+
+ if (!name)
+ return 0;
+
+ while ((c = *name++)) {
+ if (isspace(c))
+ continue;
+ if (c == '/') {
+ base = (base >> 6) ^ hash;
+ hash = 0;
+ } else {
+ /*
+ * 'c' is only a single byte. Reverse it and move
+ * it to the top of the hash, moving the rest to
+ * less-significant bits.
+ */
+ c = (c & 0xF0) >> 4 | (c & 0x0F) << 4;
+ c = (c & 0xCC) >> 2 | (c & 0x33) << 2;
+ c = (c & 0xAA) >> 1 | (c & 0x55) << 1;
+ hash = (hash >> 2) + (c << 24);
+ }
+ }
+ return (base >> 6) ^ hash;
+}
+
static inline enum object_type oe_type(const struct object_entry *e)
{
return e->type_valid ? e->type_ : OBJ_BAD;