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")) &&