Merge branch 'np/verify-pack'
authorJunio C Hamano <gitster@pobox.com>
Mon, 3 Mar 2008 00:07:30 +0000 (16:07 -0800)
committerJunio C Hamano <gitster@pobox.com>
Mon, 3 Mar 2008 00:07:30 +0000 (16:07 -0800)
* 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

1  2 
Makefile
builtin-pack-objects.c
diff --combined Makefile
index 71f01d16b1a42d366b04f1fce621db4dac6b1976,1acac027667b89b90235d2873652b01c991b952f..ca5aad963ca7b5565338f49ce1705c451216c8be
+++ 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 \
        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 6c8b662e7835501f7540c8323596d4e04e0b90d1,c7834bb3684131b508257e0e11c81a8934d5b700..2799e6833849eea9a4cb35213c1115c44bf702ed
@@@ -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) {