diff options
author | Vicent Marti <tanoku@gmail.com> | 2013-01-03 23:36:26 +0400 |
---|---|---|
committer | Vicent Marti <tanoku@gmail.com> | 2013-01-10 18:34:56 +0400 |
commit | 4a863c06662053a8530a0dcb24e0a2daa33e05cf (patch) | |
tree | 7cf411ca542687c7bda92d17809be88efd28a2e7 /src/odb_pack.c | |
parent | a22ad9fd1f1f938fb9b8ac77939dda8a3b81a00e (diff) |
Sane refresh logic
All the ODB backends have a specific refresh interface. When reading an
object, first we attempt every single backend: if the read fails, then
we refresh all the backends and retry the read one more time to see if
the object has appeared.
Diffstat (limited to 'src/odb_pack.c')
-rw-r--r-- | src/odb_pack.c | 75 |
1 files changed, 32 insertions, 43 deletions
diff --git a/src/odb_pack.c b/src/odb_pack.c index 0cdf552a0..e1b44d9ca 100644 --- a/src/odb_pack.c +++ b/src/odb_pack.c @@ -138,7 +138,6 @@ static int pack_window_contains(git_mwindow *win, off_t offset); static int packfile_sort__cb(const void *a_, const void *b_); static int packfile_load__cb(void *_data, git_buf *path); -static int packfile_refresh_all(struct pack_backend *backend); static int pack_entry_find(struct git_pack_entry *e, struct pack_backend *backend, const git_oid *oid); @@ -237,33 +236,6 @@ static int packfile_load__cb(void *_data, git_buf *path) return git_vector_insert(&backend->packs, pack); } -static int packfile_refresh_all(struct pack_backend *backend) -{ - int error; - struct stat st; - git_buf path = GIT_BUF_INIT; - - if (backend->pack_folder == NULL) - return 0; - - if (p_stat(backend->pack_folder, &st) < 0 || !S_ISDIR(st.st_mode)) - return git_odb__error_notfound("failed to refresh packfiles", NULL); - - git_buf_sets(&path, backend->pack_folder); - - /* reload all packs */ - error = git_path_direach(&path, packfile_load__cb, (void *)backend); - - git_buf_free(&path); - - if (error < 0) - return error; - - git_vector_sort(&backend->packs); - - return 0; -} - static int pack_entry_find_inner( struct git_pack_entry *e, struct pack_backend *backend, @@ -294,7 +266,6 @@ static int pack_entry_find_inner( static int pack_entry_find(struct git_pack_entry *e, struct pack_backend *backend, const git_oid *oid) { - int error; struct git_pack_file *last_found = backend->last_found; if (backend->last_found && @@ -303,10 +274,6 @@ static int pack_entry_find(struct git_pack_entry *e, struct pack_backend *backen if (!pack_entry_find_inner(e, backend, oid, last_found)) return 0; - if ((error = packfile_refresh_all(backend)) < 0) - return error; - if (!pack_entry_find_inner(e, backend, oid, last_found)) - return 0; return git_odb__error_notfound("failed to find pack entry", oid); } @@ -356,17 +323,9 @@ static int pack_entry_find_prefix( const git_oid *short_oid, size_t len) { - unsigned found = 0; - int error; struct git_pack_file *last_found = backend->last_found; + unsigned int found = pack_entry_find_prefix_inner(e, backend, short_oid, len, last_found); - if ((found = pack_entry_find_prefix_inner(e, backend, short_oid, len, last_found)) > 0) - goto cleanup; - if ((error = packfile_refresh_all(backend)) < 0) - return error; - found = pack_entry_find_prefix_inner(e, backend, short_oid, len, last_found); - -cleanup: if (!found) return git_odb__error_notfound("no matching pack entry for prefix", short_oid); else if (found > 1) @@ -383,6 +342,34 @@ cleanup: * Implement the git_odb_backend API calls * ***********************************************************/ +static int pack_backend__refresh(git_odb_backend *_backend) +{ + struct pack_backend *backend = (struct pack_backend *)_backend; + + int error; + struct stat st; + git_buf path = GIT_BUF_INIT; + + if (backend->pack_folder == NULL) + return 0; + + if (p_stat(backend->pack_folder, &st) < 0 || !S_ISDIR(st.st_mode)) + return git_odb__error_notfound("failed to refresh packfiles", NULL); + + git_buf_sets(&path, backend->pack_folder); + + /* reload all packs */ + error = git_path_direach(&path, packfile_load__cb, (void *)backend); + + git_buf_free(&path); + + if (error < 0) + return error; + + git_vector_sort(&backend->packs); + return 0; +} + static int pack_backend__read_header(size_t *len_p, git_otype *type_p, struct git_odb_backend *backend, const git_oid *oid) { @@ -468,7 +455,7 @@ static int pack_backend__foreach(git_odb_backend *_backend, git_odb_foreach_cb c backend = (struct pack_backend *)_backend; /* Make sure we know about the packfiles */ - if ((error = packfile_refresh_all(backend)) < 0) + if ((error = pack_backend__refresh(_backend)) < 0) return error; git_vector_foreach(&backend->packs, i, p) { @@ -581,6 +568,7 @@ int git_odb_backend_one_pack(git_odb_backend **backend_out, const char *idx) backend->parent.read_prefix = &pack_backend__read_prefix; backend->parent.read_header = &pack_backend__read_header; backend->parent.exists = &pack_backend__exists; + backend->parent.refresh = &pack_backend__refresh; backend->parent.foreach = &pack_backend__foreach; backend->parent.free = &pack_backend__free; @@ -619,6 +607,7 @@ int git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir) backend->parent.read_prefix = &pack_backend__read_prefix; backend->parent.read_header = &pack_backend__read_header; backend->parent.exists = &pack_backend__exists; + backend->parent.refresh = &pack_backend__refresh; backend->parent.foreach = &pack_backend__foreach; backend->parent.writepack = &pack_backend__writepack; backend->parent.free = &pack_backend__free; |