From 93e72d8d8fbfbbf28abee82c3e769337d7b940ec Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Wed, 7 Mar 2007 17:09:21 -0500 Subject: Preallocate memory earlier in fast-import I'm about to teach fast-import how to reload the marks file created by a prior session. The general approach that I want to use is to immediately parse the marks file when the specific argument is found in argv, thereby allowing the caller to supply multiple marks files, as the mark space can be sparsely populated. To make that work out we need to allocate our object tables before we parse the command line options. Since none of these tables depend on the command line options, we can easily relocate them. Signed-off-by: Shawn O. Pearce --- fast-import.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'fast-import.c') diff --git a/fast-import.c b/fast-import.c index cc3347b23d..28f5e7c3b1 100644 --- a/fast-import.c +++ b/fast-import.c @@ -1988,6 +1988,12 @@ int main(int argc, const char **argv) int i, show_stats = 1; git_config(git_default_config); + alloc_objects(object_entry_alloc); + strbuf_init(&command_buf); + atom_table = xcalloc(atom_table_sz, sizeof(struct atom_str*)); + branch_table = xcalloc(branch_table_sz, sizeof(struct branch*)); + avail_tree_table = xcalloc(avail_tree_table_sz, sizeof(struct avail_tree_content*)); + marks = pool_calloc(1, sizeof(struct mark_set)); for (i = 1; i < argc; i++) { const char *a = argv[i]; @@ -2031,14 +2037,6 @@ int main(int argc, const char **argv) if (i != argc) usage(fast_import_usage); - alloc_objects(object_entry_alloc); - strbuf_init(&command_buf); - - atom_table = xcalloc(atom_table_sz, sizeof(struct atom_str*)); - branch_table = xcalloc(branch_table_sz, sizeof(struct branch*)); - avail_tree_table = xcalloc(avail_tree_table_sz, sizeof(struct avail_tree_content*)); - marks = pool_calloc(1, sizeof(struct mark_set)); - start_packfile(); for (;;) { read_next_command(); -- cgit v1.2.3 From 60b9004cdb106ce56589cbe587b6b5e7d6ad3cf9 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Wed, 7 Mar 2007 18:05:38 -0500 Subject: Use atomic updates to the fast-import mark file When we allow fast-import frontends to reload a mark file from a prior session we want to let them use the same file as they exported the marks to. This makes it very simple for the frontend to save state across incremental imports. But we don't want to lose the old marks table if anything goes wrong while writing our current marks table. So instead of truncating and overwriting the path specified to --export-marks we use the standard lockfile code to write the current marks out to a temporary file, then rename it over the old marks table. Signed-off-by: Shawn O. Pearce --- fast-import.c | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) (limited to 'fast-import.c') diff --git a/fast-import.c b/fast-import.c index 28f5e7c3b1..a09221242e 100644 --- a/fast-import.c +++ b/fast-import.c @@ -1375,16 +1375,33 @@ static void dump_marks_helper(FILE *f, static void dump_marks(void) { - if (mark_file) - { - FILE *f = fopen(mark_file, "w"); - if (f) { - dump_marks_helper(f, 0, marks); - fclose(f); - } else - failure |= error("Unable to write marks file %s: %s", - mark_file, strerror(errno)); + static struct lock_file mark_lock; + int mark_fd; + FILE *f; + + if (!mark_file) + return; + + mark_fd = hold_lock_file_for_update(&mark_lock, mark_file, 0); + if (mark_fd < 0) { + failure |= error("Unable to write marks file %s: %s", + mark_file, strerror(errno)); + return; } + + f = fdopen(mark_fd, "w"); + if (!f) { + rollback_lock_file(&mark_lock); + failure |= error("Unable to write marks file %s: %s", + mark_file, strerror(errno)); + return; + } + + dump_marks_helper(f, 0, marks); + fclose(f); + if (commit_lock_file(&mark_lock)) + failure |= error("Unable to write marks file %s: %s", + mark_file, strerror(errno)); } static void read_next_command(void) -- cgit v1.2.3 From e8438420bb7d368bec3647b90c557b9931582267 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Wed, 7 Mar 2007 18:07:26 -0500 Subject: Allow fast-import frontends to reload the marks table I'm giving fast-import a lesson on how to reload the marks table using the same format it outputs with --export-marks. This way a frontend can reload the marks table from a prior import, making incremental imports less painful. Signed-off-by: Shawn O. Pearce --- fast-import.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'fast-import.c') diff --git a/fast-import.c b/fast-import.c index a09221242e..fbed8e4e89 100644 --- a/fast-import.c +++ b/fast-import.c @@ -1997,6 +1997,40 @@ static void cmd_checkpoint(void) read_next_command(); } +static void import_marks(const char *input_file) +{ + char line[512]; + FILE *f = fopen(input_file, "r"); + if (!f) + die("cannot read %s: %s", input_file, strerror(errno)); + while (fgets(line, sizeof(line), f)) { + uintmax_t mark; + char *end; + unsigned char sha1[20]; + struct object_entry *e; + + end = strchr(line, '\n'); + if (line[0] != ':' || !end) + die("corrupt mark line: %s", line); + *end = 0; + mark = strtoumax(line + 1, &end, 10); + if (!mark || end == line + 1 + || *end != ' ' || get_sha1(end + 1, sha1)) + die("corrupt mark line: %s", line); + e = find_object(sha1); + if (!e) { + enum object_type type = sha1_object_info(sha1, NULL); + if (type < 0) + die("object not found: %s", sha1_to_hex(sha1)); + e = insert_object(sha1); + e->type = type; + e->pack_id = MAX_PACK_ID; + } + insert_mark(mark, e); + } + fclose(f); +} + static const char fast_import_usage[] = "git-fast-import [--date-format=f] [--max-pack-size=n] [--depth=n] [--active-branches=n] [--export-marks=marks.file]"; @@ -2034,6 +2068,8 @@ int main(int argc, const char **argv) max_depth = strtoul(a + 8, NULL, 0); else if (!prefixcmp(a, "--active-branches=")) max_active_branches = strtoul(a + 18, NULL, 0); + else if (!prefixcmp(a, "--import-marks=")) + import_marks(a + 15); else if (!prefixcmp(a, "--export-marks=")) mark_file = a + 15; else if (!prefixcmp(a, "--export-pack-edges=")) { -- cgit v1.2.3