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

[PATCH v4 14/24] read-cache: read cache-tree in index-v5

From
Thomas Gummerer <t.gummerer@gmail.com>
Date
Nov 27, 2013, 12:00 UTC
Message-ID
<1385553659-9928-15-git-send-email-t.gummerer@gmail.com>
In-Reply-To
<1385553659-9928-1-git-send-email-t.gummerer@gmail.com>

Since the cache-tree data is saved as part of the directory data, we already read it at the beginning of the index. The cache-tree is only converted from this directory data.

The cache-tree data is arranged in a tree, with the children sorted by pathlen at each node, while the ondisk format is sorted lexically. So we have to rebuild this format from the on-disk directory list.

Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
---
 cache-tree.c    |  2 +-
 cache-tree.h    |  1 +
 read-cache-v5.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 70 insertions(+), 1 deletion(-)
diff --git a/cache-tree.c b/cache-tree.c
index 0bbec43..1209732 100644
--- a/cache-tree.c
+++ b/cache-tree.c
@@ -31,7 +31,7 @@ void cache_tree_free(struct cache_tree **it_p)
 	*it_p = NULL;
 }
 
-static int subtree_name_cmp(const char *one, int onelen,
+int subtree_name_cmp(const char *one, int onelen,
 			    const char *two, int twolen)
 {
 	if (onelen < twolen)
diff --git a/cache-tree.h b/cache-tree.h
index f1923ad..9818926 100644
--- a/cache-tree.h
+++ b/cache-tree.h
@@ -25,6 +25,7 @@ struct cache_tree *cache_tree(void);
 void cache_tree_free(struct cache_tree **);
 void cache_tree_invalidate_path(struct cache_tree *, const char *);
 struct cache_tree_sub *cache_tree_sub(struct cache_tree *, const char *);
+int subtree_name_cmp(const char *, int, const char *, int);
 
 void cache_tree_write(struct strbuf *, struct cache_tree *root);
 struct cache_tree *cache_tree_read(const char *buffer, unsigned long size);
diff --git a/read-cache-v5.c b/read-cache-v5.c
index a9c687f..01f1c88 100644
--- a/read-cache-v5.c
+++ b/read-cache-v5.c
@@ -418,6 +418,73 @@ static int read_index_extension(struct index_state *istate,
 	return 0;
 }
 
+static int compare_cache_tree(const void *a, const void *b)
+{
+	const struct cache_tree_sub *it1, *it2;
+
+	it1 = *(const struct cache_tree_sub **) a;
+	it2 = *(const struct cache_tree_sub **) b;
+	return subtree_name_cmp(it1->name, it1->namelen,
+				it2->name, it2->namelen);
+}
+
+/*
+ * Convert the directory entries to cache-tree entries
+ * recursively.
+ */
+static struct cache_tree *convert_one(struct directory_entry *de)
+{
+	int i;
+	struct cache_tree *it;
+
+	it = cache_tree();
+	it->entry_count = de->de_nentries;
+	if (0 <= it->entry_count)
+		hashcpy(it->sha1, de->sha1);
+
+	/*
+	 * Just a heuristic -- we do not add directories that often but
+	 * we do not want to have to extend it immediately when we do,
+	 * hence +2.
+	 */
+	it->subtree_alloc = de->de_nsubtrees + 2;
+	it->down = xcalloc(it->subtree_alloc, sizeof(struct cache_tree_sub *));
+	for (i = 0; i < de->de_nsubtrees; i++) {
+		struct cache_tree *sub = convert_one(de->sub[i]);
+		struct cache_tree_sub *subtree;
+		/* -1 for removing the / at the end of the pathname */
+		int namelen = de->sub[i]->de_pathlen - de->de_pathlen - 1;
+
+		if (!sub)
+			goto free_return;
+
+		subtree = xmalloc(sizeof(*subtree) + namelen + 1);
+		subtree->cache_tree = sub;
+		subtree->namelen = namelen;
+		memcpy(subtree->name, de->sub[i]->pathname + de->de_pathlen, namelen);
+		subtree->name[namelen] = '\0';
+		it->down[i] = subtree;
+		it->subtree_nr++;
+	}
+	qsort(it->down, it->subtree_nr, sizeof(struct cache_tree_sub *),
+	      compare_cache_tree);
+	return it;
+free_return:
+	cache_tree_free(&it);
+	return NULL;
+}
+
+/*
+ * This function modifies the directory argument that is given to it.
+ * Don't use it if the directory entries are still needed after.
+ */
+static struct cache_tree *cache_tree_convert_v5(struct directory_entry *de)
+{
+	if (!de->de_nentries)
+		return NULL;
+	return convert_one(de);
+}
+
 /*
  * Read all file entries from the index.  This function is recursive to get
  * the ordering right. In the index file the entries are sorted def, abc/def,
@@ -558,6 +625,7 @@ static int read_index_v5(struct index_state *istate, void *mmap,
 				return -1;
 		}
 	}
+	istate->cache_tree = cache_tree_convert_v5(root_directory);
 	free_directory_tree(root_directory);
 	istate->cache_nr = nr;
 	return 0;
-- 
1.8.4.2
Previous: Thomas GummererNext: Thomas Gummerer
Message 25 of 41 in “Index-v5”
  1. 00/24 Index-v5Thomas Gummerer, Nov 27, 2013
  2. 01/24 t2104: Don't fail for index versions other than [23]Thomas Gummerer, Nov 27, 2013
  3. 02/24 read-cache: split index file version specific functionalityThomas Gummerer, Nov 27, 2013
  4. 03/24 read-cache: move index v2 specific functions to their own fileThomas Gummerer, Nov 27, 2013
  5. 04/24 read-cache: Re-read index if index file changedThomas Gummerer, Nov 27, 2013
  6. 05/24 add documentation for the index apiThomas Gummerer, Nov 27, 2013
  7. 06/24 read-cache: add index reading apiThomas Gummerer, Nov 27, 2013
  8. 07/24 make sure partially read index is not changedThomas Gummerer, Nov 27, 2013
  9. 08/24 grep.c: use index apiThomas Gummerer, Nov 27, 2013
  10. 09/24 ls-files.c: use index apiThomas Gummerer, Nov 27, 2013
  11. Duy NguyenNov 30, 2013
  12. Thomas GummererNov 30, 2013
  13. Antoine PelisseNov 30, 2013
  14. Thomas GummererNov 30, 2013
  15. 10/24 documentation: add documentation of the index-v5 file formatThomas Gummerer, Nov 27, 2013
  16. 11/24 read-cache: make in-memory format aware of stat_crcThomas Gummerer, Nov 27, 2013
  17. 12/24 read-cache: read index-v5Thomas Gummerer, Nov 27, 2013
  18. Duy NguyenNov 30, 2013
  19. Thomas GummererNov 30, 2013
  20. Antoine PelisseNov 30, 2013
  21. Thomas GummererNov 30, 2013
  22. Antoine PelisseNov 30, 2013
  23. Thomas GummererNov 30, 2013
  24. 13/24 read-cache: read resolve-undo dataThomas Gummerer, Nov 27, 2013
  25. 14/24 read-cache: read cache-tree in index-v5Thomas Gummerer, Nov 27, 2013
  26. 15/24 read-cache: write index-v5Thomas Gummerer, Nov 27, 2013
  27. 16/24 read-cache: write index-v5 cache-tree dataThomas Gummerer, Nov 27, 2013
  28. 17/24 read-cache: write resolve-undo data for index-v5Thomas Gummerer, Nov 27, 2013
  29. 18/24 update-index.c: rewrite index when index-version is givenThomas Gummerer, Nov 27, 2013
  30. 19/24 p0003-index.sh: add perf test for the index formatsThomas Gummerer, Nov 27, 2013
  31. 20/24 introduce GIT_INDEX_VERSION environment variableThomas Gummerer, Nov 27, 2013
  32. Eric SunshineNov 27, 2013
  33. Junio C HamanoNov 27, 2013
  34. Thomas GummererNov 28, 2013
  35. 21/24 test-lib: allow setting the index format versionThomas Gummerer, Nov 27, 2013
  36. 22/24 t1600: add index v5 specific testsThomas Gummerer, Nov 27, 2013
  37. 23/24 POC for partial writingThomas Gummerer, Nov 27, 2013
  38. Duy NguyenNov 30, 2013
  39. Thomas GummererNov 30, 2013
  40. 24/24 perf: add partial writing testThomas Gummerer, Nov 27, 2013
  41. Thomas GummererDec 9, 2013

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.