git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Kjetil Barvik <barvik@broadpark.no>
To: git@vger.kernel.org
Cc: Junio C Hamano <gitster@pobox.com>,
	Pete Harlan <pgit@pcharlan.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Kjetil Barvik <barvik@broadpark.no>
Subject: [PATCH/RFC v7 4/5] lstat_cache(): introduce invalidate_lstat_cache() function
Date: Tue, 13 Jan 2009 13:29:07 +0100	[thread overview]
Message-ID: <1231849748-8244-5-git-send-email-barvik@broadpark.no> (raw)
In-Reply-To: <1231849748-8244-1-git-send-email-barvik@broadpark.no>

In some cases it could maybe be necessary to say to the cache that
"Hey, I deleted this directory and if you currently has it inside your
cache, you should deleted it".  This patch introduce a function which
support this.

Signed-off-by: Kjetil Barvik <barvik@broadpark.no>
---
 cache.h    |    1 +
 symlinks.c |   39 +++++++++++++++++++++++++++++++--------
 2 files changed, 32 insertions(+), 8 deletions(-)

diff --git a/cache.h b/cache.h
index 7c8c8e4..f4452a8 100644
--- a/cache.h
+++ b/cache.h
@@ -722,6 +722,7 @@ extern int checkout_entry(struct cache_entry *ce, const struct checkout *state,
 extern int has_symlink_leading_path(int len, const char *name);
 extern int has_symlink_or_noent_leading_path(int len, const char *name);
 extern int has_dirs_only_path(int len, const char *name, int prefix_len);
+extern void invalidate_lstat_cache(int len, const char *name);
 
 extern struct alternate_object_database {
 	struct alternate_object_database *next;
diff --git a/symlinks.c b/symlinks.c
index f9d1821..3b1c3da 100644
--- a/symlinks.c
+++ b/symlinks.c
@@ -11,23 +11,30 @@ static struct cache_def {
 /* Returns the length (on a path component basis) of the longest
  * common prefix match of 'name' and the cached path string.
  */
-static inline int greatest_match_lstat_cache(int len, const char *name)
+static inline int greatest_match_lstat_cache(int len, const char *name,
+					     int *previous_slash)
 {
-	int max_len, match_len = 0, i = 0;
+	int max_len, match_len = 0, match_len_prev = 0, i = 0;
 
 	max_len = len < cache.len ? len : cache.len;
 	while (i < max_len && name[i] == cache.path[i]) {
-		if (name[i] == '/')
+		if (name[i] == '/') {
+			match_len_prev = match_len;
 			match_len = i;
+		}
 		i++;
 	}
 	/* Is the cached path string a substring of 'name'? */
-	if (i == cache.len && len > cache.len && name[cache.len] == '/')
+	if (i == cache.len && len > cache.len && name[cache.len] == '/') {
+		match_len_prev = match_len;
 		match_len = cache.len;
 	/* Is 'name' a substring of the cached path string? */
-	else if ((i == len && len < cache.len && cache.path[len] == '/') ||
-		 (i == len && len == cache.len))
+	} else if ((i == len && len < cache.len && cache.path[len] == '/') ||
+		   (i == len && len == cache.len)) {
+		match_len_prev = match_len;
 		match_len = len;
+	}
+	*previous_slash = match_len_prev;
 	return match_len;
 }
 
@@ -62,7 +69,7 @@ static inline void reset_lstat_cache(int track_flags, int prefix_len_stat_func)
 static int lstat_cache(int len, const char *name,
 		       int track_flags, int prefix_len_stat_func)
 {
-	int match_len, last_slash, last_slash_dir;
+	int match_len, last_slash, last_slash_dir, previous_slash;
 	int match_flags, ret_flags, save_flags, max_len, ret;
 	struct stat st;
 
@@ -80,7 +87,8 @@ static int lstat_cache(int len, const char *name,
 		 * Check to see if we have a match from the cache for
 		 * the 2 "excluding" path types.
 		 */
-		match_len = last_slash = greatest_match_lstat_cache(len, name);
+		match_len = last_slash =
+			greatest_match_lstat_cache(len, name, &previous_slash);
 		match_flags = cache.flags & track_flags & (FL_NOENT|FL_SYMLINK);
 		if (match_flags && match_len == cache.len)
 			return match_flags;
@@ -160,6 +168,21 @@ static int lstat_cache(int len, const char *name,
 	return ret_flags;
 }
 
+/* Invalidate the given 'name' from the cache, if 'name' matches
+ * completely with the cache.
+ */
+void invalidate_lstat_cache(int len, const char *name)
+{
+	int match_len, previous_slash;
+
+	match_len = greatest_match_lstat_cache(len, name, &previous_slash);
+	if (match_len == len) {
+		cache.path[previous_slash] = '\0';
+		cache.len   = previous_slash;
+		cache.flags = previous_slash ? FL_DIR : 0;
+	}
+}
+
 #define USE_ONLY_LSTAT  0
 
 /* Return non-zero if path 'name' has a leading symlink component.
-- 
1.6.0.2.GIT

  parent reply	other threads:[~2009-01-13 12:31 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-01-13 12:29 [PATCH/RFC v7 0/5] git checkout: optimise away lots of lstat() calls Kjetil Barvik
2009-01-13 12:29 ` [PATCH/RFC v7 1/5] lstat_cache(): more cache effective symlink/directory detection Kjetil Barvik
2009-01-13 12:29 ` [PATCH/RFC v7 2/5] lstat_cache(): introduce has_symlink_or_noent_leading_path() function Kjetil Barvik
2009-01-13 12:29 ` [PATCH/RFC v7 3/5] lstat_cache(): introduce has_dirs_only_path() function Kjetil Barvik
2009-01-13 12:29 ` Kjetil Barvik [this message]
2009-01-13 12:29 ` [PATCH/RFC v7 5/5] lstat_cache(): introduce clear_lstat_cache() function Kjetil Barvik
2009-01-13 20:17 ` [PATCH/RFC v7 0/5] git checkout: optimise away lots of lstat() calls Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1231849748-8244-5-git-send-email-barvik@broadpark.no \
    --to=barvik@broadpark.no \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=pgit@pcharlan.com \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).