@matheusbsbs / matheus-bagliano / commits / 212818160d
Fork 0

fast-import: use sha1write() for pack data

This is in preparation for using write_idx_file(). Also, by using sha1write() we get some buffering to reduces the number of write syscalls, and the written data is SHA1 summed which allows for the extra data integrity validation check performed in fixup_pack_header_footer() (details on this in commit abeb40e5aa). Signed-off-by: Nicolas Pitre <nico@fluxnic.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nicolas Pitre committed Feb 17, 2010 at 14:05 UTC 212818160d588fae403dfc823250e95ffbac76e5
1 file changed +25 -10
fast-import.c
+25 -10
@@ -312,6 +312,7 @@ static struct atom_str **atom_table;
312
313 /* The .pack file being generated */
314 static unsigned int pack_id;
315 +static struct sha1file *pack_file;
316 static struct packed_git *pack_data;
317 static struct packed_git **all_packs;
318 static unsigned long pack_size;
@@ -838,11 +839,12 @@ static void start_packfile(void)
839 p = xcalloc(1, sizeof(*p) + strlen(tmpfile) + 2);
840 strcpy(p->pack_name, tmpfile);
841 p->pack_fd = pack_fd;
842 + pack_file = sha1fd(pack_fd, p->pack_name);
843
844 hdr.hdr_signature = htonl(PACK_SIGNATURE);
845 hdr.hdr_version = htonl(2);
846 hdr.hdr_entries = 0;
845 - write_or_die(p->pack_fd, &hdr, sizeof(hdr));
847 + sha1write(pack_file, &hdr, sizeof(hdr));
848
849 pack_data = p;
850 pack_size = sizeof(hdr);
@@ -956,15 +958,17 @@ static void end_packfile(void)
958
959 clear_delta_base_cache();
960 if (object_count) {
961 + unsigned char cur_pack_sha1[20];
962 char *idx_name;
963 int i;
964 struct branch *b;
965 struct tag *t;
966
967 close_pack_windows(pack_data);
968 + sha1close(pack_file, cur_pack_sha1, 0);
969 fixup_pack_header_footer(pack_data->pack_fd, pack_data->sha1,
970 pack_data->pack_name, object_count,
967 - NULL, 0);
971 + cur_pack_sha1, pack_size);
972 close(pack_data->pack_fd);
973 idx_name = keep_pack(create_index());
974
@@ -1138,22 +1142,22 @@ static int store_object(
1142 e->depth = last->depth + 1;
1143
1144 hdrlen = encode_header(OBJ_OFS_DELTA, deltalen, hdr);
1141 - write_or_die(pack_data->pack_fd, hdr, hdrlen);
1145 + sha1write(pack_file, hdr, hdrlen);
1146 pack_size += hdrlen;
1147
1148 hdr[pos] = ofs & 127;
1149 while (ofs >>= 7)
1150 hdr[--pos] = 128 | (--ofs & 127);
1147 - write_or_die(pack_data->pack_fd, hdr + pos, sizeof(hdr) - pos);
1151 + sha1write(pack_file, hdr + pos, sizeof(hdr) - pos);
1152 pack_size += sizeof(hdr) - pos;
1153 } else {
1154 e->depth = 0;
1155 hdrlen = encode_header(type, dat->len, hdr);
1152 - write_or_die(pack_data->pack_fd, hdr, hdrlen);
1156 + sha1write(pack_file, hdr, hdrlen);
1157 pack_size += hdrlen;
1158 }
1159
1156 - write_or_die(pack_data->pack_fd, out, s.total_out);
1160 + sha1write(pack_file, out, s.total_out);
1161 pack_size += s.total_out;
1162
1163 free(out);
@@ -1170,12 +1174,17 @@ static int store_object(
1174 return 0;
1175 }
1176
1173 -static void truncate_pack(off_t to)
1177 +static void truncate_pack(off_t to, git_SHA_CTX *ctx)
1178 {
1179 if (ftruncate(pack_data->pack_fd, to)
1180 || lseek(pack_data->pack_fd, to, SEEK_SET) != to)
1181 die_errno("cannot truncate pack to skip duplicate");
1182 pack_size = to;
1183 +
1184 + /* yes this is a layering violation */
1185 + pack_file->total = to;
1186 + pack_file->offset = 0;
1187 + pack_file->ctx = *ctx;
1188 }
1189
1190 static void stream_blob(uintmax_t len, unsigned char *sha1out, uintmax_t mark)
@@ -1188,6 +1197,7 @@ static void stream_blob(uintmax_t len, unsigned char *sha1out, uintmax_t mark)
1197 unsigned long hdrlen;
1198 off_t offset;
1199 git_SHA_CTX c;
1200 + git_SHA_CTX pack_file_ctx;
1201 z_stream s;
1202 int status = Z_OK;
1203
@@ -1198,6 +1208,10 @@ static void stream_blob(uintmax_t len, unsigned char *sha1out, uintmax_t mark)
1208
1209 offset = pack_size;
1210
1211 + /* preserve the pack_file SHA1 ctx in case we have to truncate later */
1212 + sha1flush(pack_file);
1213 + pack_file_ctx = pack_file->ctx;
1214 +
1215 hdrlen = snprintf((char *)out_buf, out_sz, "blob %" PRIuMAX, len) + 1;
1216 if (out_sz <= hdrlen)
1217 die("impossibly large object header");
@@ -1232,7 +1246,7 @@ static void stream_blob(uintmax_t len, unsigned char *sha1out, uintmax_t mark)
1246
1247 if (!s.avail_out || status == Z_STREAM_END) {
1248 size_t n = s.next_out - out_buf;
1235 - write_or_die(pack_data->pack_fd, out_buf, n);
1249 + sha1write(pack_file, out_buf, n);
1250 pack_size += n;
1251 s.next_out = out_buf;
1252 s.avail_out = out_sz;
@@ -1260,14 +1274,14 @@ static void stream_blob(uintmax_t len, unsigned char *sha1out, uintmax_t mark)
1274
1275 if (e->idx.offset) {
1276 duplicate_count_by_type[OBJ_BLOB]++;
1263 - truncate_pack(offset);
1277 + truncate_pack(offset, &pack_file_ctx);
1278
1279 } else if (find_sha1_pack(sha1, packed_git)) {
1280 e->type = OBJ_BLOB;
1281 e->pack_id = MAX_PACK_ID;
1282 e->idx.offset = 1; /* just not zero! */
1283 duplicate_count_by_type[OBJ_BLOB]++;
1270 - truncate_pack(offset);
1284 + truncate_pack(offset, &pack_file_ctx);
1285
1286 } else {
1287 e->depth = 0;
@@ -1316,6 +1330,7 @@ static void *gfi_unpack_entry(
1330 * the newly written data.
1331 */
1332 close_pack_windows(p);
1333 + sha1flush(pack_file);
1334
1335 /* We have to offer 20 bytes additional on the end of
1336 * the packfile as the core unpacker code assumes the