From: Junio C Hamano Date: Mon, 3 Mar 2008 00:07:30 +0000 (-0800) Subject: Merge branch 'np/verify-pack' X-Git-Tag: v1.5.5-rc0~82 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/c0b48ad777eb8ad42d8d0eafc8f0ee82955b1319?ds=inline;hp=-c Merge branch 'np/verify-pack' * np/verify-pack: add storage size output to 'git verify-pack -v' fix unimplemented packed_object_info_detail() features make verify_one_pack() a bit less wrong wrt packed_git structure factorize revindex code out of builtin-pack-objects.c Conflicts: Makefile --- c0b48ad777eb8ad42d8d0eafc8f0ee82955b1319 diff --combined Makefile index 71f01d16b1,1acac02766..ca5aad963c --- a/Makefile +++ b/Makefile @@@ -304,7 -304,8 +304,8 @@@ LIB_H = run-command.h strbuf.h tag.h tree.h git-compat-util.h revision.h \ tree-walk.h log-tree.h dir.h path-list.h unpack-trees.h builtin.h \ utf8.h reflog-walk.h patch-ids.h attr.h decorate.h progress.h \ - mailmap.h remote.h parse-options.h transport.h diffcore.h hash.h fsck.h - mailmap.h remote.h parse-options.h transport.h diffcore.h hash.h \ ++ mailmap.h remote.h parse-options.h transport.h diffcore.h hash.h fsck.h \ + pack-revindex.h DIFF_OBJS = \ diff.o diff-lib.o diffcore-break.o diffcore-order.o \ @@@ -319,7 -320,7 +320,7 @@@ LIB_OBJS = patch-ids.o \ object.o pack-check.o pack-write.o patch-delta.o path.o pkt-line.o \ sideband.o reachable.o reflog-walk.o \ - quote.o read-cache.o refs.o run-command.o dir.o object-refs.o \ + quote.o read-cache.o refs.o run-command.o dir.o \ server-info.o setup.o sha1_file.o sha1_name.o strbuf.o \ tag.o tree.o usage.o config.o environment.o ctype.o copy.o \ revision.o pager.o tree-walk.o xdiff-interface.o \ @@@ -328,7 -329,7 +329,7 @@@ color.o wt-status.o archive-zip.o archive-tar.o shallow.o utf8.o \ convert.o attr.o decorate.o progress.o mailmap.o symlinks.o remote.o \ transport.o bundle.o walker.o parse-options.o ws.o archive.o branch.o \ - alias.o fsck.o - alias.o pack-revindex.o ++ alias.o fsck.o pack-revindex.o BUILTIN_OBJS = \ builtin-add.o \ @@@ -812,7 -813,7 +813,7 @@@ export TAR INSTALL DESTDIR SHELL_PAT ### Build rules -all:: $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) +all:: $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) GIT-BUILD-OPTIONS ifneq (,$X) $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), $(RM) '$p';) endif @@@ -1011,9 -1012,6 +1012,9 @@@ GIT-CFLAGS: .FORCE-GIT-CFLAG echo "$$FLAGS" >GIT-CFLAGS; \ fi +GIT-BUILD-OPTIONS: .FORCE-GIT-BUILD-OPTIONS + @echo SHELL_PATH=\''$(SHELL_PATH_SQ)'\' >$@ + ### Detect Tck/Tk interpreter path changes ifndef NO_TCLTK TRACK_VARS = $(subst ','\'',-DTCLTK_PATH='$(TCLTK_PATH_SQ)') @@@ -1169,11 -1167,10 +1170,11 @@@ ifndef NO_TCLT $(MAKE) -C gitk-git clean $(MAKE) -C git-gui clean endif - $(RM) GIT-VERSION-FILE GIT-CFLAGS GIT-GUI-VARS + $(RM) GIT-VERSION-FILE GIT-CFLAGS GIT-GUI-VARS GIT-BUILD-OPTIONS .PHONY: all install clean strip .PHONY: .FORCE-GIT-VERSION-FILE TAGS tags cscope .FORCE-GIT-CFLAGS +.PHONY: .FORCE-GIT-BUILD-OPTIONS ### Check documentation # diff --combined builtin-pack-objects.c index 6c8b662e78,c7834bb368..2799e68338 --- a/builtin-pack-objects.c +++ b/builtin-pack-objects.c @@@ -8,6 -8,7 +8,7 @@@ #include "tree.h" #include "delta.h" #include "pack.h" + #include "pack-revindex.h" #include "csum-file.h" #include "tree-walk.h" #include "diff.h" @@@ -92,158 -93,12 +93,12 @@@ static unsigned long window_memory_limi static int *object_ix; static int object_ix_hashsz; - /* - * Pack index for existing packs give us easy access to the offsets into - * corresponding pack file where each object's data starts, but the entries - * do not store the size of the compressed representation (uncompressed - * size is easily available by examining the pack entry header). It is - * also rather expensive to find the sha1 for an object given its offset. - * - * We build a hashtable of existing packs (pack_revindex), and keep reverse - * index here -- pack index file is sorted by object name mapping to offset; - * this pack_revindex[].revindex array is a list of offset/index_nr pairs - * ordered by offset, so if you know the offset of an object, next offset - * is where its packed representation ends and the index_nr can be used to - * get the object sha1 from the main index. - */ - struct revindex_entry { - off_t offset; - unsigned int nr; - }; - struct pack_revindex { - struct packed_git *p; - struct revindex_entry *revindex; - }; - static struct pack_revindex *pack_revindex; - static int pack_revindex_hashsz; - /* * stats */ static uint32_t written, written_delta; static uint32_t reused, reused_delta; - static int pack_revindex_ix(struct packed_git *p) - { - unsigned long ui = (unsigned long)p; - int i; - - ui = ui ^ (ui >> 16); /* defeat structure alignment */ - i = (int)(ui % pack_revindex_hashsz); - while (pack_revindex[i].p) { - if (pack_revindex[i].p == p) - return i; - if (++i == pack_revindex_hashsz) - i = 0; - } - return -1 - i; - } - - static void prepare_pack_ix(void) - { - int num; - struct packed_git *p; - for (num = 0, p = packed_git; p; p = p->next) - num++; - if (!num) - return; - pack_revindex_hashsz = num * 11; - pack_revindex = xcalloc(sizeof(*pack_revindex), pack_revindex_hashsz); - for (p = packed_git; p; p = p->next) { - num = pack_revindex_ix(p); - num = - 1 - num; - pack_revindex[num].p = p; - } - /* revindex elements are lazily initialized */ - } - - static int cmp_offset(const void *a_, const void *b_) - { - const struct revindex_entry *a = a_; - const struct revindex_entry *b = b_; - return (a->offset < b->offset) ? -1 : (a->offset > b->offset) ? 1 : 0; - } - - /* - * Ordered list of offsets of objects in the pack. - */ - static void prepare_pack_revindex(struct pack_revindex *rix) - { - struct packed_git *p = rix->p; - int num_ent = p->num_objects; - int i; - const char *index = p->index_data; - - rix->revindex = xmalloc(sizeof(*rix->revindex) * (num_ent + 1)); - index += 4 * 256; - - if (p->index_version > 1) { - const uint32_t *off_32 = - (uint32_t *)(index + 8 + p->num_objects * (20 + 4)); - const uint32_t *off_64 = off_32 + p->num_objects; - for (i = 0; i < num_ent; i++) { - uint32_t off = ntohl(*off_32++); - if (!(off & 0x80000000)) { - rix->revindex[i].offset = off; - } else { - rix->revindex[i].offset = - ((uint64_t)ntohl(*off_64++)) << 32; - rix->revindex[i].offset |= - ntohl(*off_64++); - } - rix->revindex[i].nr = i; - } - } else { - for (i = 0; i < num_ent; i++) { - uint32_t hl = *((uint32_t *)(index + 24 * i)); - rix->revindex[i].offset = ntohl(hl); - rix->revindex[i].nr = i; - } - } - - /* This knows the pack format -- the 20-byte trailer - * follows immediately after the last object data. - */ - rix->revindex[num_ent].offset = p->pack_size - 20; - rix->revindex[num_ent].nr = -1; - qsort(rix->revindex, num_ent, sizeof(*rix->revindex), cmp_offset); - } - - static struct revindex_entry * find_packed_object(struct packed_git *p, - off_t ofs) - { - int num; - int lo, hi; - struct pack_revindex *rix; - struct revindex_entry *revindex; - num = pack_revindex_ix(p); - if (num < 0) - die("internal error: pack revindex uninitialized"); - rix = &pack_revindex[num]; - if (!rix->revindex) - prepare_pack_revindex(rix); - revindex = rix->revindex; - lo = 0; - hi = p->num_objects + 1; - do { - int mi = (lo + hi) / 2; - if (revindex[mi].offset == ofs) { - return revindex + mi; - } - else if (ofs < revindex[mi].offset) - hi = mi; - else - lo = mi + 1; - } while (lo < hi); - die("internal error: pack revindex corrupt"); - } - - static const unsigned char *find_packed_object_name(struct packed_git *p, - off_t ofs) - { - struct revindex_entry *entry = find_packed_object(p, ofs); - return nth_packed_object_sha1(p, entry->nr); - } static void *delta_against(void *buf, unsigned long size, struct object_entry *entry) { @@@ -510,7 -365,7 +365,7 @@@ static unsigned long write_object(struc } hdrlen = encode_header(obj_type, entry->size, header); offset = entry->in_pack_offset; - revidx = find_packed_object(p, offset); + revidx = find_pack_revindex(p, offset); datalen = revidx[1].offset - offset; if (!pack_to_stdout && p->index_version > 1 && check_pack_crc(p, &w_curs, offset, datalen, revidx->nr)) @@@ -1162,8 -1017,11 +1017,11 @@@ static void check_object(struct object_ die("delta base offset out of bound for %s", sha1_to_hex(entry->idx.sha1)); ofs = entry->in_pack_offset - ofs; - if (!no_reuse_delta && !entry->preferred_base) - base_ref = find_packed_object_name(p, ofs); + if (!no_reuse_delta && !entry->preferred_base) { + struct revindex_entry *revidx; + revidx = find_pack_revindex(p, ofs); + base_ref = nth_packed_object_sha1(p, revidx->nr); + } entry->in_pack_header_size = used + used_0; break; } @@@ -1240,9 -1098,11 +1098,11 @@@ static void get_object_details(void sorted_by_offset[i] = objects + i; qsort(sorted_by_offset, nr_objects, sizeof(*sorted_by_offset), pack_offset_sort); - prepare_pack_ix(); + init_pack_revindex(); + for (i = 0; i < nr_objects; i++) check_object(sorted_by_offset[i]); + free(sorted_by_offset); } @@@ -2013,6 -1873,7 +1873,6 @@@ static void get_object_list(int ac, con init_revisions(&revs, NULL); save_commit_buffer = 0; - track_object_refs = 0; setup_revisions(ac, av, &revs, NULL); while (fgets(line, sizeof(line), stdin) != NULL) {