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
+}