{"thread":{"id":"6685","subject":"[PATCH 1/2] Add cache_sha1_file() interface.","startedAt":"2007-02-05T05:51:23Z","lastAt":"2007-02-05T05:51:23Z","messageCount":1,"participants":["Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"33608","messageId":"7v8xfdp2xw.fsf@assigned-by-dhcp.cox.net","threadId":"6685","inReplyTo":null,"subject":"[PATCH 1/2] Add cache_sha1_file() interface.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-02-05T05:51:23Z","receivedAt":"2007-02-05T05:51:23Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"The new interface allows an application to temporarily hash a\nsmall number of objects and pretend that they are available in\nthe object store without actually writing them.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\n cache.h     |    1 +\n sha1_file.c |   57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 58 insertions(+), 0 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex 38a9bc0..8775088 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -257,6 +257,7 @@ extern void * unpack_sha1_file(void *map, unsigned long mapsize, char *type, uns\n extern void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size);\n extern int hash_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *sha1);\n extern int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *return_sha1);\n+extern int cache_sha1_file(void *, unsigned long, const char *, unsigned char *);\n \n extern int check_sha1_signature(const unsigned char *sha1, void *buf, unsigned long size, const char *type);\n \ndiff --git a/sha1_file.c b/sha1_file.c\nindex 1526a28..6a7a5b5 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -1505,10 +1505,67 @@ static void *read_packed_sha1(const unsigned char *sha1, char *type, unsigned lo\n \t\treturn unpack_entry(e.p, e.offset, type, size);\n }\n \n+/*\n+ * This is meant to hold a *small* number of objects that you would\n+ * want read_sha1_file() to be able to return, but yet you do not want\n+ * to write them into the object store (e.g. a browse-only\n+ * application).\n+ */\n+static struct cached_object {\n+\tunsigned char sha1[20];\n+\tconst char *type;\n+\tvoid *buf;\n+\tunsigned long size;\n+} *cached_objects;\n+static int cached_object_nr, cached_object_alloc;\n+\n+static struct cached_object *find_cached_object(const unsigned char *sha1)\n+{\n+\tint i;\n+\tstruct cached_object *co = cached_objects;\n+\n+\tfor (i = 0; i < cached_object_nr; i++, co++) {\n+\t\tif (!hashcmp(co->sha1, sha1))\n+\t\t\treturn co;\n+\t}\n+\treturn NULL;\n+}\n+\n+int cache_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *sha1)\n+{\n+\tstruct cached_object *co;\n+\n+\thash_sha1_file(buf, len, type, sha1);\n+\tif (has_sha1_file(sha1) || find_cached_object(sha1))\n+\t\treturn 0;\n+\tif (cached_object_alloc <= cached_object_nr) {\n+\t\tcached_object_alloc = alloc_nr(cached_object_alloc);\n+\t\tcached_objects = xrealloc(cached_objects,\n+\t\t\t\t\t  sizeof(*cached_objects) *\n+\t\t\t\t\t  cached_object_alloc);\n+\t}\n+\tco = &cached_objects[cached_object_nr++];\n+\tco->size = len;\n+\tco->type = strdup(type);\n+\thashcpy(co->sha1, sha1);\n+\treturn 0;\n+}\n+\n void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size)\n {\n \tunsigned long mapsize;\n \tvoid *map, *buf;\n+\tstruct cached_object *co;\n+\n+\tco = find_cached_object(sha1);\n+\tif (co) {\n+\t\tbuf = xmalloc(co->size + 1);\n+\t\tmemcpy(buf, co->buf, co->size);\n+\t\t((char*)buf)[co->size] = 0;\n+\t\tstrcpy(type, co->type);\n+\t\t*size = co->size;\n+\t\treturn buf;\n+\t}\n \n \tbuf = read_packed_sha1(sha1, type, size);\n \tif (buf)\n-- \n1.5.0.rc3.58.g79812\n"}]}