Commit c3da9f06 by Carlos Martín Nieto

Add git_futils_readbuffer_updated

This extends the git_fuitls_readbuffer function to only read in if the
file's modification date is later than the given one. Some code paths
want to check a file's modification date in order to decide whether
they should read it or not. If they do want to read it, another stat
call is done by futils. This function combines these two operations so
we avoid one stat call each time we read a new or updated file.

The git_futils_readbuffer functions is now a wrapper around the new
function.

Signed-off-by: Carlos Martín Nieto <cmn@elego.de>
parent f630366f
...@@ -141,23 +141,40 @@ git_off_t git_futils_filesize(git_file fd) ...@@ -141,23 +141,40 @@ git_off_t git_futils_filesize(git_file fd)
return sb.st_size; return sb.st_size;
} }
int git_futils_readbuffer(git_fbuffer *obj, const char *path) int git_futils_readbuffer_updated(git_fbuffer *obj, const char *path, time_t *mtime, int *updated)
{ {
git_file fd; git_file fd;
size_t len; size_t len;
git_off_t size; struct stat st;
unsigned char *buff; unsigned char *buff;
assert(obj && path && *path); assert(obj && path && *path);
if ((fd = p_open(path, O_RDONLY)) < 0) if (updated != NULL)
return git__throw(GIT_ERROR, "Failed to open %s for reading", path); *updated = 0;
if (((size = git_futils_filesize(fd)) < 0) || !git__is_sizet(size+1)) { if (p_stat(path, &st) < 0)
p_close(fd); return git__throw(GIT_ENOTFOUND, "Failed to stat file %s", path);
if (S_ISDIR(st.st_mode))
return git__throw(GIT_ERROR, "Can't read a dir into a buffer");
/*
* If we were given a time, we only want to read the file if it
* has been modified.
*/
if (mtime != NULL && *mtime >= st.st_mtime)
return GIT_SUCCESS;
if (mtime != NULL)
*mtime = st.st_mtime;
if (!git__is_sizet(st.st_size+1))
return git__throw(GIT_ERROR, "Failed to read file `%s`. An error occured while calculating its size", path); return git__throw(GIT_ERROR, "Failed to read file `%s`. An error occured while calculating its size", path);
}
len = (size_t) size; len = (size_t) st.st_size;
if ((fd = p_open(path, O_RDONLY)) < 0)
return git__throw(GIT_EOSERR, "Failed to open %s for reading", path);
if ((buff = git__malloc(len + 1)) == NULL) { if ((buff = git__malloc(len + 1)) == NULL) {
p_close(fd); p_close(fd);
...@@ -173,12 +190,22 @@ int git_futils_readbuffer(git_fbuffer *obj, const char *path) ...@@ -173,12 +190,22 @@ int git_futils_readbuffer(git_fbuffer *obj, const char *path)
p_close(fd); p_close(fd);
if (mtime != NULL)
*mtime = st.st_mtime;
if (updated != NULL)
*updated = 1;
obj->data = buff; obj->data = buff;
obj->len = len; obj->len = len;
return GIT_SUCCESS; return GIT_SUCCESS;
} }
int git_futils_readbuffer(git_fbuffer *obj, const char *path)
{
return git_futils_readbuffer_updated(obj, path, NULL, NULL);
}
void git_futils_freebuffer(git_fbuffer *obj) void git_futils_freebuffer(git_fbuffer *obj)
{ {
assert(obj); assert(obj);
......
...@@ -25,6 +25,7 @@ typedef struct { /* file io buffer */ ...@@ -25,6 +25,7 @@ typedef struct { /* file io buffer */
} git_fbuffer; } git_fbuffer;
extern int git_futils_readbuffer(git_fbuffer *obj, const char *path); extern int git_futils_readbuffer(git_fbuffer *obj, const char *path);
extern int git_futils_readbuffer_updated(git_fbuffer *obj, const char *path, time_t *mtime, int *updated);
extern void git_futils_freebuffer(git_fbuffer *obj); extern void git_futils_freebuffer(git_fbuffer *obj);
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment