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>

Michael Haggerty committed Jun 20, 2013 at 10:37 UTC 38612532240ecbe1b12e54ca859fed8410ae6de1
2 files changed +57
cache.h
+27
@@ -1360,4 +1360,31 @@ int checkout_fast_forward(const unsigned char *from,
1360
1361 int sane_execvp(const char *file, char *const argv[]);
1362
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 +
1390 #endif /* CACHE_H */
read-cache.c
+30
@@ -1950,3 +1950,33 @@ void *read_blob_data_from_index(struct index_state *istate, const char *path, un
1950 *size = sz;
1951 return data;
1952 }
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 +}