git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Lukas Sandström" <lukass@etek.chalmers.se>
To: git@vger.kernel.org
Cc: "Alex Riesen" <raa.lkml@gmail.com>,
	junkio@cox.net, "Lukas Sandström" <lukass@etek.chalmers.se>
Subject: [PATCH] Make git-pack-redundant non-horribly slow on large sets of packs
Date: Thu, 17 Nov 2005 14:11:56 +0100	[thread overview]
Message-ID: <437C819C.4040507@etek.chalmers.se> (raw)
In-Reply-To: <20051115223340.GA3951@steel.home>

Change the smallest-set detection algortithm so that when
we have found a good set, we don't check any larger sets.

Signed-off-by: Lukas Sandström <lukass@etek.chalmers.se>

---
This change might make git-pack-redundant return non-optimal
pack-sets in some cases. OTOH, the case which Alex reported
completes in 0.6 sec instead of several minutes.

 pack-redundant.c |   62 +++++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 49 insertions(+), 13 deletions(-)

applies-to: 1e3fcf60526c196a46433e6947c9104ca236f230
498cc056d758b9e1cd21e984be281d55e24f1117
diff --git a/pack-redundant.c b/pack-redundant.c
index fcb36ff..51d7341 100644
--- a/pack-redundant.c
+++ b/pack-redundant.c
@@ -33,6 +33,7 @@ struct pack_list {
 struct pll {
 	struct pll *next;
 	struct pack_list *pl;
+	size_t pl_size;
 };
 
 inline void llist_free(struct llist *list)
@@ -249,18 +250,45 @@ void cmp_two_packs(struct pack_list *p1,
 	}
 }
 
+void pll_insert(struct pll **pll, struct pll **hint_table)
+{
+	struct pll *prev;
+	int i = (*pll)->pl_size - 1;
+
+	if (hint_table[i] == NULL) {
+		hint_table[i--] = *pll;
+		for (; i >= 0; --i) {
+			if (hint_table[i] != NULL)
+				break;
+		}
+		if (hint_table[i] == NULL) /* no elements in list */
+			die("Why did this happen?");
+	}
+
+	prev = hint_table[i];
+	while (prev->next && prev->next->pl_size < (*pll)->pl_size)
+		prev = prev->next;
+
+	(*pll)->next = prev->next;
+	prev->next = *pll;
+}
+
 /* all the permutations have to be free()d at the same time,
  * since they refer to each other
  */
 struct pll * get_all_permutations(struct pack_list *list)
 {
 	struct pll *subset, *pll, *new_pll = NULL; /*silence warning*/
-
+	static struct pll **hint = NULL;
+	if (hint == NULL)
+		hint = xcalloc(pack_list_size(list), sizeof(struct pll *));
+		
 	if (list == NULL)
 		return NULL;
 
 	if (list->next == NULL) {
 		new_pll = xmalloc(sizeof(struct pll));
+		hint[0] = new_pll;
 		new_pll->next = NULL;
 		new_pll->pl = list;
 		return new_pll;
@@ -268,24 +296,30 @@ struct pll * get_all_permutations(struct
 
 	pll = subset = get_all_permutations(list->next);
 	while (pll) {
+		if (pll->pl->pack == list->pack) {
+			pll = pll->next;
+			continue;
+		}
 		new_pll = xmalloc(sizeof(struct pll));
-		new_pll->next = pll->next;
-		pll->next = new_pll;
 
 		new_pll->pl = xmalloc(sizeof(struct pack_list));
 		memcpy(new_pll->pl, list, sizeof(struct pack_list));
 		new_pll->pl->next = pll->pl;
+		new_pll->pl_size = pll->pl_size + 1;
+		
+		pll_insert(&new_pll, hint);
+
+		pll = pll->next;
+	}
+	/* add ourself */
+	new_pll = xmalloc(sizeof(struct pll));
+	new_pll->pl = xmalloc(sizeof(struct pack_list));
+	memcpy(new_pll->pl, list, sizeof(struct pack_list));
+	new_pll->pl->next = NULL;
+	new_pll->pl_size = 1;
+	pll_insert(&new_pll, hint);
 
-		pll = new_pll->next;
-	}
-	/* add ourself to the end */
-	new_pll->next = xmalloc(sizeof(struct pll));
-	new_pll->next->pl = xmalloc(sizeof(struct pack_list));
-	new_pll->next->next = NULL;
-	memcpy(new_pll->next->pl, list, sizeof(struct pack_list));
-	new_pll->next->pl->next = NULL;
-
-	return subset;
+	return hint[0];
 }
 
 int is_superset(struct pack_list *pl, struct llist *list)
@@ -401,6 +435,8 @@ void minimize(struct pack_list **min)
 	/* find the permutations which contain all missing objects */
 	perm_all = perm = get_all_permutations(non_unique);
 	while (perm) {
+		if (perm_ok && perm->pl_size > perm_ok->pl_size)
+			break; /* ignore all larger permutations */
 		if (is_superset(perm->pl, missing)) {
 			new_perm = xmalloc(sizeof(struct pll));
 			new_perm->pl = perm->pl;
---
0.99.9.GIT

  parent reply	other threads:[~2005-11-17 13:11 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-11-16 23:09 git-pack-redundant returns the most containing pack Alex Riesen
2005-11-16 23:23 ` Lukas Sandström
2005-11-15 15:49   ` fix git-pack-redundant crashing sometimes Alex Riesen
2005-11-15 16:08     ` Timo Hirvonen
2005-11-15 16:11       ` Alex Riesen
2005-11-15 17:28         ` Linus Torvalds
2005-11-15 21:38       ` Lukas Sandström
2005-11-15 21:24     ` [PATCH] Fix llist_sorted_difference_inplace in git-pack-redundant Lukas Sandström
2005-11-15 21:34     ` fix git-pack-redundant crashing sometimes Alex Riesen
2005-11-15 21:41       ` Lukas Sandström
2005-11-15 22:33         ` Alex Riesen
2005-11-15 23:13           ` Lukas Sandström
2005-11-16  7:01             ` Alex Riesen
2005-11-16 21:11             ` Alex Riesen
2005-11-15 23:58           ` Linus Torvalds
2005-11-16 20:13             ` Junio C Hamano
2005-11-16 21:37             ` Lukas Sandström
2005-11-16 23:59               ` Lukas Sandström
2005-11-17 16:56                 ` Matthias Urlichs
2005-11-17  7:08               ` Fredrik Kuivinen
2005-11-17 13:11           ` Lukas Sandström [this message]
2005-11-17 20:39             ` [PATCH] Make git-pack-redundant non-horribly slow on large sets of packs Alex Riesen
2005-11-18 16:30             ` [PATCH] Fix bug introduced by the latest changes to git-pack-redundant Lukas Sandström
2005-11-18 21:53             ` [PATCH] Fix a bug in get_all_permutations Lukas Sandström
2005-11-17  7:45   ` git-pack-redundant returns the most containing pack Alex Riesen

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=437C819C.4040507@etek.chalmers.se \
    --to=lukass@etek.chalmers.se \
    --cc=git@vger.kernel.org \
    --cc=junkio@cox.net \
    --cc=raa.lkml@gmail.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).