mirror of
https://git.proxmox.com/git/libgit2
synced 2026-01-26 21:14:09 +00:00
odb: only freshen pack files every 2 seconds
Since writing multiple objects may all already exist in a single packfile, avoid freshening that packfile repeatedly in a tight loop. Instead, only freshen pack files every 2 seconds.
This commit is contained in:
parent
8f09a98e18
commit
27051d4e31
@ -837,16 +837,13 @@ int git_futils_cp(const char *from, const char *to, mode_t filemode)
|
||||
return cp_by_fd(ifd, ofd, true);
|
||||
}
|
||||
|
||||
int git_futils_touch(const char *path)
|
||||
int git_futils_touch(const char *path, time_t *when)
|
||||
{
|
||||
struct p_timeval times[2];
|
||||
time_t now = time(NULL);
|
||||
int ret;
|
||||
|
||||
times[0].tv_sec = now;
|
||||
times[0].tv_usec = 0;
|
||||
times[1].tv_sec = now;
|
||||
times[1].tv_usec = 0;
|
||||
times[0].tv_sec = times[1].tv_sec = when ? *when : time(NULL);
|
||||
times[0].tv_usec = times[1].tv_usec = 0;
|
||||
|
||||
ret = p_utimes(path, times);
|
||||
|
||||
|
||||
@ -185,9 +185,10 @@ extern int git_futils_cp(
|
||||
mode_t filemode);
|
||||
|
||||
/**
|
||||
* Set the files atime and mtime to the current time.
|
||||
* Set the files atime and mtime to the given time, or the current time
|
||||
* if `ts` is NULL.
|
||||
*/
|
||||
extern int git_futils_touch(const char *path);
|
||||
extern int git_futils_touch(const char *path, time_t *when);
|
||||
|
||||
/**
|
||||
* Flags that can be passed to `git_futils_cp_r`.
|
||||
|
||||
@ -929,7 +929,7 @@ static int loose_backend__freshen(
|
||||
if (object_file_name(&path, backend, oid) < 0)
|
||||
return -1;
|
||||
|
||||
error = git_futils_touch(path.ptr);
|
||||
error = git_futils_touch(path.ptr, NULL);
|
||||
git_buf_free(&path);
|
||||
|
||||
return error;
|
||||
|
||||
@ -20,6 +20,9 @@
|
||||
|
||||
#include "git2/odb_backend.h"
|
||||
|
||||
/* re-freshen pack files no more than every 2 seconds */
|
||||
#define FRESHEN_FREQUENCY 2
|
||||
|
||||
struct pack_backend {
|
||||
git_odb_backend parent;
|
||||
git_vector packs;
|
||||
@ -367,12 +370,22 @@ static int pack_backend__freshen(
|
||||
git_odb_backend *backend, const git_oid *oid)
|
||||
{
|
||||
struct git_pack_entry e;
|
||||
time_t now;
|
||||
int error;
|
||||
|
||||
if ((error = pack_entry_find(&e, (struct pack_backend *)backend, oid)) < 0)
|
||||
return error;
|
||||
|
||||
return git_futils_touch(e.p->pack_name);
|
||||
now = time(NULL);
|
||||
|
||||
if (e.p->last_freshen > now - FRESHEN_FREQUENCY)
|
||||
return 0;
|
||||
|
||||
if ((error = git_futils_touch(e.p->pack_name, &now)) < 0)
|
||||
return error;
|
||||
|
||||
e.p->last_freshen = now;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pack_backend__read(
|
||||
|
||||
@ -102,6 +102,8 @@ struct git_pack_file {
|
||||
|
||||
git_pack_cache bases; /* delta base cache */
|
||||
|
||||
time_t last_freshen; /* last time the packfile was freshened */
|
||||
|
||||
/* something like ".git/objects/pack/xxxxx.pack" */
|
||||
char pack_name[GIT_FLEX_ARRAY]; /* more */
|
||||
};
|
||||
|
||||
@ -68,6 +68,7 @@ void test_odb_freshen__packed_object(void)
|
||||
cl_must_pass(p_utimes("testrepo.git/objects/pack/" PACKED_FN, old_times));
|
||||
cl_must_pass(p_lstat("testrepo.git/objects/pack/" PACKED_FN, &before));
|
||||
|
||||
/* ensure that packfile is freshened */
|
||||
cl_git_pass(git_odb_write(&id, odb, PACKED_STR,
|
||||
CONST_STRLEN(PACKED_STR), GIT_OBJ_BLOB));
|
||||
cl_assert_equal_oid(&expected_id, &id);
|
||||
@ -75,5 +76,18 @@ void test_odb_freshen__packed_object(void)
|
||||
|
||||
cl_assert(before.st_atime < after.st_atime);
|
||||
cl_assert(before.st_mtime < after.st_mtime);
|
||||
|
||||
memcpy(&before, &after, sizeof(struct stat));
|
||||
|
||||
/* ensure that the pack file is not freshened again immediately */
|
||||
cl_git_pass(git_odb_write(&id, odb, PACKED_STR,
|
||||
CONST_STRLEN(PACKED_STR), GIT_OBJ_BLOB));
|
||||
cl_assert_equal_oid(&expected_id, &id);
|
||||
cl_must_pass(p_lstat("testrepo.git/objects/pack/" PACKED_FN, &after));
|
||||
|
||||
cl_assert(before.st_atime == after.st_atime);
|
||||
cl_assert(before.st_atime_nsec == after.st_atime_nsec);
|
||||
cl_assert(before.st_mtime == after.st_mtime);
|
||||
cl_assert(before.st_mtime_nsec == after.st_mtime_nsec);
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user