Skip to content

Commit 3861253

Browse files
mhaggergitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent c21d39d commit 3861253

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

cache.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1360,4 +1360,31 @@ int checkout_fast_forward(const unsigned char *from,
13601360

13611361
int sane_execvp(const char *file, char *const argv[]);
13621362

1363+
/*
1364+
* A struct to encapsulate the concept of whether a file has changed
1365+
* since we last checked it. This uses criteria similar to those used
1366+
* for the index.
1367+
*/
1368+
struct stat_validity {
1369+
struct stat_data *sd;
1370+
};
1371+
1372+
void stat_validity_clear(struct stat_validity *sv);
1373+
1374+
/*
1375+
* Returns 1 if the path is a regular file (or a symlink to a regular
1376+
* file) and matches the saved stat_validity, 0 otherwise. A missing
1377+
* or inaccessible file is considered a match if the struct was just
1378+
* initialized, or if the previous update found an inaccessible file.
1379+
*/
1380+
int stat_validity_check(struct stat_validity *sv, const char *path);
1381+
1382+
/*
1383+
* Update the stat_validity from a file opened at descriptor fd. If
1384+
* the file is missing, inaccessible, or not a regular file, then
1385+
* future calls to stat_validity_check will match iff one of those
1386+
* conditions continues to be true.
1387+
*/
1388+
void stat_validity_update(struct stat_validity *sv, int fd);
1389+
13631390
#endif /* CACHE_H */

read-cache.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1950,3 +1950,33 @@ void *read_blob_data_from_index(struct index_state *istate, const char *path, un
19501950
*size = sz;
19511951
return data;
19521952
}
1953+
1954+
void stat_validity_clear(struct stat_validity *sv)
1955+
{
1956+
free(sv->sd);
1957+
sv->sd = NULL;
1958+
}
1959+
1960+
int stat_validity_check(struct stat_validity *sv, const char *path)
1961+
{
1962+
struct stat st;
1963+
1964+
if (stat(path, &st) < 0)
1965+
return sv->sd == NULL;
1966+
if (!sv->sd)
1967+
return 0;
1968+
return S_ISREG(st.st_mode) && !match_stat_data(sv->sd, &st);
1969+
}
1970+
1971+
void stat_validity_update(struct stat_validity *sv, int fd)
1972+
{
1973+
struct stat st;
1974+
1975+
if (fstat(fd, &st) < 0 || !S_ISREG(st.st_mode))
1976+
stat_validity_clear(sv);
1977+
else {
1978+
if (!sv->sd)
1979+
sv->sd = xcalloc(1, sizeof(struct stat_data));
1980+
fill_stat_data(sv->sd, &st);
1981+
}
1982+
}

0 commit comments

Comments
 (0)