1. 30 7月, 2009 1 次提交
  2. 10 7月, 2009 2 次提交
  3. 08 6月, 2009 1 次提交
  4. 18 3月, 2009 1 次提交
  5. 10 2月, 2009 5 次提交
    • K
      lstat_cache(): print a warning if doing ping-pong between cache types · 7734f048
      Kjetil Barvik 提交于
      This is a debug patch which is only to be used while the lstat_cache()
      is in the test stage, and should be removed/reverted before the final
      relase.
      
      I think it should be useful to catch these warnings, as I it could be
      an indication of that the cache would not be very effective if it is
      doing ping-pong by switching between different cache types too many
      times.
      
      Also, if someone is experimenting with the lstat_cache(), this patch
      will maybe be useful while debugging.
      
      If someone is able to trigger the warning, then send a mail to the GIT
      mailing list, containing the first 15 lines of the warning, and a
      short description of the GIT commands to trigger the warnings.
      
      I hope someone is willing to use this patch for a while, to be able to
      catch possible ping-pong's.
      Signed-off-by: NKjetil Barvik <barvik@broadpark.no>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      7734f048
    • K
      unlink_entry(): introduce schedule_dir_for_removal() · 78478927
      Kjetil Barvik 提交于
      Currently inside unlink_entry() if we get a successful removal of one
      file with unlink(), we try to remove the leading directories each and
      every time.  So if one directory containing 200 files is moved to an
      other location we get 199 failed calls to rmdir() and 1 successful
      call.
      
      To fix this and avoid some unnecessary calls to rmdir(), we schedule
      each directory for removal and wait much longer before we do the real
      call to rmdir().
      
      Since the unlink_entry() function is called with alphabetically sorted
      names, this new function end up being very effective to avoid
      unnecessary calls to rmdir().  In some cases over 95% of all calls to
      rmdir() is removed with this patch.
      Signed-off-by: NKjetil Barvik <barvik@broadpark.no>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      78478927
    • K
      lstat_cache(): swap func(length, string) into func(string, length) · 57199892
      Kjetil Barvik 提交于
      Swap function argument pair (length, string) into (string, length) to
      conform with the commonly used order inside the GIT source code.
      
      Also, add a note about this fact into the coding guidelines.
      Signed-off-by: NKjetil Barvik <barvik@broadpark.no>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      57199892
    • K
      lstat_cache(): generalise longest_match_lstat_cache() · 148bc06b
      Kjetil Barvik 提交于
      Rename the function to longst_path_match() and generalise it such that
      it can also be used by other functions.
      Signed-off-by: NKjetil Barvik <barvik@broadpark.no>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      148bc06b
    • K
      lstat_cache(): small cleanup and optimisation · 60b458b7
      Kjetil Barvik 提交于
      Simplify the if-else test in longest_match_lstat_cache() such that we
      only have one simple if test.  Instead of testing for 'i == cache.len'
      or 'i == len', we transform this to a common test for 'i == max_len'.
      
      And to further optimise we use 'i >= max_len' instead of 'i ==
      max_len', the reason is that it is now the exact opposite of one part
      inside the while-loop termination expression 'i < max_len && name[i]
      == cache.path[i]', and then the compiler can probably reuse a test
      instruction from it.
      
      We also throw away the arguments to reset_lstat_cache(), such that all
      the safeguard logic inside lstat_cache() is handled at one place.
      Signed-off-by: NKjetil Barvik <barvik@broadpark.no>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      60b458b7
  6. 19 1月, 2009 5 次提交
    • K
      lstat_cache(): introduce clear_lstat_cache() function · bda6eb0d
      Kjetil Barvik 提交于
      If you want to completely clear the contents of the lstat_cache(), then
      call this new function.
      Signed-off-by: NKjetil Barvik <barvik@broadpark.no>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      bda6eb0d
    • K
      lstat_cache(): introduce invalidate_lstat_cache() function · aeabab5c
      Kjetil Barvik 提交于
      In some cases it could maybe be necessary to say to the cache that
      "Hey, I deleted/changed the type of this pathname and if you currently
      have it inside your cache, you should deleted it".
      
      This patch introduce a function which support this.
      Signed-off-by: NKjetil Barvik <barvik@broadpark.no>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      aeabab5c
    • K
      lstat_cache(): introduce has_dirs_only_path() function · bad4a54f
      Kjetil Barvik 提交于
      The create_directories() function in entry.c currently calls stat()
      or lstat() for each path component of the pathname 'path' each and every
      time.  For the 'git checkout' command, this function is called on each
      file for which we must do an update (ce->ce_flags & CE_UPDATE), so we get
      lots and lots of calls.
      
      To fix this, we make a new wrapper to the lstat_cache() function, and
      call the wrapper function instead of the calls to the stat() or the
      lstat() functions.  Since the paths given to the create_directories()
      function, is sorted alphabetically, the new wrapper would be very
      cache effective in this situation.
      
      To support it we must update the lstat_cache() function to be able to
      say that "please test the complete length of 'name'", and also to give
      it the length of a prefix, where the cache should use the stat()
      function instead of the lstat() function to test each path component.
      
      Thanks to Junio C Hamano, Linus Torvalds and Rene Scharfe for valuable
      comments to this patch!
      Signed-off-by: NKjetil Barvik <barvik@broadpark.no>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      bad4a54f
    • K
      lstat_cache(): introduce has_symlink_or_noent_leading_path() function · 09c93066
      Kjetil Barvik 提交于
      In some cases, especially inside the unpack-trees.c file, and inside
      the verify_absent() function, we can avoid some unnecessary calls to
      lstat(), if the lstat_cache() function can also be told to keep track
      of non-existing directories.
      
      So we update the lstat_cache() function to handle this new fact,
      introduce a new wrapper function, and the result is that we save lots
      of lstat() calls for a removed directory which previously contained
      lots of files, when we call this new wrapper of lstat_cache() instead
      of the old one.
      
      We do similar changes inside the unlink_entry() function, since if we
      can already say that the leading directory component of a pathname
      does not exist, it is not necessary to try to remove a pathname below
      it!
      
      Thanks to Junio C Hamano, Linus Torvalds and Rene Scharfe for valuable
      comments to this patch!
      Signed-off-by: NKjetil Barvik <barvik@broadpark.no>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      09c93066
    • K
      lstat_cache(): more cache effective symlink/directory detection · 92604b46
      Kjetil Barvik 提交于
      Make the cache functionality more effective.  Previously when A/B/C/D
      was in the cache and A/B/C/E/file.c was called for, there was no match
      at all from the cache.  Now we use the fact that the paths "A", "A/B"
      and "A/B/C" are already tested, and we only need to do an lstat() call
      on "A/B/C/E".
      
      We only cache/store the last path regardless of its type.  Since the
      cache functionality is always used with alphabetically sorted names
      (at least it seems so for me), there is no need to store both the last
      symlink-leading path and the last real-directory path.  Note that if
      the cache is not called with (mostly) alphabetically sorted names,
      neither the old, nor this new one, would be very effective.
      
      Previously, when symlink A/B/C/S was cached/stored in the symlink-
      leading path, and A/B/C/file.c was called for, it was not easy to use
      the fact that we already knew that the paths "A", "A/B" and "A/B/C"
      are real directories.
      
      Avoid copying the first path components of the name 2 zillion times
      when we test new path components.  Since we always cache/store the
      last path, we can copy each component as we test those directly into
      the cache.  Previously we ended up doing a memcpy() for the full
      path/name right before each lstat() call, and when updating the cache
      for each time we have tested a new path component.
      
      We also use less memory, that is, PATH_MAX bytes less memory on the
      stack and PATH_MAX bytes less memory on the heap.
      
      Thanks to Junio C Hamano, Linus Torvalds and Rene Scharfe for valuable
      comments to this patch!
      Signed-off-by: NKjetil Barvik <barvik@broadpark.no>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      92604b46
  7. 11 5月, 2008 1 次提交
    • L
      Optimize symlink/directory detection · c40641b7
      Linus Torvalds 提交于
      This is the base for making symlink detection in the middle fo a pathname
      saner and (much) more efficient.
      
      Under various loads, we want to verify that the full path leading up to a
      filename is a real directory tree, and that when we successfully do an
      'lstat()' on a filename, we don't get a false positive due to a symlink in
      the middle of the path that git should have seen as a symlink, not as a
      normal path component.
      
      The 'has_symlink_leading_path()' function already did this, and cached
      a single level of symlink information, but didn't cache the _lack_ of a
      symlink, so the normal behaviour was actually the wrong way around, and we
      ended up doing an 'lstat()' on each path component to check that it was a
      real directory.
      
      This caches the last detected full directory and symlink entries, and
      speeds up especially deep directory structures a lot by avoiding to
      lstat() all the directories leading up to each entry in the index.
      
      [ This can - and should - probably be extended upon so that we eventually
        never do a bare 'lstat()' on any path entries at *all* when checking the
        index, but always check the full path carefully. Right now we do not
        generally check the whole path for all our normal quick index
        revalidation.
      
        We should also make sure that we're careful about all the invalidation,
        ie when we remove a link and replace it by a directory we should
        invalidate the symlink cache if it matches (and vice versa for the
        directory cache).
      
        But regardless, the basic function needs to be sane to do that. The old
        'has_symlink_leading_path()' was not capable enough - or indeed the code
        readable enough - to really do that sanely. So I'm pushing this as not
        just an optimization, but as a base for further work. ]
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      c40641b7
  8. 12 5月, 2007 1 次提交
    • J
      Add has_symlink_leading_path() function. · f859c846
      Junio C Hamano 提交于
      When we are applying a patch that creates a blob at a path, or
      when we are switching from a branch that does not have a blob at
      the path to another branch that has one, we need to make sure
      that there is nothing at the path in the working tree, as such a
      file is a local modification made by the user that would be lost
      by the operation.
      
      Normally, lstat() on the path and making sure ENOENT is returned
      is good enough for that purpose.  However there is a twist.  We
      may be creating a regular file arch/x86_64/boot/Makefile, while
      removing an existing symbolic link at arch/x86_64/boot that
      points at existing ../i386/boot directory that has Makefile in
      it.  We always first check without touching filesystem and then
      perform the actual operation, so when we verify the new file,
      arch/x86_64/boot/Makefile, does not exist, we haven't removed
      the symbolic link arc/x86_64/boot symbolic link yet.  lstat() on
      the file sees through the symbolic link and reports the file is
      there, which is not what we want.
      
      The function has_symlink_leading_path() function takes a path,
      and sees if any of the leading directory component is a symbolic
      link.
      
      When files in a new directory are created, we tend to process
      them together because both index and tree are sorted.  The
      function takes advantage of this and allows the caller to cache
      and reuse which symbolic link on the filesystem caused the
      function to return true.
      
      The calling sequence would be:
      
      	char last_symlink[PATH_MAX];
      
              *last_symlink = '\0';
              for each index entry {
      		if (!lose)
      			continue;
      		if (lstat(it))
      			if (errno == ENOENT)
      				; /* happy */
      			else
      				error;
      		else if (has_symlink_leading_path(it, last_symlink))
      			; /* happy */
      		else
      			error; /* would lose local changes */
      		unlink_entry(it, last_symlink);
      	}
      Signed-off-by: NJunio C Hamano <junkio@cox.net>
      f859c846