git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Patrick Steinhardt <ps@pks.im>
To: git@vger.kernel.org
Subject: [PATCH 01/14] oidtree: modernize the code a bit
Date: Thu, 19 Mar 2026 07:52:59 +0100	[thread overview]
Message-ID: <20260319-b4-pks-odb-source-abbrev-v1-1-5ddebad292b0@pks.im> (raw)
In-Reply-To: <20260319-b4-pks-odb-source-abbrev-v1-0-5ddebad292b0@pks.im>

The "oidtree.c" subsystem is rather small and self-contained and tends
to just work. It thus doesn't typically receive a lot of attention,
which has as a consequence that it's coding style is somewhat dated
nowadays.

Modernize the style of this subsystem a bit:

  - Rename the `oidtree_iter()` function to `oidtree_each_cb()`.

  - Rename `struct oidtree_iter_data` to `struct oidtree_each_data` to
    match the renamed callback function type.

  - Rename parameters and variables to clarify their intent.

  - Add comments that explain what some of the functions do.

  - Adapt the return value of `oidtree_contains()` to be a boolean.

This prepares for some changes to the subsystem that'll happen in the
next commit.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
 oidtree.c                | 61 ++++++++++++++++++++++++------------------------
 oidtree.h                | 42 +++++++++++++++++++++++++++------
 t/unit-tests/u-oidtree.c | 14 +++++------
 3 files changed, 73 insertions(+), 44 deletions(-)

diff --git a/oidtree.c b/oidtree.c
index 324de94934..a4d10cd429 100644
--- a/oidtree.c
+++ b/oidtree.c
@@ -6,14 +6,6 @@
 #include "oidtree.h"
 #include "hash.h"
 
-struct oidtree_iter_data {
-	oidtree_iter fn;
-	void *arg;
-	size_t *last_nibble_at;
-	uint32_t algo;
-	uint8_t last_byte;
-};
-
 void oidtree_init(struct oidtree *ot)
 {
 	cb_init(&ot->tree);
@@ -54,8 +46,7 @@ void oidtree_insert(struct oidtree *ot, const struct object_id *oid)
 	cb_insert(&ot->tree, on, sizeof(*oid));
 }
 
-
-int oidtree_contains(struct oidtree *ot, const struct object_id *oid)
+bool oidtree_contains(struct oidtree *ot, const struct object_id *oid)
 {
 	struct object_id k;
 	size_t klen = sizeof(k);
@@ -69,41 +60,51 @@ int oidtree_contains(struct oidtree *ot, const struct object_id *oid)
 	klen += BUILD_ASSERT_OR_ZERO(offsetof(struct object_id, hash) <
 				offsetof(struct object_id, algo));
 
-	return cb_lookup(&ot->tree, (const uint8_t *)&k, klen) ? 1 : 0;
+	return !!cb_lookup(&ot->tree, (const uint8_t *)&k, klen);
 }
 
-static enum cb_next iter(struct cb_node *n, void *arg)
+struct oidtree_each_data {
+	oidtree_each_cb cb;
+	void *cb_data;
+	size_t *last_nibble_at;
+	uint32_t algo;
+	uint8_t last_byte;
+};
+
+static enum cb_next iter(struct cb_node *n, void *cb_data)
 {
-	struct oidtree_iter_data *x = arg;
+	struct oidtree_each_data *data = cb_data;
 	struct object_id k;
 
 	/* Copy to provide 4-byte alignment needed by struct object_id. */
 	memcpy(&k, n->k, sizeof(k));
 
-	if (x->algo != GIT_HASH_UNKNOWN && x->algo != k.algo)
+	if (data->algo != GIT_HASH_UNKNOWN && data->algo != k.algo)
 		return CB_CONTINUE;
 
-	if (x->last_nibble_at) {
-		if ((k.hash[*x->last_nibble_at] ^ x->last_byte) & 0xf0)
+	if (data->last_nibble_at) {
+		if ((k.hash[*data->last_nibble_at] ^ data->last_byte) & 0xf0)
 			return CB_CONTINUE;
 	}
 
-	return x->fn(&k, x->arg);
+	return data->cb(&k, data->cb_data);
 }
 
-void oidtree_each(struct oidtree *ot, const struct object_id *oid,
-			size_t oidhexsz, oidtree_iter fn, void *arg)
+void oidtree_each(struct oidtree *ot, const struct object_id *prefix,
+		  size_t prefix_hex_len, oidtree_each_cb cb, void *cb_data)
 {
-	size_t klen = oidhexsz / 2;
-	struct oidtree_iter_data x = { 0 };
-	assert(oidhexsz <= GIT_MAX_HEXSZ);
-
-	x.fn = fn;
-	x.arg = arg;
-	x.algo = oid->algo;
-	if (oidhexsz & 1) {
-		x.last_byte = oid->hash[klen];
-		x.last_nibble_at = &klen;
+	struct oidtree_each_data data = {
+		.cb = cb,
+		.cb_data = cb_data,
+		.algo = prefix->algo,
+	};
+	size_t klen = prefix_hex_len / 2;
+	assert(prefix_hex_len <= GIT_MAX_HEXSZ);
+
+	if (prefix_hex_len & 1) {
+		data.last_byte = prefix->hash[klen];
+		data.last_nibble_at = &klen;
 	}
-	cb_each(&ot->tree, (const uint8_t *)oid, klen, iter, &x);
+
+	cb_each(&ot->tree, prefix->hash, klen, iter, &data);
 }
diff --git a/oidtree.h b/oidtree.h
index 77898f510a..0651401017 100644
--- a/oidtree.h
+++ b/oidtree.h
@@ -5,18 +5,46 @@
 #include "hash.h"
 #include "mem-pool.h"
 
+/*
+ * OID trees are an efficient storage for object IDs that use a critbit tree
+ * internally. Common prefixes are duplicated and object IDs are stored in a
+ * way that allow easy iteration over the objects in lexicographic order. As a
+ * consequence, operations that want to enumerate all object IDs that match a
+ * given prefix can be answered efficiently.
+ *
+ * Note that it is not (yet) possible to store data other than the object IDs
+ * themselves in this tree.
+ */
 struct oidtree {
 	struct cb_tree tree;
 	struct mem_pool mem_pool;
 };
 
-void oidtree_init(struct oidtree *);
-void oidtree_clear(struct oidtree *);
-void oidtree_insert(struct oidtree *, const struct object_id *);
-int oidtree_contains(struct oidtree *, const struct object_id *);
+/* Initialize the oidtree so that it is ready for use. */
+void oidtree_init(struct oidtree *ot);
 
-typedef enum cb_next (*oidtree_iter)(const struct object_id *, void *data);
-void oidtree_each(struct oidtree *, const struct object_id *,
-			size_t oidhexsz, oidtree_iter, void *data);
+/*
+ * Release all memory associated with the oidtree and reinitialize it for
+ * subsequent use.
+ */
+void oidtree_clear(struct oidtree *ot);
+
+/* Insert the object ID into the tree. */
+void oidtree_insert(struct oidtree *ot, const struct object_id *oid);
+
+/* Check whether the tree contains the given object ID. */
+bool oidtree_contains(struct oidtree *ot, const struct object_id *oid);
+
+/* Callback function used for `oidtree_each()`. */
+typedef enum cb_next (*oidtree_each_cb)(const struct object_id *oid,
+					void *cb_data);
+
+/*
+ * Iterate through all object IDs in the tree whose prefix matches the given
+ * object ID prefix and invoke the callback function on each of them.
+ */
+void oidtree_each(struct oidtree *ot,
+		  const struct object_id *prefix, size_t prefix_hex_len,
+		  oidtree_each_cb cb, void *cb_data);
 
 #endif /* OIDTREE_H */
diff --git a/t/unit-tests/u-oidtree.c b/t/unit-tests/u-oidtree.c
index e6eede2740..def47c6795 100644
--- a/t/unit-tests/u-oidtree.c
+++ b/t/unit-tests/u-oidtree.c
@@ -24,7 +24,7 @@ static int fill_tree_loc(struct oidtree *ot, const char *hexes[], size_t n)
 	return 0;
 }
 
-static void check_contains(struct oidtree *ot, const char *hex, int expected)
+static void check_contains(struct oidtree *ot, const char *hex, bool expected)
 {
 	struct object_id oid;
 
@@ -88,12 +88,12 @@ void test_oidtree__cleanup(void)
 void test_oidtree__contains(void)
 {
 	FILL_TREE(&ot, "444", "1", "2", "3", "4", "5", "a", "b", "c", "d", "e");
-	check_contains(&ot, "44", 0);
-	check_contains(&ot, "441", 0);
-	check_contains(&ot, "440", 0);
-	check_contains(&ot, "444", 1);
-	check_contains(&ot, "4440", 1);
-	check_contains(&ot, "4444", 0);
+	check_contains(&ot, "44", false);
+	check_contains(&ot, "441", false);
+	check_contains(&ot, "440", false);
+	check_contains(&ot, "444", true);
+	check_contains(&ot, "4440", true);
+	check_contains(&ot, "4444", false);
 }
 
 void test_oidtree__each(void)

-- 
2.53.0.1055.ga2ffed1127.dirty



  reply	other threads:[~2026-03-19  6:53 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-19  6:52 [PATCH 00/14] odb: generic object name handling Patrick Steinhardt
2026-03-19  6:52 ` Patrick Steinhardt [this message]
2026-03-19 16:08   ` [PATCH 01/14] oidtree: modernize the code a bit Junio C Hamano
2026-03-20  6:40     ` Patrick Steinhardt
2026-03-20 22:30       ` brian m. carlson
2026-03-23  6:22         ` Patrick Steinhardt
2026-03-19  6:53 ` [PATCH 02/14] oidtree: extend iteration to allow for arbitrary return codes Patrick Steinhardt
2026-03-19 16:27   ` Junio C Hamano
2026-03-20  6:40     ` Patrick Steinhardt
2026-03-19 16:27   ` Karthik Nayak
2026-03-19  6:53 ` [PATCH 03/14] odb: introduce `struct odb_for_each_object_options` Patrick Steinhardt
2026-03-19 14:25   ` Junio C Hamano
2026-03-19 14:59     ` Patrick Steinhardt
2026-03-20  9:01   ` Karthik Nayak
2026-03-19  6:53 ` [PATCH 04/14] object-name: move logic to iterate through loose prefixed objects Patrick Steinhardt
2026-03-19  6:53 ` [PATCH 05/14] object-name: move logic to iterate through packed " Patrick Steinhardt
2026-03-19  6:53 ` [PATCH 06/14] object-name: extract function to parse object ID prefixes Patrick Steinhardt
2026-03-19  6:53 ` [PATCH 07/14] object-name: backend-generic `repo_collect_ambiguous()` Patrick Steinhardt
2026-03-19 14:26   ` Junio C Hamano
2026-03-19 14:59     ` Patrick Steinhardt
2026-03-20  9:23   ` Karthik Nayak
2026-03-19  6:53 ` [PATCH 08/14] object-name: backend-generic `get_short_oid()` Patrick Steinhardt
2026-03-19  6:53 ` [PATCH 09/14] object-name: merge `update_candidates()` and `match_prefix()` Patrick Steinhardt
2026-03-19  6:53 ` [PATCH 10/14] object-name: abbreviate loose object names without `disambiguate_state` Patrick Steinhardt
2026-03-19  6:53 ` [PATCH 11/14] object-name: simplify computing common prefixes Patrick Steinhardt
2026-03-20 10:01   ` Karthik Nayak
2026-03-20 10:30     ` Patrick Steinhardt
2026-03-19  6:53 ` [PATCH 12/14] object-name: move logic to compute loose abbreviation length Patrick Steinhardt
2026-03-19  6:53 ` [PATCH 13/14] object-file: move logic to compute packed " Patrick Steinhardt
2026-03-19  6:53 ` [PATCH 14/14] odb: introduce generic `odb_find_abbrev_len()` Patrick Steinhardt
2026-03-20  7:07 ` [PATCH v2 00/14] odb: generic object name handling Patrick Steinhardt
2026-03-20  7:07   ` [PATCH v2 01/14] oidtree: modernize the code a bit Patrick Steinhardt
2026-03-20  7:07   ` [PATCH v2 02/14] oidtree: extend iteration to allow for arbitrary return codes Patrick Steinhardt
2026-03-20  7:07   ` [PATCH v2 03/14] odb: introduce `struct odb_for_each_object_options` Patrick Steinhardt
2026-03-20  7:07   ` [PATCH v2 04/14] object-name: move logic to iterate through loose prefixed objects Patrick Steinhardt
2026-03-20  7:07   ` [PATCH v2 05/14] object-name: move logic to iterate through packed " Patrick Steinhardt
2026-03-30 17:55     ` Toon Claes
2026-03-20  7:07   ` [PATCH v2 06/14] object-name: extract function to parse object ID prefixes Patrick Steinhardt
2026-03-20  7:07   ` [PATCH v2 07/14] object-name: backend-generic `repo_collect_ambiguous()` Patrick Steinhardt
2026-03-20  7:07   ` [PATCH v2 08/14] object-name: backend-generic `get_short_oid()` Patrick Steinhardt
2026-03-30 15:12     ` Toon Claes
2026-03-20  7:07   ` [PATCH v2 09/14] object-name: merge `update_candidates()` and `match_prefix()` Patrick Steinhardt
2026-03-20  7:07   ` [PATCH v2 10/14] object-name: abbreviate loose object names without `disambiguate_state` Patrick Steinhardt
2026-03-20  7:07   ` [PATCH v2 11/14] object-name: simplify computing common prefixes Patrick Steinhardt
2026-03-20  7:07   ` [PATCH v2 12/14] object-name: move logic to compute loose abbreviation length Patrick Steinhardt
2026-03-20  7:07   ` [PATCH v2 13/14] object-file: move logic to compute packed " Patrick Steinhardt
2026-03-20  7:07   ` [PATCH v2 14/14] odb: introduce generic `odb_find_abbrev_len()` Patrick Steinhardt
2026-03-20 10:04   ` [PATCH v2 00/14] odb: generic object name handling Karthik Nayak
2026-03-20 10:30     ` Patrick Steinhardt
2026-03-30 20:35       ` Toon Claes
2026-03-30 21:01         ` Junio C Hamano
2026-03-31  6:04         ` Patrick Steinhardt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260319-b4-pks-odb-source-abbrev-v1-1-5ddebad292b0@pks.im \
    --to=ps@pks.im \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).