From: Jonathan Nieder <jrnieder@gmail.com>
To: David Barr <davidbarr@google.com>
Cc: Git List <git@vger.kernel.org>,
Thomas Rast <trast@student.ethz.ch>,
Dmitry Ivankov <divanorama@gmail.com>,
Sverre Rabbelier <srabbelier@gmail.com>
Subject: [PATCH 3/4] fast-import: allow branch_table to grow dynamically
Date: Wed, 11 Apr 2012 07:15:01 -0500 [thread overview]
Message-ID: <20120411121500.GE19568@burratino> (raw)
In-Reply-To: <20120411121259.GB19568@burratino>
Date: Mon, 30 May 2011 22:25:35 -0500
Use a struct hash_table to allow the table for branches to grow. The
main benefit is to make the code more self-consistent and avoid a
magic number for table size.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
fast-import.c | 104 ++++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 69 insertions(+), 35 deletions(-)
diff --git a/fast-import.c b/fast-import.c
index 67769573..ebb27006 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -334,8 +334,7 @@ static struct strbuf new_tree = STRBUF_INIT;
/* Branch data */
static unsigned long max_active_branches = 5;
static unsigned long cur_active_branches;
-static unsigned long branch_table_sz = 1039;
-static struct branch **branch_table;
+static struct hash_table branch_table;
static struct branch *active_branches;
/* Tag data */
@@ -364,8 +363,10 @@ static void parse_argv(void);
static void parse_cat_blob(void);
static void parse_ls(struct branch *b);
-static void write_branch_report(FILE *rpt, struct branch *b)
+static int write_branch_report(struct branch *b, void *cb)
{
+ FILE *rpt = cb;
+
fprintf(rpt, "%s:\n", b->name);
fprintf(rpt, " status :");
@@ -388,6 +389,36 @@ static void write_branch_report(FILE *rpt, struct branch *b)
fputc('\n', rpt);
fputc('\n', rpt);
+
+ return 0;
+}
+
+struct for_each_branch_data {
+ int (*fn)(struct branch *, void *);
+ void *data;
+};
+
+static int for_each_branch_helper(void *bucket, void *helper_data)
+{
+ struct for_each_branch_data *cb = helper_data;
+ struct branch *b;
+ int sum = 0;
+
+ for (b = bucket; b; b = b->table_next_branch) {
+ int val = cb->fn(b, cb->data);
+ if (val < 0)
+ return val;
+ sum += val;
+ }
+ return sum;
+}
+
+static int for_each_branch(int (*fn)(struct branch *, void *), void *data)
+{
+ struct for_each_branch_data cb;
+ cb.fn = fn;
+ cb.data = data;
+ return for_each_hash(&branch_table, for_each_branch_helper, &cb);
}
static void dump_marks_helper(FILE *, uintmax_t, struct mark_set *);
@@ -445,10 +476,7 @@ static void write_crash_report(const char *err)
fputc('\n', rpt);
fputs("Inactive Branches\n", rpt);
fputs("-----------------\n", rpt);
- for (lu = 0; lu < branch_table_sz; lu++) {
- for (b = branch_table[lu]; b; b = b->table_next_branch)
- write_branch_report(rpt, b);
- }
+ for_each_branch(write_branch_report, rpt);
if (first_tag) {
struct tag *tg;
@@ -714,10 +742,10 @@ static struct atom_str *to_atom(const char *s, unsigned short len)
static struct branch *lookup_branch(const char *name)
{
- unsigned int hc = hc_str(name, strlen(name)) % branch_table_sz;
+ unsigned int hc = hc_str(name, strlen(name));
struct branch *b;
- for (b = branch_table[hc]; b; b = b->table_next_branch)
+ for (b = lookup_hash(hc, &branch_table); b; b = b->table_next_branch)
if (!strcmp(name, b->name))
return b;
return NULL;
@@ -725,8 +753,9 @@ static struct branch *lookup_branch(const char *name)
static struct branch *new_branch(const char *name)
{
- unsigned int hc = hc_str(name, strlen(name)) % branch_table_sz;
+ unsigned int hc = hc_str(name, strlen(name));
struct branch *b = lookup_branch(name);
+ void **pos;
if (b)
die("Invalid attempt to create duplicate branch: %s", name);
@@ -740,13 +769,16 @@ static struct branch *new_branch(const char *name)
b = pool_calloc(1, sizeof(struct branch));
b->name = pool_strdup(name);
- b->table_next_branch = branch_table[hc];
b->branch_tree.versions[0].mode = S_IFDIR;
b->branch_tree.versions[1].mode = S_IFDIR;
b->num_notes = 0;
b->active = 0;
b->pack_id = MAX_PACK_ID;
- branch_table[hc] = b;
+ pos = insert_hash(hc, b, &branch_table);
+ if (pos) {
+ b->table_next_branch = *pos;
+ *pos = b;
+ }
branch_count++;
return b;
}
@@ -956,6 +988,15 @@ static void unkeep_all_packs(void)
}
}
+static int print_sha1_if_same_pack(struct branch *b, void *cb)
+{
+ const unsigned int *pack_id = cb;
+
+ if (b->pack_id == *pack_id)
+ fprintf(pack_edges, " %s", sha1_to_hex(b->sha1));
+ return 0;
+}
+
static void end_packfile(void)
{
struct packed_git *old_p = pack_data, *new_p;
@@ -964,8 +1005,6 @@ static void end_packfile(void)
if (object_count) {
unsigned char cur_pack_sha1[20];
char *idx_name;
- int i;
- struct branch *b;
struct tag *t;
close_pack_windows(pack_data);
@@ -986,12 +1025,7 @@ static void end_packfile(void)
/* Print the boundary */
if (pack_edges) {
fprintf(pack_edges, "%s:", new_p->pack_name);
- for (i = 0; i < branch_table_sz; i++) {
- for (b = branch_table[i]; b; b = b->table_next_branch) {
- if (b->pack_id == pack_id)
- fprintf(pack_edges, " %s", sha1_to_hex(b->sha1));
- }
- }
+ for_each_branch(print_sha1_if_same_pack, &pack_id);
for (t = first_tag; t; t = t->next_tag) {
if (t->pack_id == pack_id)
fprintf(pack_edges, " %s", sha1_to_hex(t->sha1));
@@ -1667,7 +1701,8 @@ static int tree_content_get(
return 0;
}
-static int update_branch(struct branch *b)
+/* 1 means failure; -1 means stop. */
+static int update_branch(struct branch *b, void *unused)
{
static const char *msg = "fast-import";
struct ref_lock *lock;
@@ -1678,8 +1713,10 @@ static int update_branch(struct branch *b)
if (read_ref(b->name, old_sha1))
hashclr(old_sha1);
lock = lock_any_ref_for_update(b->name, old_sha1, 0);
- if (!lock)
- return error("Unable to lock %s", b->name);
+ if (!lock) {
+ error("Unable to lock %s", b->name);
+ return 1;
+ }
if (!force_update && !is_null_sha1(old_sha1)) {
struct commit *old_cmit, *new_cmit;
@@ -1687,7 +1724,8 @@ static int update_branch(struct branch *b)
new_cmit = lookup_commit_reference_gently(b->sha1, 0);
if (!old_cmit || !new_cmit) {
unlock_ref(lock);
- return error("Branch %s is missing commits.", b->name);
+ error("Branch %s is missing commits.", b->name);
+ return 1;
}
if (!in_merge_bases(old_cmit, &new_cmit, 1)) {
@@ -1695,23 +1733,19 @@ static int update_branch(struct branch *b)
warning("Not updating %s"
" (new tip %s does not contain %s)",
b->name, sha1_to_hex(b->sha1), sha1_to_hex(old_sha1));
- return -1;
+ return 1;
}
}
- if (write_ref_sha1(lock, b->sha1, msg) < 0)
- return error("Unable to update %s", b->name);
+ if (write_ref_sha1(lock, b->sha1, msg) < 0) {
+ error("Unable to update %s", b->name);
+ return 1;
+ }
return 0;
}
static void dump_branches(void)
{
- unsigned int i;
- struct branch *b;
-
- for (i = 0; i < branch_table_sz; i++) {
- for (b = branch_table[i]; b; b = b->table_next_branch)
- failure |= update_branch(b);
- }
+ failure |= for_each_branch(update_branch, NULL);
}
static void dump_tags(void)
@@ -3275,7 +3309,7 @@ int main(int argc, const char **argv)
alloc_objects(object_entry_alloc);
strbuf_init(&command_buf, 0);
init_hash(&atom_table);
- branch_table = xcalloc(branch_table_sz, sizeof(struct branch*));
+ init_hash(&branch_table);
avail_tree_table = xcalloc(avail_tree_table_sz, sizeof(struct avail_tree_content*));
init_hash(&object_table);
marks = pool_calloc(1, sizeof(struct mark_set));
--
1.7.10
next prev parent reply other threads:[~2012-04-11 12:15 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-03-31 11:59 fast-import: use struct hash_table David Barr
2011-03-31 11:59 ` [PATCH 1/2] fast-import: use struct hash_table for atom strings David Barr
2011-04-02 2:42 ` Jonathan Nieder
2011-04-02 3:33 ` Jonathan Nieder
2011-03-31 11:59 ` [PATCH 2/2] fast-import: use struct hash_table for objects David Barr
2011-04-02 2:46 ` Jonathan Nieder
2011-04-02 2:48 ` fast-import: use struct hash_table Jonathan Nieder
2012-04-11 12:11 ` [PATCH/RFC v2 0/4] " Jonathan Nieder
2012-04-11 12:12 ` [PATCH/RFC v2 0/4 resend] " Jonathan Nieder
2012-04-11 12:13 ` [PATCH 1/4] fast-import: allow object_table to grow dynamically Jonathan Nieder
2012-04-11 12:14 ` [PATCH 2/4] fast-import: allow atom_table " Jonathan Nieder
2012-04-11 12:15 ` Jonathan Nieder [this message]
2012-04-11 12:15 ` [PATCH 4/4] fast-import: use DIV_ROUND_UP Jonathan Nieder
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
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120411121500.GE19568@burratino \
--to=jrnieder@gmail.com \
--cc=davidbarr@google.com \
--cc=divanorama@gmail.com \
--cc=git@vger.kernel.org \
--cc=srabbelier@gmail.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.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
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 read-only IMAP folder(s) and NNTP newsgroup(s).