1. 17 4月, 2007 5 次提交
    • N
      pack-objects: get rid of reuse_cached_pack · f7ae6a93
      Nicolas Pitre 提交于
      This capability is practically never useful, and therefore never tested,
      because it is fairly unlikely that the requested pack will be already
      available.  Furthermore it is of little gain over the ability to reuse
      existing pack data.
      
      In fact the ability to change delta type on the fly when reusing delta
      data is a nice thing that has almost no cost and allows greater backward
      compatibility with a client's capabilities than if the client is blindly
      sent a whole pack without any discrimination.
      
      And this "feature" is simply in the way of other cleanups.
      Let's get rid of it.
      Signed-off-by: NNicolas Pitre <nico@cam.org>
      Signed-off-by: NJunio C Hamano <junkio@cox.net>
      f7ae6a93
    • N
      pack-objects: clean up list sorting · 9668cf59
      Nicolas Pitre 提交于
      Get rid of sort_comparator() as it impose a run time double indirect
      function call for little compile time type checking gain.
      
      Also get rid of create_sorted_list() as it only has one user which would
      as well be just fine doing its sorting locally.  Eventually the list of
      deltifiable objects might be shorter than the whole object list.
      Signed-off-by: NNicolas Pitre <nico@cam.org>
      Signed-off-by: NJunio C Hamano <junkio@cox.net>
      9668cf59
    • N
      pack-objects: rework check_delta_limit usage · 898b14ce
      Nicolas Pitre 提交于
      Objects that have delta "children" from pack data reuse must consider the
      depth of their deepest child when they try to deltify themselves for those
      children not to become too deep.
      
      However, in the context of a "thin" pack, the delta children depth was
      skipped entirely on the presumption that the pack was always going to be
      exploded on the receiving end, hence the delta length wasn't an issue.
      
      Now that we keep received packs as is and reuse pack data when repacking,
      those packs do contain delta chains that are longer than expected. Worse,
      those delta chain may even grow longer when the pack is further repacked
      into another thin pack for a subsequent transmission.
      
      So this patch restores strict delta length even for thin packs, and it
      moves check_delta_limit() usage directly in the delta loop where it is
      needed.  This way the delta_limit can be removed from struct object_entry
      as well.  Oh and the initial value was wrong too.
      
      The  progress_interval() function was moved to a more logical location in
      the process.
      Signed-off-by: NNicolas Pitre <nico@cam.org>
      Signed-off-by: NJunio C Hamano <junkio@cox.net>
      898b14ce
    • N
      pack-objects: equal objects in size should delta against newer objects · adcc7095
      Nicolas Pitre 提交于
      Before finding best delta combinations, we sort objects by name hash,
      then by size, then by their position in memory.  Then we walk the list
      backwards to test delta candidates.
      
      We hope that a bigger size usually means a newer objects.  But a bigger
      address in memory does not mean a newer object.  So the last comparison
      must be reversed.
      Signed-off-by: NNicolas Pitre <nico@cam.org>
      Signed-off-by: NJunio C Hamano <junkio@cox.net>
      adcc7095
    • N
      pack-objects: optimize preferred base handling a bit · 8a5a8d6c
      Nicolas Pitre 提交于
      Let's avoid some cycles when there is no base to test against, and avoid
      unnecessary object lookups.
      Signed-off-by: NNicolas Pitre <nico@cam.org>
      Signed-off-by: NJunio C Hamano <junkio@cox.net>
      8a5a8d6c
  2. 12 4月, 2007 1 次提交
  3. 11 4月, 2007 7 次提交
    • N
      validate reused pack data with CRC when possible · 91ecbeca
      Nicolas Pitre 提交于
      This replaces the inflate validation with a CRC validation when reusing
      data from a pack which uses index version 2.  That makes repacking much
      safer against corruptions, and it should be a bit faster too.
      Signed-off-by: NNicolas Pitre <nico@cam.org>
      Signed-off-by: NJunio C Hamano <junkio@cox.net>
      91ecbeca
    • N
      allow forcing index v2 and 64-bit offset treshold · 4ba7d711
      Nicolas Pitre 提交于
      This is necessary for testing the new capabilities in some automated
      way without having an actual 4GB+ pack.
      Signed-off-by: NNicolas Pitre <nico@cam.org>
      Signed-off-by: NJunio C Hamano <junkio@cox.net>
      4ba7d711
    • N
      pack-objects: learn about pack index version 2 · c553ca25
      Nicolas Pitre 提交于
      Pack index version 2 goes as follows:
      
       - 8 bytes of header with signature and version.
      
       - 256 entries of 4-byte first-level fan-out table.
      
       - Table of sorted 20-byte SHA1 records for each object in pack.
      
       - Table of 4-byte CRC32 entries for raw pack object data.
      
       - Table of 4-byte offset entries for objects in the pack if offset is
         representable with 31 bits or less, otherwise it is an index in the next
         table with top bit set.
      
       - Table of 8-byte offset entries indexed from previous table for offsets
         which are 32 bits or more (optional).
      
       - 20-byte SHA1 checksum of sorted object names.
      
       - 20-byte SHA1 checksum of the above.
      
      The object SHA1 table is all contiguous so future pack format that would
      contain this table directly won't require big changes to the code. It is
      also tighter for slightly better cache locality when looking up entries.
      
      Support for large packs exceeding 31 bits in size won't impose an index
      size bloat for packs within that range that don't need a 64-bit offset.
      And because newer objects which are likely to be the most frequently used
      are located at the beginning of the pack, they won't pay the 64-bit offset
      lookup at run time either even if the pack is large.
      
      Right now an index version 2 is created only when the biggest offset in a
      pack reaches 31 bits.  It might be a good idea to always use index version
      2 eventually to benefit from the CRC32 it contains when reusing pack data
      while repacking.
      
      [jc: with the "oops" fix to keep track of the last offset correctly]
      Signed-off-by: NNicolas Pitre <nico@cam.org>
      Signed-off-by: NJunio C Hamano <junkio@cox.net>
      c553ca25
    • N
      compute a CRC32 for each object as stored in a pack · 78d1e84f
      Nicolas Pitre 提交于
      The most important optimization for performance when repacking is the
      ability to reuse data from a previous pack as is and bypass any delta
      or even SHA1 computation by simply copying the raw data from one pack
      to another directly.
      
      The problem with  this is that any data corruption within a copied object
      would go unnoticed and the new (repacked) pack would be self-consistent
      with its own checksum despite containing a corrupted object.  This is a
      real issue that already happened at least once in the past.
      
      In some attempt to prevent this, we validate the copied data by inflating
      it and making sure no error is signaled by zlib.  But this is still not
      perfect as a significant portion of a pack content is made of object
      headers and references to delta base objects which are not deflated and
      therefore not validated when repacking actually making the pack data reuse
      still not as safe as it could be.
      
      Of course a full SHA1 validation could be performed, but that implies
      full data inflating and delta replaying which is extremely costly, which
      cost the data reuse optimization was designed to avoid in the first place.
      
      So the best solution to this is simply to store a CRC32 of the raw pack
      data for each object in the pack index.  This way any object in a pack can
      be validated before being copied as is in another pack, including header
      and any other non deflated data.
      
      Why CRC32 instead of a faster checksum like Adler32?  Quoting Wikipedia:
      
         Jonathan Stone discovered in 2001 that Adler-32 has a weakness for very
         short messages. He wrote "Briefly, the problem is that, for very short
         packets, Adler32 is guaranteed to give poor coverage of the available
         bits. Don't take my word for it, ask Mark Adler. :-)" The problem is
         that sum A does not wrap for short messages. The maximum value of A for
         a 128-byte message is 32640, which is below the value 65521 used by the
         modulo operation. An extended explanation can be found in RFC 3309,
         which mandates the use of CRC32 instead of Adler-32 for SCTP, the
         Stream Control Transmission Protocol.
      
      In the context of a GIT pack, we have lots of small objects, especially
      deltas, which are likely to be quite small and in a size range for which
      Adler32 is dimed not to be sufficient.  Another advantage of CRC32 is the
      possibility for recovery from certain types of small corruptions like
      single bit errors which are the most probable type of corruptions.
      
      OK what this patch does is to compute the CRC32 of each object written to
      a pack within pack-objects.  It is not written to the index yet and it is
      obviously not validated when reusing pack data yet either.
      Signed-off-by: NNicolas Pitre <nico@cam.org>
      Signed-off-by: NJunio C Hamano <junkio@cox.net>
      78d1e84f
    • N
      add overflow tests on pack offset variables · d7dd0223
      Nicolas Pitre 提交于
      Change a few size and offset variables to more appropriate type, then
      add overflow tests on those offsets.  This prevents any bad data to be
      generated/processed if off_t happens to not be large enough to handle
      some big packs.
      
      Better be safe than sorry.
      Signed-off-by: NNicolas Pitre <nico@cam.org>
      Signed-off-by: NJunio C Hamano <junkio@cox.net>
      d7dd0223
    • N
      make overflow test on delta base offset work regardless of variable size · 8723f216
      Nicolas Pitre 提交于
      This patch introduces the MSB() macro to obtain the desired number of
      most significant bits from a given variable independently of the variable
      type.
      
      It is then used to better implement the overflow test on the OBJ_OFS_DELTA
      base offset variable with the property of always working correctly
      regardless of the type/size of that variable.
      Signed-off-by: NNicolas Pitre <nico@cam.org>
      Signed-off-by: NJunio C Hamano <junkio@cox.net>
      8723f216
    • N
      get rid of num_packed_objects() · 57059091
      Nicolas Pitre 提交于
      The coming index format change doesn't allow for the number of objects
      to be determined from the size of the index file directly.  Instead, Let's
      initialize a field in the packed_git structure with the object count when
      the index is validated since the count is always known at that point.
      
      While at it let's reorder some struct packed_git fields to avoid padding
      due to needed 64-bit alignment for some of them.
      Signed-off-by: NNicolas Pitre <nico@cam.org>
      Signed-off-by: NJunio C Hamano <junkio@cox.net>
      57059091
  4. 06 4月, 2007 1 次提交
  5. 22 3月, 2007 2 次提交
  6. 17 3月, 2007 1 次提交
    • N
      [PATCH] clean up pack index handling a bit · 42873078
      Nicolas Pitre 提交于
      Especially with the new index format to come, it is more appropriate
      to encapsulate more into check_packed_git_idx() and assume less of the
      index format in struct packed_git.
      
      To that effect, the index_base is renamed to index_data with void * type
      so it is not used directly but other pointers initialized with it. This
      allows for a couple pointer cast removal, as well as providing a better
      generic name to grep for when adding support for new index versions or
      formats.
      
      And index_data is declared const too while at it.
      Signed-off-by: NNicolas Pitre <nico@cam.org>
      Signed-off-by: NJunio C Hamano <junkio@cox.net>
      42873078
  7. 08 3月, 2007 2 次提交
  8. 27 2月, 2007 2 次提交
  9. 26 2月, 2007 1 次提交
    • R
      Allow arbitrary number of arguments to git-pack-objects · ffa84ffb
      Roland Dreier 提交于
      If a repository ever gets in a situation where there are too many
      packs (more than 60 or so), perhaps because of frequent use of
      git-fetch -k or incremental git-repack, then it becomes impossible to
      fully repack the repository with git-repack -a.  That command just
      dies with the cryptic message
      
          fatal: too many internal rev-list options
      
      This message comes from git-pack-objects, which is passed one command
      line option like --unpacked=pack-<SHA1>.pack for each pack file to be
      repacked.  However, the current code has a static limit of 64 command
      line arguments and just aborts if more arguments are passed to it.
      
      Fix this by dynamically allocating the array of command line
      arguments, and doubling the size each time it overflows.
      Signed-off-by: NRoland Dreier <roland@digitalvampire.org>
      Signed-off-by: NJunio C Hamano <junkio@cox.net>
      ffa84ffb
  10. 21 2月, 2007 2 次提交
    • J
      prefixcmp(): fix-up mechanical conversion. · 599065a3
      Junio C Hamano 提交于
      Previous step converted use of strncmp() with literal string
      mechanically even when the result is only used as a boolean:
      
          if (!strncmp("foo", arg, 3)) ==> if (!(-prefixcmp(arg, "foo")))
      
      This step manually cleans them up to read:
      
          if (!prefixcmp(arg, "foo"))
      Signed-off-by: NJunio C Hamano <junkio@cox.net>
      599065a3
    • J
      Mechanical conversion to use prefixcmp() · cc44c765
      Junio C Hamano 提交于
      This mechanically converts strncmp() to use prefixcmp(), but only when
      the parameters match specific patterns, so that they can be verified
      easily.  Leftover from this will be fixed in a separate step, including
      idiotic conversions like
      
          if (!strncmp("foo", arg, 3))
      
        =>
      
          if (!(-prefixcmp(arg, "foo")))
      
      This was done by using this script in px.perl
      
         #!/usr/bin/perl -i.bak -p
         if (/strncmp\(([^,]+), "([^\\"]*)", (\d+)\)/ && (length($2) == $3)) {
                 s|strncmp\(([^,]+), "([^\\"]*)", (\d+)\)|prefixcmp($1, "$2")|;
         }
         if (/strncmp\("([^\\"]*)", ([^,]+), (\d+)\)/ && (length($1) == $3)) {
                 s|strncmp\("([^\\"]*)", ([^,]+), (\d+)\)|(-prefixcmp($2, "$1"))|;
         }
      
      and running:
      
         $ git grep -l strncmp -- '*.c' | xargs perl px.perl
      Signed-off-by: NJunio C Hamano <junkio@cox.net>
      cc44c765
  11. 19 1月, 2007 1 次提交
  12. 30 12月, 2006 5 次提交
    • J
      pack-objects: fix use of use_pack(). · 9c18df19
      Junio C Hamano 提交于
      The code calls use_pack() to make that the variably encoded
      offset fits in the mmap'ed window, but it forgot that the
      operation gives the pointer to the beginning of the asked
      region.
      Signed-off-by: NJunio C Hamano <junkio@cox.net>
      9c18df19
    • S
      Fix random segfaults in pack-objects. · f5b1b5a0
      Shawn O. Pearce 提交于
      Junio noticed that 'non-trivial' pushes were failing if executed
      using the sliding window mmap changes.  This was somewhat difficult
      to track down as the failure was appearing randomly.
      
      It turns out this was a failure caused by the delta base reference
      (either ref or offset format) spanning over the end of a mmap window.
      
      The error in pack-objects was we were not recalling use_pack
      after the object header was unpacked, and therefore we did not
      get the promise of at least 20 bytes in the buffer for the delta
      base parsing.  This would case later memcmp() calls to walk into
      unassigned address space at the end of the window.
      
      The reason Junio and I had hard time tracking this down in current
      Git repositories is we were both probably packing with offset deltas,
      which minimized the odds of the delta base reference spanning over
      the end of the mmap window.  Stepping back and repacking with
      version 1.3.3 (which only supported reference deltas) increased
      the likelyhood of seeing the bug.
      
      The correct technique (as used in sha1_file.c) is to invoke
      use_pack() after unpack_object_header_gently to ensure we have
      enough data available for the delta base decoding.
      Signed-off-by: NShawn O. Pearce <spearce@spearce.org>
      Signed-off-by: NJunio C Hamano <junkio@cox.net>
      f5b1b5a0
    • S
      Loop over pack_windows when inflating/accessing data. · 079afb18
      Shawn O. Pearce 提交于
      When multiple mmaps start getting used for all pack file access it
      is not possible to get all data associated with a specific object
      in one contiguous memory region.  This limitation prevents simply
      passing a single address and length to SHA1_Update or to inflate.
      
      Instead we need to loop until we have processed all data of interest.
      
      As we loop over the data we are always interested in reusing the same
      window 'cursor', as the prior window will no longer be of any use
      to us.  This allows the use_pack() call to automatically decrement
      the use count of the prior window before setting up access for us
      to the next window.
      
      Within each loop we need to make use of the available length output
      parameter of use_pack() to tell us how many bytes are available in
      the current memory region, as we cannot tell otherwise.
      Signed-off-by: NShawn O. Pearce <spearce@spearce.org>
      Signed-off-by: NJunio C Hamano <junkio@cox.net>
      079afb18
    • S
      Replace use_packed_git with window cursors. · 03e79c88
      Shawn O. Pearce 提交于
      Part of the implementation concept of the sliding mmap window for
      pack access is to permit multiple windows per pack to be mapped
      independently.  Since the inuse_cnt is associated with the mmap and
      not with the file, this value is in struct pack_window and needs to
      be incremented/decremented for each pack_window accessed by any code.
      
      To faciliate that implementation we need to replace all uses of
      use_packed_git() and unuse_packed_git() with a different API that
      follows struct pack_window objects rather than struct packed_git.
      
      The way this works is when we need to start accessing a pack for
      the first time we should setup a new window 'cursor' by declaring
      a local and setting it to NULL:
      
        struct pack_windows *w_curs = NULL;
      
      To obtain the memory region which contains a specific section of
      the pack file we invoke use_pack(), supplying the address of our
      current window cursor:
      
        unsigned int len;
        unsigned char *addr = use_pack(p, &w_curs, offset, &len);
      
      the returned address `addr` will be the first byte at `offset`
      within the pack file.  The optional variable len will also be
      updated with the number of bytes remaining following the address.
      
      Multiple calls to use_pack() with the same window cursor will
      update the window cursor, moving it from one window to another
      when necessary.  In this way each window cursor variable maintains
      only one struct pack_window inuse at a time.
      
      Finally before exiting the scope which originally declared the window
      cursor we must invoke unuse_pack() to unuse the current window (which
      may be different from the one that was first obtained from use_pack):
      
        unuse_pack(&w_curs);
      
      This implementation is still not complete with regards to multiple
      windows, as only one window per pack file is supported right now.
      Signed-off-by: NShawn O. Pearce <spearce@spearce.org>
      Signed-off-by: NJunio C Hamano <junkio@cox.net>
      03e79c88
    • S
      Refactor packed_git to prepare for sliding mmap windows. · c41ee586
      Shawn O. Pearce 提交于
      The idea behind the sliding mmap window pack reader implementation
      is to have multiple mmap regions active against the same pack file,
      thereby allowing the process to mmap in only the active/hot sections
      of the pack and reduce overall virtual address space usage.
      
      To implement this we need to refactor the mmap related data
      (pack_base, pack_use_cnt) out of struct packed_git and move them
      into a new struct pack_window.
      
      We are refactoring the code to support a single struct pack_window
      per packfile, thereby emulating the prior behavior of mmap'ing the
      entire pack file.
      Signed-off-by: NShawn O. Pearce <spearce@spearce.org>
      Signed-off-by: NJunio C Hamano <junkio@cox.net>
      c41ee586
  13. 21 12月, 2006 2 次提交
    • J
      Teach git-repack to preserve objects referred to by reflog entries. · 63049292
      Junio C Hamano 提交于
      This adds a new option --reflog to pack-objects and revision
      machinery; do not bother documenting it for now, since this is
      only useful for local repacking.
      
      When the option is passed, objects reachable from reflog entries
      are marked as interesting while computing the set of objects to
      pack.
      Signed-off-by: NJunio C Hamano <junkio@cox.net>
      63049292
    • J
      simplify inclusion of system header files. · 85023577
      Junio C Hamano 提交于
      This is a mechanical clean-up of the way *.c files include
      system header files.
      
       (1) sources under compat/, platform sha-1 implementations, and
           xdelta code are exempt from the following rules;
      
       (2) the first #include must be "git-compat-util.h" or one of
           our own header file that includes it first (e.g. config.h,
           builtin.h, pkt-line.h);
      
       (3) system headers that are included in "git-compat-util.h"
           need not be included in individual C source files.
      
       (4) "git-compat-util.h" does not have to include subsystem
           specific header files (e.g. expat.h).
      Signed-off-by: NJunio C Hamano <junkio@cox.net>
      85023577
  14. 30 11月, 2006 1 次提交
  15. 17 11月, 2006 1 次提交
  16. 08 11月, 2006 1 次提交
  17. 02 11月, 2006 1 次提交
  18. 10 10月, 2006 1 次提交
  19. 28 9月, 2006 2 次提交
  20. 27 9月, 2006 1 次提交