add a stat_validity struct
It can sometimes be useful to know whether a path in the filesystem has been updated without going to the work of opening and re-reading its content. We trust the stat() information on disk already to handle index updates, and we can use the same trick here. This patch introduces a "stat_validity" struct which encapsulates the concept of checking the stat-freshness of a file. It is implemented on top of "struct stat_data" to reuse the logic about which stat entries to trust for a particular platform, but hides the complexity behind two simple functions: check and update. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
c21d39d7c7
commit
3861253224
27
cache.h
27
cache.h
@ -1360,4 +1360,31 @@ int checkout_fast_forward(const unsigned char *from,
|
||||
|
||||
int sane_execvp(const char *file, char *const argv[]);
|
||||
|
||||
/*
|
||||
* A struct to encapsulate the concept of whether a file has changed
|
||||
* since we last checked it. This uses criteria similar to those used
|
||||
* for the index.
|
||||
*/
|
||||
struct stat_validity {
|
||||
struct stat_data *sd;
|
||||
};
|
||||
|
||||
void stat_validity_clear(struct stat_validity *sv);
|
||||
|
||||
/*
|
||||
* Returns 1 if the path is a regular file (or a symlink to a regular
|
||||
* file) and matches the saved stat_validity, 0 otherwise. A missing
|
||||
* or inaccessible file is considered a match if the struct was just
|
||||
* initialized, or if the previous update found an inaccessible file.
|
||||
*/
|
||||
int stat_validity_check(struct stat_validity *sv, const char *path);
|
||||
|
||||
/*
|
||||
* Update the stat_validity from a file opened at descriptor fd. If
|
||||
* the file is missing, inaccessible, or not a regular file, then
|
||||
* future calls to stat_validity_check will match iff one of those
|
||||
* conditions continues to be true.
|
||||
*/
|
||||
void stat_validity_update(struct stat_validity *sv, int fd);
|
||||
|
||||
#endif /* CACHE_H */
|
||||
|
30
read-cache.c
30
read-cache.c
@ -1950,3 +1950,33 @@ void *read_blob_data_from_index(struct index_state *istate, const char *path, un
|
||||
*size = sz;
|
||||
return data;
|
||||
}
|
||||
|
||||
void stat_validity_clear(struct stat_validity *sv)
|
||||
{
|
||||
free(sv->sd);
|
||||
sv->sd = NULL;
|
||||
}
|
||||
|
||||
int stat_validity_check(struct stat_validity *sv, const char *path)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (stat(path, &st) < 0)
|
||||
return sv->sd == NULL;
|
||||
if (!sv->sd)
|
||||
return 0;
|
||||
return S_ISREG(st.st_mode) && !match_stat_data(sv->sd, &st);
|
||||
}
|
||||
|
||||
void stat_validity_update(struct stat_validity *sv, int fd)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (fstat(fd, &st) < 0 || !S_ISREG(st.st_mode))
|
||||
stat_validity_clear(sv);
|
||||
else {
|
||||
if (!sv->sd)
|
||||
sv->sd = xcalloc(1, sizeof(struct stat_data));
|
||||
fill_stat_data(sv->sd, &st);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user