vendor/libgit2/src/odb_pack.c in rugged-0.19.0 vs vendor/libgit2/src/odb_pack.c in rugged-0.21.0
- old
+ new
@@ -27,11 +27,11 @@
char *pack_folder;
};
struct pack_writepack {
struct git_odb_writepack parent;
- git_indexer_stream *indexer_stream;
+ git_indexer *indexer;
};
/**
* The wonderful tale of a Packed Object lookup query
* ===================================================
@@ -188,35 +188,43 @@
return -1;
}
-
-static int packfile_load__cb(void *_data, git_buf *path)
+static int packfile_load__cb(void *data, git_buf *path)
{
- struct pack_backend *backend = (struct pack_backend *)_data;
+ struct pack_backend *backend = data;
struct git_pack_file *pack;
+ const char *path_str = git_buf_cstr(path);
+ size_t i, cmp_len = git_buf_len(path);
int error;
- size_t i;
- if (git__suffixcmp(path->ptr, ".idx") != 0)
+ if (cmp_len <= strlen(".idx") || git__suffixcmp(path_str, ".idx") != 0)
return 0; /* not an index */
+ cmp_len -= strlen(".idx");
+
for (i = 0; i < backend->packs.length; ++i) {
struct git_pack_file *p = git_vector_get(&backend->packs, i);
- if (memcmp(p->pack_name, git_buf_cstr(path), git_buf_len(path) - strlen(".idx")) == 0)
+
+ if (memcmp(p->pack_name, path_str, cmp_len) == 0)
return 0;
}
- error = git_packfile_alloc(&pack, path->ptr);
- if (error == GIT_ENOTFOUND)
- /* ignore missing .pack file as git does */
+ error = git_mwindow_get_pack(&pack, path->ptr);
+
+ /* ignore missing .pack file as git does */
+ if (error == GIT_ENOTFOUND) {
+ giterr_clear();
return 0;
- else if (error < 0)
- return error;
+ }
- return git_vector_insert(&backend->packs, pack);
+ if (!error)
+ error = git_vector_insert(&backend->packs, pack);
+
+ return error;
+
}
static int pack_entry_find_inner(
struct git_pack_entry *e,
struct pack_backend *backend,
@@ -257,27 +265,30 @@
return 0;
return git_odb__error_notfound("failed to find pack entry", oid);
}
-static unsigned pack_entry_find_prefix_inner(
- struct git_pack_entry *e,
- struct pack_backend *backend,
- const git_oid *short_oid,
- size_t len,
- struct git_pack_file *last_found)
+static int pack_entry_find_prefix(
+ struct git_pack_entry *e,
+ struct pack_backend *backend,
+ const git_oid *short_oid,
+ size_t len)
{
int error;
size_t i;
- unsigned found = 0;
+ git_oid found_full_oid = {{0}};
+ bool found = false;
+ struct git_pack_file *last_found = backend->last_found;
if (last_found) {
error = git_pack_entry_find(e, last_found, short_oid, len);
if (error == GIT_EAMBIGUOUS)
return error;
- if (!error)
- found = 1;
+ if (!error) {
+ git_oid_cpy(&found_full_oid, &e->sha1);
+ found = true;
+ }
}
for (i = 0; i < backend->packs.length; ++i) {
struct git_pack_file *p;
@@ -287,32 +298,20 @@
error = git_pack_entry_find(e, p, short_oid, len);
if (error == GIT_EAMBIGUOUS)
return error;
if (!error) {
- if (++found > 1)
- break;
+ if (found && git_oid_cmp(&e->sha1, &found_full_oid))
+ return git_odb__error_ambiguous("found multiple pack entries");
+ git_oid_cpy(&found_full_oid, &e->sha1);
+ found = true;
backend->last_found = p;
}
}
- return found;
-}
-
-static int pack_entry_find_prefix(
- struct git_pack_entry *e,
- struct pack_backend *backend,
- const git_oid *short_oid,
- size_t len)
-{
- 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)
return git_odb__error_notfound("no matching pack entry for prefix", short_oid);
- else if (found > 1)
- return git_odb__error_ambiguous("found multiple pack entries");
else
return 0;
}
@@ -321,40 +320,37 @@
* PACKED BACKEND PUBLIC API
*
* Implement the git_odb_backend API calls
*
***********************************************************/
-static int pack_backend__refresh(git_odb_backend *_backend)
+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;
+ struct pack_backend *backend = (struct pack_backend *)backend_;
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);
+ error = git_path_direach(&path, 0, packfile_load__cb, backend);
git_buf_free(&path);
-
- if (error < 0)
- return error;
-
git_vector_sort(&backend->packs);
- return 0;
+
+ return error;
}
-
-static int pack_backend__read_header(size_t *len_p, git_otype *type_p, struct git_odb_backend *backend, const git_oid *oid)
+static int pack_backend__read_header_internal(
+ size_t *len_p, git_otype *type_p,
+ struct git_odb_backend *backend, const git_oid *oid)
{
struct git_pack_entry e;
int error;
assert(len_p && type_p && backend && oid);
@@ -363,12 +359,31 @@
return error;
return git_packfile_resolve_header(len_p, type_p, e.p, e.offset);
}
-static int pack_backend__read(void **buffer_p, size_t *len_p, git_otype *type_p, git_odb_backend *backend, const git_oid *oid)
+static int pack_backend__read_header(
+ size_t *len_p, git_otype *type_p,
+ struct git_odb_backend *backend, const git_oid *oid)
{
+ int error;
+
+ error = pack_backend__read_header_internal(len_p, type_p, backend, oid);
+
+ if (error != GIT_ENOTFOUND)
+ return error;
+
+ if ((error = pack_backend__refresh(backend)) < 0)
+ return error;
+
+ return pack_backend__read_header_internal(len_p, type_p, backend, oid);
+}
+
+static int pack_backend__read_internal(
+ void **buffer_p, size_t *len_p, git_otype *type_p,
+ git_odb_backend *backend, const git_oid *oid)
+{
struct git_pack_entry e;
git_rawobj raw;
int error;
if ((error = pack_entry_find(&e, (struct pack_backend *)backend, oid)) < 0 ||
@@ -380,11 +395,28 @@
*type_p = raw.type;
return 0;
}
-static int pack_backend__read_prefix(
+static int pack_backend__read(
+ void **buffer_p, size_t *len_p, git_otype *type_p,
+ git_odb_backend *backend, const git_oid *oid)
+{
+ int error;
+
+ error = pack_backend__read_internal(buffer_p, len_p, type_p, backend, oid);
+
+ if (error != GIT_ENOTFOUND)
+ return error;
+
+ if ((error = pack_backend__refresh(backend)) < 0)
+ return error;
+
+ return pack_backend__read_internal(buffer_p, len_p, type_p, backend, oid);
+}
+
+static int pack_backend__read_prefix_internal(
git_oid *out_oid,
void **buffer_p,
size_t *len_p,
git_otype *type_p,
git_odb_backend *backend,
@@ -417,16 +449,69 @@
}
return error;
}
+static int pack_backend__read_prefix(
+ git_oid *out_oid,
+ void **buffer_p,
+ size_t *len_p,
+ git_otype *type_p,
+ git_odb_backend *backend,
+ const git_oid *short_oid,
+ size_t len)
+{
+ int error;
+
+ error = pack_backend__read_prefix_internal(
+ out_oid, buffer_p, len_p, type_p, backend, short_oid, len);
+
+ if (error != GIT_ENOTFOUND)
+ return error;
+
+ if ((error = pack_backend__refresh(backend)) < 0)
+ return error;
+
+ return pack_backend__read_prefix_internal(
+ out_oid, buffer_p, len_p, type_p, backend, short_oid, len);
+}
+
static int pack_backend__exists(git_odb_backend *backend, const git_oid *oid)
{
struct git_pack_entry e;
+ int error;
+
+ error = pack_entry_find(&e, (struct pack_backend *)backend, oid);
+
+ if (error != GIT_ENOTFOUND)
+ return error == 0;
+
+ if ((error = pack_backend__refresh(backend)) < 0) {
+ giterr_clear();
+ return (int)false;
+ }
+
return pack_entry_find(&e, (struct pack_backend *)backend, oid) == 0;
}
+static int pack_backend__exists_prefix(
+ git_oid *out, git_odb_backend *backend, const git_oid *short_id, size_t len)
+{
+ int error;
+ struct pack_backend *pb = (struct pack_backend *)backend;
+ struct git_pack_entry e = {0};
+
+ error = pack_entry_find_prefix(&e, pb, short_id, len);
+
+ if (error == GIT_ENOTFOUND && !(error = pack_backend__refresh(backend)))
+ error = pack_entry_find_prefix(&e, pb, short_id, len);
+
+ git_oid_cpy(out, &e.sha1);
+
+ return error;
+}
+
static int pack_backend__foreach(git_odb_backend *_backend, git_odb_foreach_cb cb, void *data)
{
int error;
struct git_pack_file *p;
struct pack_backend *backend;
@@ -445,41 +530,42 @@
}
return 0;
}
-static int pack_backend__writepack_add(struct git_odb_writepack *_writepack, const void *data, size_t size, git_transfer_progress *stats)
+static int pack_backend__writepack_append(struct git_odb_writepack *_writepack, const void *data, size_t size, git_transfer_progress *stats)
{
struct pack_writepack *writepack = (struct pack_writepack *)_writepack;
assert(writepack);
- return git_indexer_stream_add(writepack->indexer_stream, data, size, stats);
+ return git_indexer_append(writepack->indexer, data, size, stats);
}
static int pack_backend__writepack_commit(struct git_odb_writepack *_writepack, git_transfer_progress *stats)
{
struct pack_writepack *writepack = (struct pack_writepack *)_writepack;
assert(writepack);
- return git_indexer_stream_finalize(writepack->indexer_stream, stats);
+ return git_indexer_commit(writepack->indexer, stats);
}
static void pack_backend__writepack_free(struct git_odb_writepack *_writepack)
{
struct pack_writepack *writepack = (struct pack_writepack *)_writepack;
assert(writepack);
- git_indexer_stream_free(writepack->indexer_stream);
+ git_indexer_free(writepack->indexer);
git__free(writepack);
}
static int pack_backend__writepack(struct git_odb_writepack **out,
git_odb_backend *_backend,
- git_transfer_progress_callback progress_cb,
+ git_odb *odb,
+ git_transfer_progress_cb progress_cb,
void *progress_payload)
{
struct pack_backend *backend;
struct pack_writepack *writepack;
@@ -490,18 +576,18 @@
backend = (struct pack_backend *)_backend;
writepack = git__calloc(1, sizeof(struct pack_writepack));
GITERR_CHECK_ALLOC(writepack);
- if (git_indexer_stream_new(&writepack->indexer_stream,
- backend->pack_folder, progress_cb, progress_payload) < 0) {
+ if (git_indexer_new(&writepack->indexer,
+ backend->pack_folder, 0, odb, progress_cb, progress_payload) < 0) {
git__free(writepack);
return -1;
}
writepack->parent.backend = _backend;
- writepack->parent.add = pack_backend__writepack_add;
+ writepack->parent.append = pack_backend__writepack_append;
writepack->parent.commit = pack_backend__writepack_commit;
writepack->parent.free = pack_backend__writepack_free;
*out = (git_odb_writepack *)writepack;
@@ -517,11 +603,11 @@
backend = (struct pack_backend *)_backend;
for (i = 0; i < backend->packs.length; ++i) {
struct git_pack_file *p = git_vector_get(&backend->packs, i);
- git_packfile_free(p);
+ git_mwindow_put_pack(p);
}
git_vector_free(&backend->packs);
git__free(backend->pack_folder);
git__free(backend);
@@ -541,10 +627,11 @@
backend->parent.read = &pack_backend__read;
backend->parent.read_prefix = &pack_backend__read_prefix;
backend->parent.read_header = &pack_backend__read_header;
backend->parent.exists = &pack_backend__exists;
+ backend->parent.exists_prefix = &pack_backend__exists_prefix;
backend->parent.refresh = &pack_backend__refresh;
backend->parent.foreach = &pack_backend__foreach;
backend->parent.writepack = &pack_backend__writepack;
backend->parent.free = &pack_backend__free;
@@ -558,11 +645,11 @@
struct git_pack_file *packfile = NULL;
if (pack_backend__alloc(&backend, 1) < 0)
return -1;
- if (git_packfile_alloc(&packfile, idx) < 0 ||
+ if (git_mwindow_get_pack(&packfile, idx) < 0 ||
git_vector_insert(&backend->packs, packfile) < 0)
{
pack_backend__free((git_odb_backend *)backend);
return -1;
}
@@ -574,9 +661,12 @@
int git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir)
{
int error = 0;
struct pack_backend *backend = NULL;
git_buf path = GIT_BUF_INIT;
+
+ if (git_mwindow_files_init() < 0)
+ return -1;
if (pack_backend__alloc(&backend, 8) < 0)
return -1;
if (!(error = git_buf_joinpath(&path, objects_dir, "pack")) &&