[PATCH 1/2] Add cache_sha1_file() interface.

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

 



The new interface allows an application to temporarily hash a
small number of objects and pretend that they are available in
the object store without actually writing them.

Signed-off-by: Junio C Hamano <junkio@xxxxxxx>
---
 cache.h     |    1 +
 sha1_file.c |   57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 58 insertions(+), 0 deletions(-)

diff --git a/cache.h b/cache.h
index 38a9bc0..8775088 100644
--- a/cache.h
+++ b/cache.h
@@ -257,6 +257,7 @@ extern void * unpack_sha1_file(void *map, unsigned long mapsize, char *type, uns
 extern void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size);
 extern int hash_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *sha1);
 extern int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *return_sha1);
+extern int cache_sha1_file(void *, unsigned long, const char *, unsigned char *);
 
 extern int check_sha1_signature(const unsigned char *sha1, void *buf, unsigned long size, const char *type);
 
diff --git a/sha1_file.c b/sha1_file.c
index 1526a28..6a7a5b5 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -1505,10 +1505,67 @@ static void *read_packed_sha1(const unsigned char *sha1, char *type, unsigned lo
 		return unpack_entry(e.p, e.offset, type, size);
 }
 
+/*
+ * This is meant to hold a *small* number of objects that you would
+ * want read_sha1_file() to be able to return, but yet you do not want
+ * to write them into the object store (e.g. a browse-only
+ * application).
+ */
+static struct cached_object {
+	unsigned char sha1[20];
+	const char *type;
+	void *buf;
+	unsigned long size;
+} *cached_objects;
+static int cached_object_nr, cached_object_alloc;
+
+static struct cached_object *find_cached_object(const unsigned char *sha1)
+{
+	int i;
+	struct cached_object *co = cached_objects;
+
+	for (i = 0; i < cached_object_nr; i++, co++) {
+		if (!hashcmp(co->sha1, sha1))
+			return co;
+	}
+	return NULL;
+}
+
+int cache_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *sha1)
+{
+	struct cached_object *co;
+
+	hash_sha1_file(buf, len, type, sha1);
+	if (has_sha1_file(sha1) || find_cached_object(sha1))
+		return 0;
+	if (cached_object_alloc <= cached_object_nr) {
+		cached_object_alloc = alloc_nr(cached_object_alloc);
+		cached_objects = xrealloc(cached_objects,
+					  sizeof(*cached_objects) *
+					  cached_object_alloc);
+	}
+	co = &cached_objects[cached_object_nr++];
+	co->size = len;
+	co->type = strdup(type);
+	hashcpy(co->sha1, sha1);
+	return 0;
+}
+
 void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size)
 {
 	unsigned long mapsize;
 	void *map, *buf;
+	struct cached_object *co;
+
+	co = find_cached_object(sha1);
+	if (co) {
+		buf = xmalloc(co->size + 1);
+		memcpy(buf, co->buf, co->size);
+		((char*)buf)[co->size] = 0;
+		strcpy(type, co->type);
+		*size = co->size;
+		return buf;
+	}
 
 	buf = read_packed_sha1(sha1, type, size);
 	if (buf)
-- 
1.5.0.rc3.58.g79812


-
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]