11 struct object_entry *next;
13 unsigned char sha1[20];
16 struct object_entry_block
18 struct object_entry_block *next_block;
19 struct object_entry *next_free;
20 struct object_entry *end;
21 struct object_entry entries[FLEX_ARRAY]; /* more */
29 unsigned char sha1[20];
32 /* Stats and misc. counters. */
33 static int max_depth = 10;
34 static unsigned long alloc_count;
35 static unsigned long object_count;
36 static unsigned long duplicate_count;
40 static unsigned long pack_offset;
41 static unsigned char pack_sha1[20];
43 /* Table of objects we've written. */
44 struct object_entry_block *blocks;
45 struct object_entry *object_table[1 << 16];
48 struct last_object last_blob;
50 static void alloc_objects(int cnt)
52 struct object_entry_block *b;
54 b = xmalloc(sizeof(struct object_entry_block)
55 + cnt * sizeof(struct object_entry));
56 b->next_block = blocks;
57 b->next_free = b->entries;
58 b->end = b->entries + cnt;
63 static struct object_entry* new_object(unsigned char *sha1)
65 struct object_entry *e;
67 if (blocks->next_free == blocks->end)
70 e = blocks->next_free++;
71 memcpy(e->sha1, sha1, sizeof(e->sha1));
75 static struct object_entry* insert_object(unsigned char *sha1)
77 unsigned int h = sha1[0] << 8 | sha1[1];
78 struct object_entry *e = object_table[h];
79 struct object_entry *p = 0;
82 if (!memcmp(sha1, e->sha1, sizeof(e->sha1)))
98 static ssize_t yread(int fd, void *buffer, size_t length)
101 while (ret < length) {
102 ssize_t size = xread(fd, (char *) buffer + ret, length - ret);
114 static ssize_t ywrite(int fd, void *buffer, size_t length)
117 while (ret < length) {
118 ssize_t size = xwrite(fd, (char *) buffer + ret, length - ret);
130 static unsigned long encode_header(
131 enum object_type type,
138 if (type < OBJ_COMMIT || type > OBJ_DELTA)
139 die("bad type %d", type);
141 c = (type << 4) | (size & 15);
153 static int store_object(
154 enum object_type type,
156 unsigned long datlen,
157 struct last_object *last)
160 struct object_entry *e;
161 unsigned char hdr[96];
162 unsigned char sha1[20];
163 unsigned long hdrlen, deltalen;
167 hdrlen = sprintf((char*)hdr,"%s %lu",type_names[type],datlen) + 1;
169 SHA1_Update(&c, hdr, hdrlen);
170 SHA1_Update(&c, dat, datlen);
171 SHA1_Final(sha1, &c);
173 e = insert_object(sha1);
178 e->offset = pack_offset;
181 if (last->data && last->depth < max_depth)
182 delta = diff_delta(last->data, last->len,
188 memset(&s, 0, sizeof(s));
189 deflateInit(&s, zlib_compression_level);
194 s.avail_in = deltalen;
195 hdrlen = encode_header(OBJ_DELTA, deltalen, hdr);
196 if (ywrite(pack_fd, hdr, hdrlen) != hdrlen)
197 die("Can't write object header: %s", strerror(errno));
198 if (ywrite(pack_fd, last->sha1, sizeof(sha1)) != sizeof(sha1))
199 die("Can't write object base: %s", strerror(errno));
200 pack_offset += hdrlen + sizeof(sha1);
205 hdrlen = encode_header(type, datlen, hdr);
206 if (ywrite(pack_fd, hdr, hdrlen) != hdrlen)
207 die("Can't write object header: %s", strerror(errno));
208 pack_offset += hdrlen;
211 s.avail_out = deflateBound(&s, s.avail_in);
212 s.next_out = out = xmalloc(s.avail_out);
213 while (deflate(&s, Z_FINISH) == Z_OK)
217 if (ywrite(pack_fd, out, s.total_out) != s.total_out)
218 die("Failed writing compressed data %s", strerror(errno));
219 pack_offset += s.total_out;
228 memcpy(last->sha1, sha1, sizeof(sha1));
232 static void init_pack_header()
234 const char* magic = "PACK";
235 unsigned long version = 2;
236 unsigned long zero = 0;
238 version = htonl(version);
240 if (ywrite(pack_fd, (char*)magic, 4) != 4)
241 die("Can't write pack magic: %s", strerror(errno));
242 if (ywrite(pack_fd, &version, 4) != 4)
243 die("Can't write pack version: %s", strerror(errno));
244 if (ywrite(pack_fd, &zero, 4) != 4)
245 die("Can't write 0 object count: %s", strerror(errno));
249 static void fixup_header_footer()
257 if (lseek(pack_fd, 0, SEEK_SET) != 0)
258 die("Failed seeking to start: %s", strerror(errno));
261 if (yread(pack_fd, hdr, 8) != 8)
262 die("Failed reading header: %s", strerror(errno));
263 SHA1_Update(&c, hdr, 8);
265 cnt = htonl(object_count);
266 SHA1_Update(&c, &cnt, 4);
267 if (ywrite(pack_fd, &cnt, 4) != 4)
268 die("Failed writing object count: %s", strerror(errno));
270 buf = xmalloc(128 * 1024);
272 n = xread(pack_fd, buf, 128 * 1024);
275 SHA1_Update(&c, buf, n);
279 SHA1_Final(pack_sha1, &c);
280 if (ywrite(pack_fd, pack_sha1, sizeof(pack_sha1)) != sizeof(pack_sha1))
281 die("Failed writing pack checksum: %s", strerror(errno));
284 static int oecmp (const void *_a, const void *_b)
286 struct object_entry *a = *((struct object_entry**)_a);
287 struct object_entry *b = *((struct object_entry**)_b);
288 return memcmp(a->sha1, b->sha1, sizeof(a->sha1));
291 static void write_index(const char *idx_name)
294 struct object_entry **idx, **c, **last;
295 struct object_entry *e;
296 struct object_entry_block *o;
297 unsigned int array[256];
300 /* Build the sorted table of object IDs. */
301 idx = xmalloc(object_count * sizeof(struct object_entry*));
303 for (o = blocks; o; o = o->next_block)
304 for (e = o->entries; e != o->next_free; e++)
306 last = idx + object_count;
307 qsort(idx, object_count, sizeof(struct object_entry*), oecmp);
309 /* Generate the fan-out array. */
311 for (i = 0; i < 256; i++) {
312 struct object_entry **next = c;;
313 while (next < last) {
314 if ((*next)->sha1[0] != i)
318 array[i] = htonl(next - idx);
322 f = sha1create("%s", idx_name);
323 sha1write(f, array, 256 * sizeof(int));
324 for (c = idx; c != last; c++) {
325 unsigned int offset = htonl((*c)->offset);
326 sha1write(f, &offset, 4);
327 sha1write(f, (*c)->sha1, sizeof((*c)->sha1));
329 sha1write(f, pack_sha1, sizeof(pack_sha1));
330 sha1close(f, NULL, 1);
334 int main(int argc, const char **argv)
336 const char *base_name = argv[1];
337 int est_obj_cnt = atoi(argv[2]);
341 pack_name = xmalloc(strlen(base_name) + 6);
342 sprintf(pack_name, "%s.pack", base_name);
343 idx_name = xmalloc(strlen(base_name) + 5);
344 sprintf(idx_name, "%s.idx", base_name);
346 pack_fd = open(pack_name, O_RDWR|O_CREAT|O_EXCL, 0666);
348 die("Can't create pack file %s: %s", pack_name, strerror(errno));
350 alloc_objects(est_obj_cnt);
353 unsigned long datlen;
356 if (yread(0, &datlen, 4) != 4)
359 dat = xmalloc(datlen);
360 if (yread(0, dat, datlen) != datlen)
363 if (!store_object(OBJ_BLOB, dat, datlen, &last_blob))
366 fixup_header_footer();
368 write_index(idx_name);
370 fprintf(stderr, "%lu objects, %lu duplicates, %lu allocated (%lu overflow)\n",
371 object_count, duplicate_count, alloc_count, alloc_count - est_obj_cnt);