All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thomas Gummerer <t.gummerer@gmail.com>
To: git@vger.kernel.org
Cc: trast@student.ethz.ch, mhagger@alum.mit.edu, gitster@pobox.com,
	pclouds@gmail.com, robin.rosenberg@dewire.com,
	t.gummerer@gmail.com
Subject: [PATCH/RFC v3 08/13] Read cache-tree in index-v5
Date: Wed,  8 Aug 2012 13:17:56 +0200	[thread overview]
Message-ID: <1344424681-31469-9-git-send-email-t.gummerer@gmail.com> (raw)
In-Reply-To: <1344424681-31469-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    |   93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 cache-tree.h    |   10 ++++++
 read-cache-v5.c |    1 +
 3 files changed, 104 insertions(+)

diff --git a/cache-tree.c b/cache-tree.c
index 28ed657..440cd04 100644
--- a/cache-tree.c
+++ b/cache-tree.c
@@ -519,6 +519,99 @@ struct cache_tree *cache_tree_read(const char *buffer, unsigned long size)
 	return read_one(&buffer, &size);
 }
 
+static struct cache_tree *convert_one(struct directory_queue *queue, int dirnr)
+{
+	int i, subtree_nr;
+	struct cache_tree *it;
+	struct directory_queue *down;
+
+	it = cache_tree();
+	it->entry_count = queue[dirnr].de->de_nentries;
+	subtree_nr = queue[dirnr].de->de_nsubtrees;
+	if (0 <= it->entry_count)
+		hashcpy(it->sha1, queue[dirnr].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 = subtree_nr + 2;
+	it->down = xcalloc(it->subtree_alloc, sizeof(struct cache_tree_sub *));
+	down = queue[dirnr].down;
+	for (i = 0; i < subtree_nr; i++) {
+		struct cache_tree *sub;
+		struct cache_tree_sub *subtree;
+		char *buf, *name;
+
+		name = "";
+		buf = strtok(down[i].de->pathname, "/");
+		while (buf) {
+			name = buf;
+			buf = strtok(NULL, "/");
+		}
+		sub = convert_one(down, i);
+		if(!sub)
+			goto free_return;
+		subtree = cache_tree_sub(it, name);
+		subtree->cache_tree = sub;
+	}
+	if (subtree_nr != it->subtree_nr)
+		die("cache-tree: internal error");
+	return it;
+ free_return:
+	cache_tree_free(&it);
+	return NULL;
+}
+
+static int compare_cache_tree_elements(const void *a, const void *b)
+{
+	const struct directory_entry *de1, *de2;
+
+	de1 = ((const struct directory_queue *)a)->de;
+	de2 = ((const struct directory_queue *)b)->de;
+	return subtree_name_cmp(de1->pathname, de1->de_pathlen,
+				de2->pathname, de2->de_pathlen);
+}
+
+static struct directory_entry *sort_directories(struct directory_entry *de,
+						struct directory_queue *queue)
+{
+	int i, nsubtrees;
+
+	nsubtrees = de->de_nsubtrees;
+	for (i = 0; i < nsubtrees; i++) {
+		struct directory_entry *new_de;
+		de = de->next;
+		new_de = xmalloc(directory_entry_size(de->de_pathlen));
+		memcpy(new_de, de, directory_entry_size(de->de_pathlen));
+		queue[i].de = new_de;
+		if (de->de_nsubtrees) {
+			queue[i].down = xcalloc(de->de_nsubtrees,
+					sizeof(struct directory_queue));
+			de = sort_directories(de,
+					queue[i].down);
+		}
+	}
+	qsort(queue, nsubtrees, sizeof(struct directory_queue),
+			compare_cache_tree_elements);
+	return de;
+}
+
+struct cache_tree *cache_tree_convert_v5(struct directory_entry *de)
+{
+	struct directory_queue *queue;
+
+	if (!de->de_nentries)
+		return NULL;
+	queue = xcalloc(1, sizeof(struct directory_queue));
+	queue[0].de = de;
+	queue[0].down = xcalloc(de->de_nsubtrees, sizeof(struct directory_queue));
+
+	sort_directories(de, queue[0].down);
+	return convert_one(queue, 0);
+}
+
 static struct cache_tree *cache_tree_find(struct cache_tree *it, const char *path)
 {
 	if (!it)
diff --git a/cache-tree.h b/cache-tree.h
index d8cb2e9..7f29d26 100644
--- a/cache-tree.h
+++ b/cache-tree.h
@@ -20,6 +20,11 @@ struct cache_tree {
 	struct cache_tree_sub **down;
 };
 
+struct directory_queue {
+	struct directory_queue *down;
+	struct directory_entry *de;
+};
+
 struct cache_tree *cache_tree(void);
 void cache_tree_free(struct cache_tree **);
 void cache_tree_invalidate_path(struct cache_tree *, const char *);
@@ -27,6 +32,11 @@ struct cache_tree_sub *cache_tree_sub(struct cache_tree *, const char *);
 
 void cache_tree_write(struct strbuf *, struct cache_tree *root);
 struct cache_tree *cache_tree_read(const char *buffer, unsigned long size);
+/*
+ * This function modifys the directory argument that is given to it.
+ * Don't use it if the directory entries are still needed after.
+ */
+struct cache_tree *cache_tree_convert_v5(struct directory_entry *de);
 
 int cache_tree_fully_valid(struct cache_tree *);
 int cache_tree_update(struct cache_tree *, struct cache_entry **, int, int);
diff --git a/read-cache-v5.c b/read-cache-v5.c
index b47398d..57d0fb5 100644
--- a/read-cache-v5.c
+++ b/read-cache-v5.c
@@ -580,6 +580,7 @@ static void read_index_v5(struct index_state *istate, void *mmap, int mmap_size,
 	while (de)
 		de = read_entries(istate, de, &entry_offset,
 				&mmap, mmap_size, &nr, &foffsetblock, fd);
+	istate->cache_tree = cache_tree_convert_v5(root_directory);
 }
 
 struct index_ops v5_ops = {
-- 
1.7.10.GIT

  parent reply	other threads:[~2012-08-08 11:26 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-08-08 11:17 [PATCH/RFC v3 0/13] Introduce index file format version 5 Thomas Gummerer
2012-08-08 11:17 ` [PATCH/RFC v3 01/13] Move index v2 specific functions to their own file Thomas Gummerer
2012-08-08 12:04   ` Nguyen Thai Ngoc Duy
2012-08-08 19:21     ` Thomas Gummerer
2012-08-09 22:02   ` Junio C Hamano
2012-08-09 22:54     ` Thomas Gummerer
2012-08-10  0:13     ` Junio C Hamano
2012-08-10  2:23       ` Nguyen Thai Ngoc Duy
2012-08-10 14:24     ` Thomas Rast
2012-08-10 14:58       ` Junio C Hamano
2012-08-10 15:40         ` Thomas Gummerer
2012-08-08 11:17 ` [PATCH/RFC v3 02/13] t2104: Don't fail for index versions other than [23] Thomas Gummerer
2012-08-08 11:17 ` [PATCH/RFC v3 03/13] t3700: Avoid interfering with the racy code Thomas Gummerer
2012-08-08 11:17 ` [PATCH/RFC v3 04/13] Add documentation of the index-v5 file format Thomas Gummerer
2012-08-09 22:41   ` Junio C Hamano
2012-08-09 23:10     ` Thomas Gummerer
2012-08-09 23:13     ` Junio C Hamano
2012-08-08 11:17 ` [PATCH/RFC v3 05/13] Make in-memory format aware of stat_crc Thomas Gummerer
2012-08-08 11:17 ` [PATCH/RFC v3 06/13] Read index-v5 Thomas Gummerer
2012-08-08 12:05   ` Nguyen Thai Ngoc Duy
2012-08-08 12:18     ` Johannes Sixt
2012-08-08 17:05     ` Junio C Hamano
2012-08-08 19:29     ` Thomas Gummerer
2012-08-08 11:17 ` [PATCH/RFC v3 07/13] Read resolve-undo data Thomas Gummerer
2012-08-09 22:51   ` Junio C Hamano
2012-08-09 23:23     ` Thomas Gummerer
2012-08-10  0:02       ` Junio C Hamano
2012-08-10  9:27         ` Thomas Gummerer
2012-08-08 11:17 ` Thomas Gummerer [this message]
2012-08-08 11:17 ` [PATCH/RFC v3 09/13] Write index-v5 Thomas Gummerer
2012-08-08 11:17 ` [PATCH/RFC v3 10/13] Write index-v5 cache-tree data Thomas Gummerer
2012-08-08 11:17 ` [PATCH/RFC v3 11/13] Write resolve-undo data for index-v5 Thomas Gummerer
2012-08-08 11:18 ` [PATCH/RFC v3 12/13] update-index.c: always rewrite the index when index-version is given Thomas Gummerer
2012-08-08 11:18 ` [PATCH/RFC v3 13/13] p0002-index.sh: add perf test for the index formats Thomas Gummerer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1344424681-31469-9-git-send-email-t.gummerer@gmail.com \
    --to=t.gummerer@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=mhagger@alum.mit.edu \
    --cc=pclouds@gmail.com \
    --cc=robin.rosenberg@dewire.com \
    --cc=trast@student.ethz.ch \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.