git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v4 5/8] sha1_file: refactor read_object

From
JTJonathan Tan <jonathantanmy@google.com>
Date
Jun 20, 2017, 01:03 UTC
Message-ID
<73d085b6fad9316c5a500341db2dd6451700656e.1497920092.git.jonathantanmy@google.com>
In-Reply-To
<cover.1497920092.git.jonathantanmy@google.com>

read_object() and sha1_object_info_extended() both implement mechanisms such as object replacement, retrying the packed store after failing to find the object in the packed store then the loose store, and being able to mark a packed object as bad and then retrying the whole process. Consolidating these mechanisms would be a great help to maintainability.

Therefore, consolidate them by extending sha1_object_info_extended() to support the functionality needed, and then modifying read_object() to use sha1_object_info_extended().

Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
---
 cache.h     |  1 +
 sha1_file.c | 84 ++++++++++++++++++++++++++++++-------------------------------
 2 files changed, 43 insertions(+), 42 deletions(-)
diff --git a/cache.h b/cache.h
index a3631b237..48aea923b 100644
--- a/cache.h
+++ b/cache.h
@@ -1827,6 +1827,7 @@ struct object_info {
 	off_t *disk_sizep;
 	unsigned char *delta_base_sha1;
 	struct strbuf *typename;
+	void **contentp;
 
 	/* Response */
 	enum {
diff --git a/sha1_file.c b/sha1_file.c
index a7be45efe..4d5033c48 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -2005,19 +2005,6 @@ int parse_sha1_header(const char *hdr, unsigned long *sizep)
 	return parse_sha1_header_extended(hdr, &oi, 0);
 }
 
-static void *unpack_sha1_file(void *map, unsigned long mapsize, enum object_type *type, unsigned long *size, const unsigned char *sha1)
-{
-	int ret;
-	git_zstream stream;
-	char hdr[8192];
-
-	ret = unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr));
-	if (ret < Z_OK || (*type = parse_sha1_header(hdr, size)) < 0)
-		return NULL;
-
-	return unpack_sha1_rest(&stream, hdr, *size, sha1);
-}
-
 unsigned long get_size_from_delta(struct packed_git *p,
 				  struct pack_window **w_curs,
 			          off_t curpos)
@@ -2326,8 +2313,10 @@ static void *cache_or_unpack_entry(struct packed_git *p, off_t base_offset,
 	if (!ent)
 		return unpack_entry(p, base_offset, type, base_size);
 
-	*type = ent->type;
-	*base_size = ent->size;
+	if (type)
+		*type = ent->type;
+	if (base_size)
+		*base_size = ent->size;
 	return xmemdupz(ent->data, ent->size);
 }
 
@@ -2388,9 +2377,16 @@ int packed_object_info(struct packed_git *p, off_t obj_offset,
 	 * We always get the representation type, but only convert it to
 	 * a "real" type later if the caller is interested.
 	 */
-	type = unpack_object_header(p, &w_curs, &curpos, &size);
+	if (oi->contentp) {
+		*oi->contentp = cache_or_unpack_entry(p, obj_offset, oi->sizep,
+						      &type);
+		if (!*oi->contentp)
+			type = OBJ_BAD;
+	} else {
+		type = unpack_object_header(p, &w_curs, &curpos, &size);
+	}
 
-	if (oi->sizep) {
+	if (!oi->contentp && oi->sizep) {
 		if (type == OBJ_OFS_DELTA || type == OBJ_REF_DELTA) {
 			off_t tmp_pos = curpos;
 			off_t base_offset = get_delta_base(p, &w_curs, &tmp_pos,
@@ -2679,8 +2675,10 @@ void *unpack_entry(struct packed_git *p, off_t obj_offset,
 		free(external_base);
 	}
 
-	*final_type = type;
-	*final_size = size;
+	if (final_type)
+		*final_type = type;
+	if (final_size)
+		*final_size = size;
 
 	unuse_pack(&w_curs);
 
@@ -2914,6 +2912,7 @@ static int sha1_loose_object_info(const unsigned char *sha1,
 	git_zstream stream;
 	char hdr[32];
 	struct strbuf hdrbuf = STRBUF_INIT;
+	unsigned long size_scratch;
 
 	if (oi->delta_base_sha1)
 		hashclr(oi->delta_base_sha1);
@@ -2926,7 +2925,7 @@ static int sha1_loose_object_info(const unsigned char *sha1,
 	 * return value implicitly indicates whether the
 	 * object even exists.
 	 */
-	if (!oi->typep && !oi->typename && !oi->sizep) {
+	if (!oi->typep && !oi->typename && !oi->sizep && !oi->contentp) {
 		const char *path;
 		struct stat st;
 		if (stat_sha1_file(sha1, &st, &path) < 0)
@@ -2939,6 +2938,10 @@ static int sha1_loose_object_info(const unsigned char *sha1,
 	map = map_sha1_file(sha1, &mapsize);
 	if (!map)
 		return -1;
+
+	if (!oi->sizep)
+		oi->sizep = &size_scratch;
+
 	if (oi->disk_sizep)
 		*oi->disk_sizep = mapsize;
 	if ((flags & OBJECT_INFO_ALLOW_UNKNOWN_TYPE)) {
@@ -2956,10 +2959,18 @@ static int sha1_loose_object_info(const unsigned char *sha1,
 				       sha1_to_hex(sha1));
 	} else if ((status = parse_sha1_header_extended(hdr, oi, flags)) < 0)
 		status = error("unable to parse %s header", sha1_to_hex(sha1));
-	git_inflate_end(&stream);
+
+	if (status >= 0 && oi->contentp)
+		*oi->contentp = unpack_sha1_rest(&stream, hdr,
+						 *oi->sizep, sha1);
+	else
+		git_inflate_end(&stream);
+
 	munmap(map, mapsize);
 	if (status && oi->typep)
 		*oi->typep = status;
+	if (oi->sizep == &size_scratch)
+		oi->sizep = NULL;
 	strbuf_release(&hdrbuf);
 	return (status < 0) ? status : 0;
 }
@@ -2985,6 +2996,8 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi,
 			hashclr(oi->delta_base_sha1);
 		if (oi->typename)
 			strbuf_addstr(oi->typename, typename(co->type));
+		if (oi->contentp)
+			*oi->contentp = xmemdupz(co->buf, co->size);
 		oi->whence = OI_CACHED;
 		return 0;
 	}
@@ -3077,28 +3090,15 @@ int pretend_sha1_file(void *buf, unsigned long len, enum object_type type,
 static void *read_object(const unsigned char *sha1, enum object_type *type,
 			 unsigned long *size)
 {
-	unsigned long mapsize;
-	void *map, *buf;
-	struct cached_object *co;
-
-	co = find_cached_object(sha1);
-	if (co) {
-		*type = co->type;
-		*size = co->size;
-		return xmemdupz(co->buf, co->size);
-	}
+	struct object_info oi = OBJECT_INFO_INIT;
+	void *content;
+	oi.typep = type;
+	oi.sizep = size;
+	oi.contentp = &content;
 
-	buf = read_packed_sha1(sha1, type, size);
-	if (buf)
-		return buf;
-	map = map_sha1_file(sha1, &mapsize);
-	if (map) {
-		buf = unpack_sha1_file(map, mapsize, type, size, sha1);
-		munmap(map, mapsize);
-		return buf;
-	}
-	reprepare_packed_git();
-	return read_packed_sha1(sha1, type, size);
+	if (sha1_object_info_extended(sha1, &oi, 0))
+		return NULL;
+	return content;
 }
 
 /*
-- 
2.13.1.611.g7e3b11ae1-goog
Previous: Jonathan TanNext: Junio C Hamano
Message 31 of 65 in “Improvements to sha1_file”
  1. 0/4 Improvements to sha1_fileJonathan Tan, Jun 9, 2017
  2. 1/4 sha1_file: teach packed_object_info about typenameJonathan Tan, Jun 9, 2017
  3. Junio C HamanoJun 12, 2017
  4. 2/4 sha1_file: extract type and size from object_infoJonathan Tan, Jun 9, 2017
  5. Jeff KingJun 10, 2017
  6. Jonathan TanJun 12, 2017
  7. Jeff KingJun 12, 2017
  8. 4/4 sha1_file, fsck: add missing blob supportJonathan Tan, Jun 9, 2017
  9. 3/4 sha1_file: consolidate storage-agnostic object fnsJonathan Tan, Jun 9, 2017
  10. 0/4 Improvements to sha1_fileJonathan Tan, Jun 13, 2017
  11. 1/4 sha1_file: teach packed_object_info about typenameJonathan Tan, Jun 13, 2017
  12. 2/4 sha1_file: move delta base cache code upJonathan Tan, Jun 13, 2017
  13. Junio C HamanoJun 15, 2017
  14. 3/4 sha1_file: consolidate storage-agnostic object fnsJonathan Tan, Jun 13, 2017
  15. Junio C HamanoJun 15, 2017
  16. Jonathan TanJun 15, 2017
  17. Jeff KingJun 17, 2017
  18. Junio C HamanoJun 19, 2017
  19. 4/4 sha1_file, fsck: add missing blob supportJonathan Tan, Jun 13, 2017
  20. Junio C HamanoJun 15, 2017
  21. Jonathan TanJun 15, 2017
  22. Junio C HamanoJun 15, 2017
  23. 0/8 Improvements to sha1_fileJonathan Tan, Jun 20, 2017
  24. 1/8 sha1_file: teach packed_object_info about typenameJonathan Tan, Jun 20, 2017
  25. 2/8 sha1_file: rename LOOKUP_UNKNOWN_OBJECTJonathan Tan, Jun 20, 2017
  26. Junio C HamanoJun 21, 2017
  27. Jonathan TanJun 21, 2017
  28. 3/8 sha1_file: rename LOOKUP_REPLACE_OBJECTJonathan Tan, Jun 20, 2017
  29. Junio C HamanoJun 21, 2017
  30. 4/8 sha1_file: move delta base cache code upJonathan Tan, Jun 20, 2017
  31. 5/8 sha1_file: refactor read_objectJonathan Tan, Jun 20, 2017
  32. Junio C HamanoJun 21, 2017
  33. 6/8 sha1_file: improve sha1_object_info_extendedJonathan Tan, Jun 20, 2017
  34. Jeff KingJun 24, 2017
  35. Jonathan TanJun 26, 2017
  36. Junio C HamanoJun 26, 2017
  37. Jonathan TanJun 26, 2017
  38. Junio C HamanoJun 26, 2017
  39. 8/8 sha1_file: refactor has_sha1_file_with_flagsJonathan Tan, Jun 20, 2017
  40. 7/8 sha1_file: do not access pack if unneededJonathan Tan, Jun 20, 2017
  41. Junio C HamanoJun 21, 2017
  42. Jeff KingJun 24, 2017
  43. Junio C HamanoJun 24, 2017
  44. Jeff KingJun 24, 2017
  45. Jonathan TanJun 26, 2017
  46. Junio C HamanoJun 21, 2017
  47. Jeff KingJun 24, 2017
  48. 0/8 Improvements to sha1_fileJonathan Tan, Jun 22, 2017
  49. 1/8 sha1_file: teach packed_object_info about typenameJonathan Tan, Jun 22, 2017
  50. 2/8 sha1_file: rename LOOKUP_UNKNOWN_OBJECTJonathan Tan, Jun 22, 2017
  51. 3/8 sha1_file: rename LOOKUP_REPLACE_OBJECTJonathan Tan, Jun 22, 2017
  52. 8/8 sha1_file: refactor has_sha1_file_with_flagsJonathan Tan, Jun 22, 2017
  53. Christian CouderJul 18, 2017
  54. Jonathan TanJul 18, 2017
  55. Johannes SchindelinJul 19, 2017
  56. sha1_file: use access(), not lstat(), if possibleJonathan Tan, Jul 19, 2017
  57. Junio C HamanoJul 20, 2017
  58. Johannes SchindelinJul 22, 2017
  59. Junio C HamanoJul 22, 2017
  60. Johannes SchindelinJul 25, 2017
  61. 6/8 sha1_file: improve sha1_object_info_extendedJonathan Tan, Jun 22, 2017
  62. 5/8 sha1_file: refactor read_objectJonathan Tan, Jun 22, 2017
  63. 4/8 sha1_file: move delta base cache code upJonathan Tan, Jun 22, 2017
  64. 7/8 sha1_file: do not access pack if unneededJonathan Tan, Jun 22, 2017
  65. Junio C HamanoJun 22, 2017

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.