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

[PATCH v4 4/5] cache: Add index extension "CONV".

From
Henrik Grubbström (Grubba) <grubba@grubba.org>
Date
Jun 1, 2010, 14:41 UTC
Message-ID
<6b41ac9d06d0180b3a03b99449f8307530804eb9.1275309129.git.grubba@grubba.org>
In-Reply-To
<cover.1275309129.git.grubba@grubba.org>
The index can now store and retrieve the ce_conv_flags data.
Signed-off-by: Henrik Grubbström <grubba@grubba.org>
---
The on disk format has changed slightly due to the changes in the
previous patch, but the change should have minimal impact, since
it typically only would force a one-time reindex.
 read-cache.c |   65 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 59 insertions(+), 6 deletions(-)
diff --git a/read-cache.c b/read-cache.c
index eeda928..630e001 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -27,6 +27,7 @@ static struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int reall
 #define CACHE_EXT(s) ( (s[0]<<24)|(s[1]<<16)|(s[2]<<8)|(s[3]) )
 #define CACHE_EXT_TREE 0x54524545	/* "TREE" */
 #define CACHE_EXT_RESOLVE_UNDO 0x52455543 /* "REUC" */
+#define CACHE_EXT_CONV 0x434f4e56	/* "CONV" */
 
 struct index_state the_index;
 
@@ -1209,6 +1210,34 @@ static int verify_hdr(struct cache_header *hdr, unsigned long size)
 	return 0;
 }
 
+/* The on disk format is the default conversion flags followed
+ * by alternating cache entry numbers and corresponding flags.
+ */
+static int conv_read(struct cache_entry **cache, unsigned int entries,
+		     const unsigned int *data, unsigned long sz)
+{
+	unsigned int entry_no;
+	unsigned int default_conv_flags;
+	if (sz < sizeof(*data))
+		return 0;
+	default_conv_flags = ntohl(*data);
+	data++;
+	sz -= sizeof(*data);
+	if (default_conv_flags) {
+		for (entry_no = 0; entry_no < entries; entry_no++)
+			cache[entry_no]->ce_conv_flags = default_conv_flags;
+	}
+	while (sz >= 2*sizeof(*data)) {
+		entry_no = ntohl(*data);
+		data++;
+		if (entry_no >= entries) break;
+		cache[entry_no]->ce_conv_flags = ntohl(*data);
+		data++;
+		sz -= 2*sizeof(*data);
+	}
+	return 0;
+}
+
 static int read_index_extension(struct index_state *istate,
 				const char *ext, void *data, unsigned long sz)
 {
@@ -1219,6 +1248,9 @@ static int read_index_extension(struct index_state *istate,
 	case CACHE_EXT_RESOLVE_UNDO:
 		istate->resolve_undo = resolve_undo_read(data, sz);
 		break;
+	case CACHE_EXT_CONV:
+		return conv_read(istate->cache, istate->cache_nr, data, sz);
+		break;
 	default:
 		if (*ext < 'A' || 'Z' < *ext)
 			return error("index uses %.4s extension, which we do not understand",
@@ -1542,6 +1574,15 @@ static void ce_smudge_racily_clean_entry(struct cache_entry *ce)
 	}
 }
 
+static void conv_write(struct strbuf *sb, const struct cache_entry *ce,
+		       int entry_no)
+{
+	unsigned int entry[2];
+	entry[0] = htonl(entry_no);
+	entry[1] = htonl(ce->ce_conv_flags);
+	strbuf_add(sb, &entry, sizeof(entry));
+}
+
 static int ce_write_entry(git_SHA_CTX *c, int fd, struct cache_entry *ce)
 {
 	int size = ondisk_ce_size(ce);
@@ -1577,10 +1618,12 @@ int write_index(struct index_state *istate, int newfd)
 {
 	git_SHA_CTX c;
 	struct cache_header hdr;
-	int i, err, removed, extended;
+	int i, j, err, removed, extended;
 	struct cache_entry **cache = istate->cache;
 	int entries = istate->cache_nr;
 	struct stat st;
+	struct strbuf sb = STRBUF_INIT;
+	unsigned int default_conv_flags;
 
 	for (i = removed = extended = 0; i < entries; i++) {
 		if (cache[i]->ce_flags & CE_REMOVE)
@@ -1603,7 +1646,10 @@ int write_index(struct index_state *istate, int newfd)
 	if (ce_write(&c, newfd, &hdr, sizeof(hdr)) < 0)
 		return -1;
 
-	for (i = 0; i < entries; i++) {
+	default_conv_flags = git_conv_flags("");
+	strbuf_add_uint32(&sb, default_conv_flags);
+
+	for (i = j = 0; i < entries; i++) {
 		struct cache_entry *ce = cache[i];
 		if (ce->ce_flags & CE_REMOVE)
 			continue;
@@ -1611,12 +1657,21 @@ int write_index(struct index_state *istate, int newfd)
 			ce_smudge_racily_clean_entry(ce);
 		if (ce_write_entry(&c, newfd, ce) < 0)
 			return -1;
+		if (ce->ce_conv_flags != default_conv_flags)
+			conv_write(&sb, ce, j);
+		j++;
 	}
 
 	/* Write extension data here */
+	if (default_conv_flags || sb.len > sizeof(default_conv_flags)) {
+		err = write_index_ext_header(&c, newfd, CACHE_EXT_CONV, sb.len) < 0
+			|| ce_write(&c, newfd, sb.buf, sb.len) < 0;
+		strbuf_release(&sb);
+		if (err)
+			return -1;
+	} else
+		strbuf_release(&sb);
 	if (istate->cache_tree) {
-		struct strbuf sb = STRBUF_INIT;
-
 		cache_tree_write(&sb, istate->cache_tree);
 		err = write_index_ext_header(&c, newfd, CACHE_EXT_TREE, sb.len) < 0
 			|| ce_write(&c, newfd, sb.buf, sb.len) < 0;
@@ -1625,8 +1680,6 @@ int write_index(struct index_state *istate, int newfd)
 			return -1;
 	}
 	if (istate->resolve_undo) {
-		struct strbuf sb = STRBUF_INIT;
-
 		resolve_undo_write(&sb, istate->resolve_undo);
 		err = write_index_ext_header(&c, newfd, CACHE_EXT_RESOLVE_UNDO,
 					     sb.len) < 0
-- 
1.7.0.4.369.g81e89
Previous: Henrik Grubbström (Grubba)Next: Henrik Grubbström (Grubba)
Message 5 of 19 in “Patches to avoid reporting conversion changes.”
  1. 0/5 Patches to avoid reporting conversion changes.Henrik Grubbström (Grubba), Jun 1, 2010
  2. 1/5 sha1_file: Add index_blob().Henrik Grubbström (Grubba), Jun 1, 2010
  3. 2/5 strbuf: Add strbuf_add_uint32().Henrik Grubbström (Grubba), Jun 1, 2010
  4. 3/5 cache: Keep track of conversion mode changes.Henrik Grubbström (Grubba), Jun 1, 2010
  5. 4/5 cache: Add index extension "CONV".Henrik Grubbström (Grubba), Jun 1, 2010
  6. 5/5 t/t0021: Test that conversion changes are detected.Henrik Grubbström (Grubba), Jun 1, 2010
  7. Junio C HamanoJun 2, 2010
  8. Henrik GrubbströmJun 3, 2010
  9. Jonathan NiederJun 4, 2010
  10. Henrik GrubbströmJun 4, 2010
  11. Jonathan NiederJun 4, 2010
  12. Henrik GrubbströmJun 6, 2010
  13. Finn Arne GangstadJun 7, 2010
  14. Henrik GrubbströmJun 7, 2010
  15. Finn Arne GangstadJun 7, 2010
  16. Henrik GrubbströmJun 8, 2010
  17. Finn Arne GangstadJun 9, 2010
  18. Henrik GrubbströmJun 9, 2010
  19. Finn Arne GangstadJun 10, 2010

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.