* [PATCH 12/13] rewrite write_pack_file() to write multiple packs
@ 2007-04-05 22:41 Dana How
0 siblings, 0 replies; only message in thread
From: Dana How @ 2007-04-05 22:41 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, danahow
[-- Attachment #1: Type: text/plain, Size: 337 bytes --]
write_pack_file() now also sets up and sorts written_list
for each pack; modify write_one() to update this and
write_index_file() to use it.
---
builtin-pack-objects.c | 147 ++++++++++++++++++++++++++++++++++--------------
1 files changed, 105 insertions(+), 42 deletions(-)
--
Dana L. How danahow@gmail.com +1 650 804 5991 cell
[-- Attachment #2: 0012-rewrite-write_pack_file-to-write-multiple-packs.patch.txt --]
[-- Type: text/plain, Size: 6687 bytes --]
From cc6808e18fbeb2049e1d705eb7c7f6f9b83b3441 Mon Sep 17 00:00:00 2001
From: Dana How <how@deathvalley.cswitch.com>
Date: Thu, 5 Apr 2007 14:43:33 -0700
Subject: [PATCH 12/13] rewrite write_pack_file() to write multiple packs
write_pack_file() now also sets up and sorts written_list
for each pack; modify write_one() to update this and
write_index_file() to use it.
---
builtin-pack-objects.c | 147 ++++++++++++++++++++++++++++++++++--------------
1 files changed, 105 insertions(+), 42 deletions(-)
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index ac643dd..3229df8 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -534,14 +534,17 @@ static off_t write_one(struct sha1file *f,
* Ensure the packfile size never exceeds or matches offset_limit.
* The "20" is for the final SHA1.
*/
- if ((unsigned long)offset < (unsigned long)(offset_limit - 20))
+ if ((unsigned long)offset < (unsigned long)(offset_limit - 20)) {
+ *written_list++ = e;
return offset;
+ }
written = save_written, written_delta = save_written_delta;
reused = save_reused, reused_delta = save_reused_delta;
sha1undo(f, &posn, offset, e->offset);
e->offset = 0;
return 0;
}
+ *written_list++ = e;
return offset + write_object(f, e);
}
@@ -597,52 +600,112 @@ static void write_index_file(void);
static void write_pack_file(void)
{
- uint32_t i;
+ uint32_t i, j;
struct sha1file *f;
off_t offset;
struct pack_header hdr;
unsigned last_percent = 999;
- int do_progress = progress;
+ int do_progress = progress >> !base_name;
+ char oldname[PATH_MAX];
+ int pack_fd;
+ struct object_entry **list;
+ SHA_CTX ctx;
+ uint32_t nr_actual = nr_result - nr_skipped;
- if (!base_name) {
- f = sha1fd(1, "<stdout>");
- do_progress >>= 1;
- }
- else
- f = sha1create("%s-%s.%s", base_name,
- sha1_to_hex(object_list_sha1), "pack");
if (do_progress)
- fprintf(stderr, "Writing %u objects.\n", nr_result);
-
- hdr.hdr_signature = htonl(PACK_SIGNATURE);
- hdr.hdr_version = htonl(PACK_VERSION);
- hdr.hdr_entries = htonl(nr_result);
- sha1write(f, &hdr, sizeof(hdr));
- offset = sizeof(hdr);
- if (!nr_result)
- goto done;
- for (i = 0; i < nr_objects; i++) {
- offset = write_one(f, objects + i, offset);
- if (do_progress) {
- unsigned percent = written * 100 / nr_result;
- if (progress_update || percent != last_percent) {
- fprintf(stderr, "%4u%% (%u/%u) done\r",
- percent, written, nr_result);
- progress_update = 0;
- last_percent = percent;
+ fprintf(stderr, "Writing %u objects.\n", nr_actual);
+ written_list = list = xmalloc(nr_objects * sizeof(struct object_entry *));
+
+ for (i = 0; i < nr_objects;) {
+ if (!base_name) {
+ f = sha1fd(pack_fd = 1, "<stdout>");
+ }
+ else {
+ int len = snprintf(oldname, sizeof oldname, "%s-XXXXXX", base_name);
+ if (len >= PATH_MAX)
+ die("excessive pathname length for initial packfile name");
+ pack_fd = mkstemp(oldname);
+ if (pack_fd < 0)
+ die("can't create %s: %s", oldname, strerror(errno));
+ f = sha1fd(pack_fd, oldname);
+ }
+
+ hdr.hdr_signature = htonl(PACK_SIGNATURE);
+ hdr.hdr_version = htonl(PACK_VERSION);
+ hdr.hdr_entries = htonl(!base_name && offset_limit ? 0 : nr_actual);
+ sha1write(f, &hdr, sizeof(hdr));
+ offset = sizeof(hdr);
+ for (; i < nr_objects; i++) {
+ off_t offset_one = write_one(f, objects + i, offset);
+ if (!offset_one)
+ break;
+ offset = offset_one;
+ if (do_progress) {
+ unsigned percent = written * 100 / nr_actual;
+ if (progress_update || percent != last_percent) {
+ fprintf(stderr, "%4u%% (%u/%u) done\r",
+ percent, written, nr_actual);
+ progress_update = 0;
+ last_percent = percent;
+ }
}
}
+ nr_written = written_list - list;
+ written_list = list;
+
+ /*
+ * Write terminator record here if desired:
+ * type=OBJ_NONE, len=0; this is a zero byte.
+ */
+
+ /*
+ * Did we write the wrong # entries in the header?
+ * If so, rewrite it like in fast-import (gackk).
+ */
+ if ( !base_name || nr_written == nr_actual ) {
+ sha1close(f, pack_file_sha1, 1);
+ } else {
+ sha1close(f, pack_file_sha1, -1);
+ fixup_header_footer(pack_fd, pack_file_sha1, oldname, nr_written);
+ }
+
+ /*
+ * compute object_list_sha1 of sorted sha's we just wrote out;
+ * we also mark these objects as written
+ */
+ current_sort = sha1_sort;
+ qsort(list, nr_written, sizeof(struct object_entry *), sort_comparator);
+ SHA1_Init(&ctx);
+ for (j = 0; j < nr_written; j++) {
+ struct object_entry *entry = *list++;
+ entry->no_write = 1;
+ SHA1_Update(&ctx, entry->sha1, 20);
+ }
+ SHA1_Final(object_list_sha1, &ctx);
+ list = written_list;
+ /*
+ * now we can rename the pack correctly and write the index file
+ */
+ if (base_name) {
+ char newname[PATH_MAX];
+ int len = snprintf(newname, sizeof newname, "%s-%s.%s",
+ base_name, sha1_to_hex(object_list_sha1), "pack");
+ if (len >= PATH_MAX)
+ die("excessive pathname length for final packfile name");
+ if (rename(oldname, newname) < 0)
+ die("could not rename the pack file");
+ }
+ if (!pack_to_stdout) {
+ write_index_file();
+ puts(sha1_to_hex(object_list_sha1));
+ }
}
- if (do_progress)
+
+ free(written_list);
+ if (nr_actual && do_progress)
fputc('\n', stderr);
- done:
- if (written != nr_result)
- die("wrote %u objects while expecting %u", written, nr_result);
- sha1close(f, pack_file_sha1, 1);
- if (!pack_to_stdout) {
- write_index_file();
- puts(sha1_to_hex(object_list_sha1));
- }
+ if (written != nr_actual)
+ die("wrote %u objects while expecting %u", written, nr_actual);
}
static void write_index_file(void)
@@ -650,8 +713,8 @@ static void write_index_file(void)
uint32_t i;
struct sha1file *f = sha1create("%s-%s.%s", base_name,
sha1_to_hex(object_list_sha1), "idx");
- struct object_entry **list = sorted_by_sha;
- struct object_entry **last = list + nr_result;
+ struct object_entry **list = written_list;
+ struct object_entry **last = list + nr_written;
uint32_t array[256];
/*
@@ -667,7 +730,7 @@ static void write_index_file(void)
break;
next++;
}
- array[i] = htonl(next - sorted_by_sha);
+ array[i] = htonl(next - written_list);
list = next;
}
sha1write(f, array, 256 * 4);
@@ -675,8 +738,8 @@ static void write_index_file(void)
/*
* Write the actual SHA1 entries..
*/
- list = sorted_by_sha;
- for (i = 0; i < nr_result; i++) {
+ list = written_list;
+ for (i = 0; i < nr_written; i++) {
struct object_entry *entry = *list++;
uint32_t offset = htonl(entry->offset);
sha1write(f, &offset, 4);
--
1.5.1.rc2.18.g9c88-dirty
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2007-04-05 22:41 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-04-05 22:41 [PATCH 12/13] rewrite write_pack_file() to write multiple packs Dana How
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).