[FFT/PATCH 12/11] object.c: make object hash implementation more opaque

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



There are only a handful of callers that want to enumerate all the objects
known to the process. Unfortunately they at least know that the object
hash can be iterated over with an integer index.

Introduce an opaque "struct object_cursor" type to hide the implementation
detail, so that later we may be able to switch to an implementation that
is not a based on a flat and sparse array that is used as a hash table.

Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx>
---

 * This is not necessary for the purpose of the earlier "cuckoo" update,
   as that still is an implementation based on a single flat sparse array,
   but I am throwing it out as a food-for-thought.

   - The function "object_cursor_max()" returns obj_hash_size, but it only
     is used by fsck to give an overestimate of the number of objects to
     check. We could change it to return nr_obj to give a more precise
     number, but I kept the behaviour bug-for-bug compatible for now.

   - Later if we need to libify the in-core object store, we would wrap
     obj_hash, nr_obj and obj_hash_size into a single "struct obj_ctx"
     (the context of a series of git operations that access the object
     store), and have a pointer to it in the "struct object_cursor".
     get_object_cursor() API function may get a new variant that takes a
     pointer to "struct obj_ctx" to switch between contexts, etc.

   This patch is designed to apply before all the others, outside the main
   series. If this "more opaque" approach is going in a desirable
   direction, the "cuckoo" series should be rebased on top of this.

 builtin/fsck.c       |   17 ++++++++---------
 builtin/index-pack.c |   10 ++++++----
 builtin/name-rev.c   |   12 +++++-------
 object.c             |   34 ++++++++++++++++++++++++++++++----
 object.h             |    7 +++++--
 5 files changed, 54 insertions(+), 26 deletions(-)

diff --git a/builtin/fsck.c b/builtin/fsck.c
index 5ae0366..a71b36d 100644
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
@@ -266,22 +266,21 @@ static void check_object(struct object *obj)
 
 static void check_connectivity(void)
 {
-	int i, max;
+	struct object_cursor *objects;
+	struct object *obj;
 
 	/* Traverse the pending reachable objects */
 	traverse_reachable();
 
 	/* Look up all the requirements, warn about missing objects.. */
-	max = get_max_object_index();
+	objects = get_object_cursor();
 	if (verbose)
-		fprintf(stderr, "Checking connectivity (%d objects)\n", max);
-
-	for (i = 0; i < max; i++) {
-		struct object *obj = get_indexed_object(i);
+		fprintf(stderr, "Checking connectivity (%d objects)\n",
+			object_cursor_max(objects));
 
-		if (obj)
-			check_object(obj);
-	}
+	while ((obj = get_next_object(objects)) != NULL)
+		check_object(obj);
+	free_object_cursor(objects);
 }
 
 static int fsck_sha1(const unsigned char *sha1)
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index e40451f..ca172d5 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -104,11 +104,13 @@ static void check_object(struct object *obj)
 
 static void check_objects(void)
 {
-	unsigned i, max;
+	struct object_cursor *objects;
+	struct object *obj;
 
-	max = get_max_object_index();
-	for (i = 0; i < max; i++)
-		check_object(get_indexed_object(i));
+	objects = get_object_cursor();
+	while ((obj = get_next_object(objects)) != NULL)
+		check_object(obj);
+	free_object_cursor(objects);
 }
 
 
diff --git a/builtin/name-rev.c b/builtin/name-rev.c
index 31f5c1c..ec6b952 100644
--- a/builtin/name-rev.c
+++ b/builtin/name-rev.c
@@ -284,16 +284,14 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
 			name_rev_line(p, &data);
 		}
 	} else if (all) {
-		int i, max;
+		struct object_cursor *objects;
+		struct object *obj;
 
-		max = get_max_object_index();
-		for (i = 0; i < max; i++) {
-			struct object *obj = get_indexed_object(i);
-			if (!obj)
-				continue;
+		objects = get_object_cursor();
+		while ((obj = get_next_object(objects)) != NULL)
 			show_name(obj, NULL,
 				  always, allow_undefined, data.name_only);
-		}
+		free_object_cursor(objects);
 	} else {
 		int i;
 		for (i = 0; i < revs.nr; i++)
diff --git a/object.c b/object.c
index 31976b5..986d243 100644
--- a/object.c
+++ b/object.c
@@ -8,14 +8,40 @@
 static struct object **obj_hash;
 static int nr_objs, obj_hash_size;
 
-unsigned int get_max_object_index(void)
+struct object_cursor {
+	int cursor_at;
+};
+
+struct object_cursor *get_object_cursor(void)
 {
-	return obj_hash_size;
+	struct object_cursor *objects;
+	objects = xmalloc(sizeof(*objects));
+	objects->cursor_at = 0;
+	return objects;
+}
+
+int object_cursor_max(struct object_cursor *objects)
+{
+	return obj_hash_size; /* nr_objs is more precise, though */
+}
+
+struct object *get_next_object(struct object_cursor *objects)
+{
+	int i = objects->cursor_at;
+	while (i < obj_hash_size) {
+		struct object *obj = obj_hash[i++];
+		if (!obj)
+			continue;
+		objects->cursor_at = i;
+		return obj;
+	}
+	objects->cursor_at = i;
+	return NULL;
 }
 
-struct object *get_indexed_object(unsigned int idx)
+void free_object_cursor(struct object_cursor *objects)
 {
-	return obj_hash[idx];
+	free(objects);
 }
 
 static const char *object_type_strings[] = {
diff --git a/object.h b/object.h
index b6618d9..fdd14a1 100644
--- a/object.h
+++ b/object.h
@@ -35,8 +35,11 @@ struct object {
 extern const char *typename(unsigned int type);
 extern int type_from_string(const char *str);
 
-extern unsigned int get_max_object_index(void);
-extern struct object *get_indexed_object(unsigned int);
+struct object_cursor; /* opaque */
+extern struct object_cursor *get_object_cursor(void);
+extern int object_cursor_max(struct object_cursor *);
+extern struct object *get_next_object(struct object_cursor *);
+extern void free_object_cursor(struct object_cursor *);
 
 /*
  * This can be used to see if we have heard of the object before, but
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]