From: Jeff King <peff@peff.net>
To: Nguyen Thai Ngoc Duy <pclouds@gmail.com>
Cc: Junio C Hamano <gitster@pobox.com>, git@vger.kernel.org
Subject: [PATCH 4/8] decorate: use "map" for the underlying implementation
Date: Sat, 4 Aug 2012 13:11:15 -0400 [thread overview]
Message-ID: <20120804171115.GD19378@sigill.intra.peff.net> (raw)
In-Reply-To: <20120804170905.GA19267@sigill.intra.peff.net>
The decoration API maps objects to void pointers. This is a
subset of what the map API is capable of, so let's get rid
of the duplicate implementation.
We could just fix all callers of decorate to call the map
API directly. However, the map API is very generic since it
is meant to handle any type. In particular, it can't use
sentinel values like "NULL" to indicate "entry not found"
(since it doesn't know whether the type can represent such a
sentinel value), which makes the interface slightly more
complicated.
Instead, let's keep the existing decorate API as a wrapper
on top of map. No callers need to be updated at all.
Signed-off-by: Jeff King <peff@peff.net>
---
Documentation/technical/api-decorate.txt | 38 +++++++++++++-
Makefile | 3 ++
decorate.c | 85 +++-----------------------------
decorate.h | 10 ++--
map-object-void-params.h | 6 +++
map-object-void.c | 7 +++
map-object-void.h | 8 +++
7 files changed, 70 insertions(+), 87 deletions(-)
create mode 100644 map-object-void-params.h
create mode 100644 map-object-void.c
create mode 100644 map-object-void.h
diff --git a/Documentation/technical/api-decorate.txt b/Documentation/technical/api-decorate.txt
index 1d52a6c..3c1197a 100644
--- a/Documentation/technical/api-decorate.txt
+++ b/Documentation/technical/api-decorate.txt
@@ -1,6 +1,40 @@
decorate API
============
-Talk about <decorate.h>
+The decorate API is a system for efficiently mapping objects to values
+in memory. It is slightly slower than an actual member of an object
+struct (because it incurs a hash lookup), but it uses less memory when
+the mapping is not in use, or when the number of decorated objects is
+small compared to the total number of objects.
-(Linus)
+The decorate API is a special form of the `map` link:api-map.html[map
+API]. It has slightly simpler calling conventions, but only use objects
+as keys, and can only store void pointers as values.
+
+
+Data Structures
+---------------
+
+`struct decoration`::
+
+ This structure represents a single mapping of objects to values.
+ The `name` field is not used by the decorate API itself, but may
+ be used by calling code. The `map` field represents the actual
+ mapping of objects to void pointers (see the
+ link:api-map.html[map API] for details).
+
+
+Functions
+---------
+
+`add_decoration`::
+
+ Add a mapping from an object to a void pointer. If there was a
+ previous value for this object, the function returns this value;
+ otherwise, the function returns NULL.
+
+`lookup_decoration`::
+
+ Retrieve the stored value pointer for an object from the
+ mapping. The return value is the value pointer, or `NULL` if
+ there is no value for this object.
diff --git a/Makefile b/Makefile
index 1d29a95..7684a76 100644
--- a/Makefile
+++ b/Makefile
@@ -633,6 +633,8 @@ LIB_H += map-decl.h
LIB_H += map-done.h
LIB_H += map-impl.h
LIB_H += map-init.h
+LIB_H += map-object-void-params.h
+LIB_H += map-object-void.h
LIB_H += map-object.h
LIB_H += merge-file.h
LIB_H += merge-recursive.h
@@ -747,6 +749,7 @@ LIB_OBJS += ll-merge.o
LIB_OBJS += lockfile.o
LIB_OBJS += log-tree.o
LIB_OBJS += mailmap.o
+LIB_OBJS += map-object-void.o
LIB_OBJS += match-trees.o
LIB_OBJS += merge-file.o
LIB_OBJS += merge-recursive.o
diff --git a/decorate.c b/decorate.c
index 2f8a63e..31e9656 100644
--- a/decorate.c
+++ b/decorate.c
@@ -1,88 +1,17 @@
-/*
- * decorate.c - decorate a git object with some arbitrary
- * data.
- */
#include "cache.h"
-#include "object.h"
#include "decorate.h"
-static unsigned int hash_obj(const struct object *obj, unsigned int n)
-{
- unsigned int hash;
-
- memcpy(&hash, obj->sha1, sizeof(unsigned int));
- return hash % n;
-}
-
-static void *insert_decoration(struct decoration *n, const struct object *base, void *decoration)
-{
- int size = n->size;
- struct object_decoration *hash = n->hash;
- unsigned int j = hash_obj(base, size);
-
- while (hash[j].base) {
- if (hash[j].base == base) {
- void *old = hash[j].decoration;
- hash[j].decoration = decoration;
- return old;
- }
- if (++j >= size)
- j = 0;
- }
- hash[j].base = base;
- hash[j].decoration = decoration;
- n->nr++;
- return NULL;
-}
-
-static void grow_decoration(struct decoration *n)
-{
- int i;
- int old_size = n->size;
- struct object_decoration *old_hash = n->hash;
-
- n->size = (old_size + 1000) * 3 / 2;
- n->hash = xcalloc(n->size, sizeof(struct object_decoration));
- n->nr = 0;
-
- for (i = 0; i < old_size; i++) {
- const struct object *base = old_hash[i].base;
- void *decoration = old_hash[i].decoration;
-
- if (!base)
- continue;
- insert_decoration(n, base, decoration);
- }
- free(old_hash);
-}
-
-/* Add a decoration pointer, return any old one */
void *add_decoration(struct decoration *n, const struct object *obj,
- void *decoration)
+ void *decoration)
{
- int nr = n->nr + 1;
-
- if (nr > n->size * 2 / 3)
- grow_decoration(n);
- return insert_decoration(n, obj, decoration);
+ void *ret = NULL;
+ map_set_object_void(&n->map, obj, decoration, &ret);
+ return ret;
}
-/* Lookup a decoration pointer */
void *lookup_decoration(struct decoration *n, const struct object *obj)
{
- unsigned int j;
-
- /* nothing to lookup */
- if (!n->size)
- return NULL;
- j = hash_obj(obj, n->size);
- for (;;) {
- struct object_decoration *ref = n->hash + j;
- if (ref->base == obj)
- return ref->decoration;
- if (!ref->base)
- return NULL;
- if (++j == n->size)
- j = 0;
- }
+ void *ret = NULL;
+ map_get_object_void(&n->map, obj, &ret);
+ return ret;
}
diff --git a/decorate.h b/decorate.h
index e732804..c58acbc 100644
--- a/decorate.h
+++ b/decorate.h
@@ -1,15 +1,11 @@
#ifndef DECORATE_H
#define DECORATE_H
-struct object_decoration {
- const struct object *base;
- void *decoration;
-};
+#include "map-object-void.h"
struct decoration {
- const char *name;
- unsigned int size, nr;
- struct object_decoration *hash;
+ char *name;
+ struct map_object_void map;
};
extern void *add_decoration(struct decoration *n, const struct object *obj, void *decoration);
diff --git a/map-object-void-params.h b/map-object-void-params.h
new file mode 100644
index 0000000..471fbdc
--- /dev/null
+++ b/map-object-void-params.h
@@ -0,0 +1,6 @@
+#define NAME object_void
+#define KEY_TYPE const struct object *
+#define VALUE_TYPE void *
+#define HASH hash_obj
+#define KEY_EQUAL obj_equal
+#define SENTINEL_NULL
diff --git a/map-object-void.c b/map-object-void.c
new file mode 100644
index 0000000..4934642
--- /dev/null
+++ b/map-object-void.c
@@ -0,0 +1,7 @@
+#include "cache.h"
+#include "map-object-void.h"
+
+#include "map-object.h"
+#include "map-object-void-params.h"
+#include "map-impl.h"
+#include "map-done.h"
diff --git a/map-object-void.h b/map-object-void.h
new file mode 100644
index 0000000..b4bc64d
--- /dev/null
+++ b/map-object-void.h
@@ -0,0 +1,8 @@
+#ifndef MAP_OBJECT_VOID_H
+#define MAP_OBJECT_VOID_H
+
+#include "map-object-void-params.h"
+#include "map-decl.h"
+#include "map-done.h"
+
+#endif /* MAP_OBJECT_VOID_H */
--
1.7.12.rc1.7.g7a223a6
next prev parent reply other threads:[~2012-08-04 17:11 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-07-31 14:15 [WIP PATCH] Manual rename correction Nguyen Thai Ngoc Duy
2012-07-31 16:32 ` Junio C Hamano
2012-07-31 19:23 ` Jeff King
2012-07-31 20:20 ` Junio C Hamano
2012-08-01 0:42 ` Jeff King
2012-08-01 6:01 ` Junio C Hamano
2012-08-01 21:54 ` Jeff King
2012-08-01 22:10 ` Junio C Hamano
2012-08-02 22:37 ` Jeff King
2012-08-02 22:51 ` Junio C Hamano
2012-08-02 22:58 ` Jeff King
2012-08-02 5:33 ` Junio C Hamano
2012-08-01 1:10 ` Nguyen Thai Ngoc Duy
2012-08-01 2:01 ` Jeff King
2012-08-01 4:36 ` Nguyen Thai Ngoc Duy
2012-08-01 6:09 ` Junio C Hamano
2012-08-01 6:34 ` Nguyen Thai Ngoc Duy
2012-08-01 21:32 ` Jeff King
2012-08-01 21:27 ` Jeff King
2012-08-02 12:08 ` Nguyen Thai Ngoc Duy
2012-08-02 22:41 ` Jeff King
2012-08-04 17:09 ` [PATCH 0/8] caching rename results Jeff King
2012-08-04 17:10 ` [PATCH 1/8] implement generic key/value map Jeff King
2012-08-04 22:58 ` Junio C Hamano
2012-08-06 20:35 ` Jeff King
2012-08-04 17:10 ` [PATCH 2/8] map: add helper functions for objects as keys Jeff King
2012-08-04 17:11 ` [PATCH 3/8] fast-export: use object to uint32 map instead of "decorate" Jeff King
2012-08-04 17:11 ` Jeff King [this message]
2012-08-04 17:11 ` [PATCH 5/8] map: implement persistent maps Jeff King
2012-08-04 17:11 ` [PATCH 6/8] implement metadata cache subsystem Jeff King
2012-08-04 22:49 ` Junio C Hamano
2012-08-06 20:31 ` Jeff King
2012-08-06 20:38 ` Jeff King
2012-08-04 17:12 ` [PATCH 7/8] implement rename cache Jeff King
2012-08-04 17:14 ` [PATCH 8/8] diff: optionally use " Jeff King
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
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120804171115.GD19378@sigill.intra.peff.net \
--to=peff@peff.net \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=pclouds@gmail.com \
/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.
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 NNTP newsgroup(s).