Commit 2638a03a by Vicent Marti

This refs iterator pleases the gods.

parent 9007c53f
...@@ -29,7 +29,8 @@ GIT__USE_STRMAP; ...@@ -29,7 +29,8 @@ GIT__USE_STRMAP;
enum { enum {
PACKREF_HAS_PEEL = 1, PACKREF_HAS_PEEL = 1,
PACKREF_WAS_LOOSE = 2, PACKREF_WAS_LOOSE = 2,
PACKREF_CANNOT_PEEL = 4 PACKREF_CANNOT_PEEL = 4,
PACKREF_SHADOWED = 8,
}; };
enum { enum {
...@@ -552,27 +553,16 @@ static int refdb_fs_backend__lookup( ...@@ -552,27 +553,16 @@ static int refdb_fs_backend__lookup(
return result; return result;
} }
struct dirent_list_data {
refdb_fs_backend *backend;
size_t repo_path_len;
unsigned int list_type:2;
git_reference_foreach_cb callback;
void *callback_payload;
int callback_error;
};
typedef struct { typedef struct {
git_reference_iterator parent; git_reference_iterator parent;
unsigned int loose;
/* packed */ git_vector loose;
git_strmap *h; unsigned int loose_pos;
khiter_t k; khiter_t packed_pos;
/* loose */
git_iterator *fsiter;
git_buf buf;
} refdb_fs_iter; } refdb_fs_iter;
static int iter_load_loose_paths(refdb_fs_iter *iter);
static int refdb_fs_backend__iterator(git_reference_iterator **out, git_refdb_backend *_backend) static int refdb_fs_backend__iterator(git_reference_iterator **out, git_refdb_backend *_backend)
{ {
refdb_fs_iter *iter; refdb_fs_iter *iter;
...@@ -588,103 +578,104 @@ static int refdb_fs_backend__iterator(git_reference_iterator **out, git_refdb_ba ...@@ -588,103 +578,104 @@ static int refdb_fs_backend__iterator(git_reference_iterator **out, git_refdb_ba
GITERR_CHECK_ALLOC(iter); GITERR_CHECK_ALLOC(iter);
iter->parent.backend = _backend; iter->parent.backend = _backend;
iter->h = backend->refcache.packfile; iter_load_loose_paths(iter);
iter->k = kh_begin(backend->refcache.packfile);
*out = (git_reference_iterator *)iter; *out = (git_reference_iterator *)iter;
return 0; return 0;
} }
static void refdb_fs_backend__iterator_free(git_reference_iterator *_iter) static void refdb_fs_backend__iterator_free(git_reference_iterator *_iter)
{ {
refdb_fs_iter *iter = (refdb_fs_iter *) _iter; refdb_fs_iter *iter = (refdb_fs_iter *) _iter;
char *loose_path;
size_t i;
git_buf_free(&iter->buf); git_vector_foreach(&iter->loose, i, loose_path) {
git_iterator_free(iter->fsiter); free(loose_path);
git__free(iter);
}
static int iter_packed(const char **out, refdb_fs_iter *iter)
{
/* Move forward to the next entry */
while (!kh_exist(iter->h, iter->k)) {
iter->k++;
if (iter->k == kh_end(iter->h))
return GIT_ITEROVER;
} }
*out = kh_key(iter->h, iter->k); git_vector_free(&iter->loose);
iter->k++; git__free(iter);
return 0;
} }
static int iter_loose(const char **out, refdb_fs_iter *iter) static int iter_load_loose_paths(refdb_fs_iter *iter)
{ {
const git_index_entry *entry;
int retry;
git_strmap *packfile_refs;
refdb_fs_backend *backend = (refdb_fs_backend *) iter->parent.backend; refdb_fs_backend *backend = (refdb_fs_backend *) iter->parent.backend;
git_strmap *packfile = backend->refcache.packfile;
packfile_refs = backend->refcache.packfile; git_buf path = GIT_BUF_INIT;
git_iterator *fsit;
const git_index_entry *entry = NULL;
do { if (git_buf_printf(&path, "%s/refs", backend->path) < 0)
khiter_t pos;
if (git_iterator_current(&entry, iter->fsiter) < 0)
return -1; return -1;
git_buf_clear(&iter->buf); if (git_iterator_for_filesystem(&fsit, git_buf_cstr(&path), 0, NULL, NULL) < 0)
if (!entry)
return GIT_ITEROVER;
if (git_buf_printf(&iter->buf, "refs/%s", entry->path) < 0)
return -1; return -1;
git_iterator_advance(NULL, iter->fsiter); git_vector_init(&iter->loose, 8, NULL);
git_buf_sets(&path, GIT_REFS_DIR);
/* Skip this one if we already listed it in packed */ while (!git_iterator_current(&entry, fsit) && entry) {
pos = git_strmap_lookup_index(packfile_refs, git_buf_cstr(&iter->buf)); const char *ref_name;
retry = 0; khiter_t pos;
if (git_strmap_valid_index(packfile_refs, pos) ||
!git_reference_is_valid_name(git_buf_cstr(&iter->buf)))
retry = 1;
*out = git_buf_cstr(&iter->buf); git_buf_truncate(&path, strlen(GIT_REFS_DIR));
} while (retry); git_buf_puts(&path, entry->path);
ref_name = git_buf_cstr(&path);
return 0; if (git__suffixcmp(ref_name, ".lock") == 0) {
} git_iterator_advance(NULL, fsit);
continue;
}
static int iter_loose_setup(refdb_fs_iter *iter) pos = git_strmap_lookup_index(packfile, ref_name);
{ if (git_strmap_valid_index(packfile, pos)) {
refdb_fs_backend *backend = (refdb_fs_backend *) iter->parent.backend; struct packref *ref = git_strmap_value_at(packfile, pos);
ref->flags |= PACKREF_SHADOWED;
}
git_buf_clear(&iter->buf); git_vector_insert(&iter->loose, git__strdup(ref_name));
if (git_buf_printf(&iter->buf, "%s/refs", backend->path) < 0) git_iterator_advance(NULL, fsit);
return -1; }
git_iterator_free(fsit);
git_buf_free(&path);
return git_iterator_for_filesystem(&iter->fsiter, git_buf_cstr(&iter->buf), 0, NULL, NULL); return 0;
} }
static int refdb_fs_backend__next(const char **out, git_reference_iterator *_iter) static int refdb_fs_backend__next(const char **out, git_reference_iterator *_iter)
{ {
refdb_fs_iter *iter = (refdb_fs_iter *)_iter; refdb_fs_iter *iter = (refdb_fs_iter *)_iter;
refdb_fs_backend *backend = (refdb_fs_backend *) iter->parent.backend;
git_strmap *packfile = backend->refcache.packfile;
if (iter->loose) if (iter->loose_pos < iter->loose.length) {
return iter_loose(out, iter); const char *path = git_vector_get(&iter->loose, iter->loose_pos++);
*out = path;
return 0;
}
if (iter->k != kh_end(iter->h)) { if (iter->packed_pos < kh_end(packfile)) {
int error = iter_packed(out, iter); struct packref *ref = NULL;
if (error != GIT_ITEROVER)
return error; do {
while (!kh_exist(packfile, iter->packed_pos)) {
iter->packed_pos++;
if (iter->packed_pos == kh_end(packfile))
return GIT_ITEROVER;
} }
if (iter_loose_setup(iter) < 0) ref = kh_val(packfile, iter->packed_pos);
return -1; iter->packed_pos++;
iter->loose = 1; } while (ref->flags & PACKREF_SHADOWED);
*out = ref->name;
return 0;
}
return iter_loose(out, iter); return GIT_ITEROVER;
} }
static int loose_write(refdb_fs_backend *backend, const git_reference *ref) static int loose_write(refdb_fs_backend *backend, const git_reference *ref)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment