mirror of
https://git.proxmox.com/git/libgit2
synced 2025-07-05 23:46:17 +00:00
Add index snapshot and use it for iterator
This commit is contained in:
parent
27e54bcf82
commit
54edbb9871
42
src/index.c
42
src/index.c
@ -1056,21 +1056,26 @@ int git_index_remove_directory(git_index *index, const char *dir, int stage)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int git_index__find(
|
int git_index__find_in_entries(
|
||||||
size_t *out, git_index *index, const char *path, size_t path_len, int stage)
|
size_t *out, git_vector *entries, git_vector_cmp entry_cmp,
|
||||||
|
const char *path, size_t path_len, int stage)
|
||||||
{
|
{
|
||||||
struct entry_srch_key srch_key;
|
struct entry_srch_key srch_key;
|
||||||
|
|
||||||
assert(path);
|
|
||||||
|
|
||||||
git_vector_sort(&index->entries);
|
|
||||||
|
|
||||||
srch_key.path = path;
|
srch_key.path = path;
|
||||||
srch_key.path_len = !path_len ? strlen(path) : path_len;
|
srch_key.path_len = !path_len ? strlen(path) : path_len;
|
||||||
srch_key.stage = stage;
|
srch_key.stage = stage;
|
||||||
|
return git_vector_bsearch2(out, entries, entry_cmp, &srch_key);
|
||||||
|
}
|
||||||
|
|
||||||
return git_vector_bsearch2(
|
int git_index__find(
|
||||||
out, &index->entries, index->entries_search, &srch_key);
|
size_t *out, git_index *index, const char *path, size_t path_len, int stage)
|
||||||
|
{
|
||||||
|
assert(index && path);
|
||||||
|
|
||||||
|
git_vector_sort(&index->entries);
|
||||||
|
|
||||||
|
return git_index__find_in_entries(
|
||||||
|
out, &index->entries, index->entries_search, path, path_len, stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
int git_index_find(size_t *at_pos, git_index *index, const char *path)
|
int git_index_find(size_t *at_pos, git_index *index, const char *path)
|
||||||
@ -2442,3 +2447,22 @@ int git_index_update_all(
|
|||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int git_index__snapshot(git_vector *entries, git_index *index)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
|
||||||
|
GIT_REFCOUNT_INC(index);
|
||||||
|
git_vector_sort(&index->entries);
|
||||||
|
error = git_vector_dup(entries, &index->entries, index->entries._cmp);
|
||||||
|
|
||||||
|
if (error < 0)
|
||||||
|
git_index_free(index);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
void git_index__release_snapshot(git_index *index)
|
||||||
|
{
|
||||||
|
git_index_free(index);
|
||||||
|
}
|
||||||
|
12
src/index.h
12
src/index.h
@ -71,4 +71,16 @@ GIT_INLINE(const git_futils_filestamp *) git_index__filestamp(git_index *index)
|
|||||||
|
|
||||||
extern int git_index__changed_relative_to(git_index *index, const git_futils_filestamp *fs);
|
extern int git_index__changed_relative_to(git_index *index, const git_futils_filestamp *fs);
|
||||||
|
|
||||||
|
/* Copy the current entries vector *and* increment the index refcount.
|
||||||
|
* Call `git_index__release_snapshot` when done.
|
||||||
|
*/
|
||||||
|
extern int git_index__snapshot(git_vector *entries, git_index *index);
|
||||||
|
extern void git_index__release_snapshot(git_index *index);
|
||||||
|
|
||||||
|
/* Allow searching in a snapshot; entries must already be sorted! */
|
||||||
|
extern int git_index__find_in_entries(
|
||||||
|
size_t *at_pos,
|
||||||
|
git_vector *entries, git_vector_cmp entry_cmp,
|
||||||
|
const char *path, size_t path_len, int stage);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -644,6 +644,8 @@ typedef struct {
|
|||||||
git_iterator base;
|
git_iterator base;
|
||||||
git_iterator_callbacks cb;
|
git_iterator_callbacks cb;
|
||||||
git_index *index;
|
git_index *index;
|
||||||
|
git_vector entries;
|
||||||
|
git_vector_cmp entry_srch;
|
||||||
size_t current;
|
size_t current;
|
||||||
/* when not in autoexpand mode, use these to represent "tree" state */
|
/* when not in autoexpand mode, use these to represent "tree" state */
|
||||||
git_buf partial;
|
git_buf partial;
|
||||||
@ -654,10 +656,10 @@ typedef struct {
|
|||||||
|
|
||||||
static const git_index_entry *index_iterator__index_entry(index_iterator *ii)
|
static const git_index_entry *index_iterator__index_entry(index_iterator *ii)
|
||||||
{
|
{
|
||||||
const git_index_entry *ie = git_index_get_byindex(ii->index, ii->current);
|
const git_index_entry *ie = git_vector_get(&ii->entries, ii->current);
|
||||||
|
|
||||||
if (ie != NULL && iterator__past_end(ii, ie->path)) {
|
if (ie != NULL && iterator__past_end(ii, ie->path)) {
|
||||||
ii->current = git_index_entrycount(ii->index);
|
ii->current = git_vector_length(&ii->entries);
|
||||||
ie = NULL;
|
ie = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -726,7 +728,7 @@ static int index_iterator__current(
|
|||||||
const git_index_entry **entry, git_iterator *self)
|
const git_index_entry **entry, git_iterator *self)
|
||||||
{
|
{
|
||||||
index_iterator *ii = (index_iterator *)self;
|
index_iterator *ii = (index_iterator *)self;
|
||||||
const git_index_entry *ie = git_index_get_byindex(ii->index, ii->current);
|
const git_index_entry *ie = git_vector_get(&ii->entries, ii->current);
|
||||||
|
|
||||||
if (ie != NULL && index_iterator__at_tree(ii)) {
|
if (ie != NULL && index_iterator__at_tree(ii)) {
|
||||||
ii->tree_entry.path = ii->partial.ptr;
|
ii->tree_entry.path = ii->partial.ptr;
|
||||||
@ -744,14 +746,14 @@ static int index_iterator__current(
|
|||||||
static int index_iterator__at_end(git_iterator *self)
|
static int index_iterator__at_end(git_iterator *self)
|
||||||
{
|
{
|
||||||
index_iterator *ii = (index_iterator *)self;
|
index_iterator *ii = (index_iterator *)self;
|
||||||
return (ii->current >= git_index_entrycount(ii->index));
|
return (ii->current >= git_vector_length(&ii->entries));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int index_iterator__advance(
|
static int index_iterator__advance(
|
||||||
const git_index_entry **entry, git_iterator *self)
|
const git_index_entry **entry, git_iterator *self)
|
||||||
{
|
{
|
||||||
index_iterator *ii = (index_iterator *)self;
|
index_iterator *ii = (index_iterator *)self;
|
||||||
size_t entrycount = git_index_entrycount(ii->index);
|
size_t entrycount = git_vector_length(&ii->entries);
|
||||||
const git_index_entry *ie;
|
const git_index_entry *ie;
|
||||||
|
|
||||||
if (!iterator__has_been_accessed(ii))
|
if (!iterator__has_been_accessed(ii))
|
||||||
@ -766,7 +768,7 @@ static int index_iterator__advance(
|
|||||||
while (ii->current < entrycount) {
|
while (ii->current < entrycount) {
|
||||||
ii->current++;
|
ii->current++;
|
||||||
|
|
||||||
if (!(ie = git_index_get_byindex(ii->index, ii->current)) ||
|
if (!(ie = git_vector_get(&ii->entries, ii->current)) ||
|
||||||
ii->base.prefixcomp(ie->path, ii->partial.ptr) != 0)
|
ii->base.prefixcomp(ie->path, ii->partial.ptr) != 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -789,7 +791,7 @@ static int index_iterator__advance_into(
|
|||||||
const git_index_entry **entry, git_iterator *self)
|
const git_index_entry **entry, git_iterator *self)
|
||||||
{
|
{
|
||||||
index_iterator *ii = (index_iterator *)self;
|
index_iterator *ii = (index_iterator *)self;
|
||||||
const git_index_entry *ie = git_index_get_byindex(ii->index, ii->current);
|
const git_index_entry *ie = git_vector_get(&ii->entries, ii->current);
|
||||||
|
|
||||||
if (ie != NULL && index_iterator__at_tree(ii)) {
|
if (ie != NULL && index_iterator__at_tree(ii)) {
|
||||||
if (ii->restore_terminator)
|
if (ii->restore_terminator)
|
||||||
@ -818,7 +820,8 @@ static int index_iterator__reset(
|
|||||||
ii->current = 0;
|
ii->current = 0;
|
||||||
|
|
||||||
if (ii->base.start)
|
if (ii->base.start)
|
||||||
git_index__find(&ii->current, ii->index, ii->base.start, 0, 0);
|
git_index__find_in_entries(
|
||||||
|
&ii->current, &ii->entries, ii->entry_srch, ii->base.start, 0, 0);
|
||||||
|
|
||||||
if ((ie = index_iterator__skip_conflicts(ii)) == NULL)
|
if ((ie = index_iterator__skip_conflicts(ii)) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
@ -843,9 +846,9 @@ static int index_iterator__reset(
|
|||||||
static void index_iterator__free(git_iterator *self)
|
static void index_iterator__free(git_iterator *self)
|
||||||
{
|
{
|
||||||
index_iterator *ii = (index_iterator *)self;
|
index_iterator *ii = (index_iterator *)self;
|
||||||
git_index_free(ii->index);
|
git_index__release_snapshot(ii->index);
|
||||||
ii->index = NULL;
|
ii->index = NULL;
|
||||||
|
git_vector_free(&ii->entries);
|
||||||
git_buf_free(&ii->partial);
|
git_buf_free(&ii->partial);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -856,9 +859,17 @@ int git_iterator_for_index(
|
|||||||
const char *start,
|
const char *start,
|
||||||
const char *end)
|
const char *end)
|
||||||
{
|
{
|
||||||
|
int error = 0;
|
||||||
index_iterator *ii = git__calloc(1, sizeof(index_iterator));
|
index_iterator *ii = git__calloc(1, sizeof(index_iterator));
|
||||||
GITERR_CHECK_ALLOC(ii);
|
GITERR_CHECK_ALLOC(ii);
|
||||||
|
|
||||||
|
if ((error = git_index__snapshot(&ii->entries, index)) < 0) {
|
||||||
|
git__free(ii);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
ii->index = index;
|
||||||
|
ii->entry_srch = index->entries_search;
|
||||||
|
|
||||||
ITERATOR_BASE_INIT(ii, index, INDEX, git_index_owner(index));
|
ITERATOR_BASE_INIT(ii, index, INDEX, git_index_owner(index));
|
||||||
|
|
||||||
if (index->ignore_case) {
|
if (index->ignore_case) {
|
||||||
@ -866,8 +877,7 @@ int git_iterator_for_index(
|
|||||||
ii->base.prefixcomp = git__prefixcmp_icase;
|
ii->base.prefixcomp = git__prefixcmp_icase;
|
||||||
}
|
}
|
||||||
|
|
||||||
ii->index = index;
|
/* TODO: resort entries to match desired ignore_case behavior */
|
||||||
GIT_REFCOUNT_INC(index);
|
|
||||||
|
|
||||||
git_buf_init(&ii->partial, 0);
|
git_buf_init(&ii->partial, 0);
|
||||||
ii->tree_entry.mode = GIT_FILEMODE_TREE;
|
ii->tree_entry.mode = GIT_FILEMODE_TREE;
|
||||||
@ -875,7 +885,6 @@ int git_iterator_for_index(
|
|||||||
index_iterator__reset((git_iterator *)ii, NULL, NULL);
|
index_iterator__reset((git_iterator *)ii, NULL, NULL);
|
||||||
|
|
||||||
*iter = (git_iterator *)ii;
|
*iter = (git_iterator *)ii;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user