Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2d945f8

Browse files
committed
refs: copy the packed refs on iteration
This lets us work without worrying about what's happening but work on a snapshot.
1 parent 4ee2543 commit 2d945f8

File tree

1 file changed

+16
-8
lines changed

1 file changed

+16
-8
lines changed

src/refdb_fs.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,7 @@ typedef struct {
458458
git_pool pool;
459459
git_vector loose;
460460

461+
git_sortedcache *cache;
461462
size_t loose_pos;
462463
size_t packed_pos;
463464
} refdb_fs_iter;
@@ -468,6 +469,7 @@ static void refdb_fs_backend__iterator_free(git_reference_iterator *_iter)
468469

469470
git_vector_free(&iter->loose);
470471
git_pool_clear(&iter->pool);
472+
git_sortedcache_free(iter->cache);
471473
git__free(iter);
472474
}
473475

@@ -539,10 +541,14 @@ static int refdb_fs_backend__iterator_next(
539541
giterr_clear();
540542
}
541543

542-
git_sortedcache_rlock(backend->refcache);
544+
if (!iter->cache) {
545+
if ((error = git_sortedcache_copy(&iter->cache, backend->refcache, 1, NULL, NULL)) < 0)
546+
return error;
547+
}
543548

544-
while (iter->packed_pos < git_sortedcache_entrycount(backend->refcache)) {
545-
ref = git_sortedcache_entry(backend->refcache, iter->packed_pos++);
549+
error = GIT_ITEROVER;
550+
while (iter->packed_pos < git_sortedcache_entrycount(iter->cache)) {
551+
ref = git_sortedcache_entry(iter->cache, iter->packed_pos++);
546552
if (!ref) /* stop now if another thread deleted refs and we past end */
547553
break;
548554

@@ -556,7 +562,6 @@ static int refdb_fs_backend__iterator_next(
556562
break;
557563
}
558564

559-
git_sortedcache_runlock(backend->refcache);
560565
return error;
561566
}
562567

@@ -579,10 +584,14 @@ static int refdb_fs_backend__iterator_next_name(
579584
giterr_clear();
580585
}
581586

582-
git_sortedcache_rlock(backend->refcache);
587+
if (!iter->cache) {
588+
if ((error = git_sortedcache_copy(&iter->cache, backend->refcache, 1, NULL, NULL)) < 0)
589+
return error;
590+
}
583591

584-
while (iter->packed_pos < git_sortedcache_entrycount(backend->refcache)) {
585-
ref = git_sortedcache_entry(backend->refcache, iter->packed_pos++);
592+
error = GIT_ITEROVER;
593+
while (iter->packed_pos < git_sortedcache_entrycount(iter->cache)) {
594+
ref = git_sortedcache_entry(iter->cache, iter->packed_pos++);
586595
if (!ref) /* stop now if another thread deleted refs and we past end */
587596
break;
588597

@@ -596,7 +605,6 @@ static int refdb_fs_backend__iterator_next_name(
596605
break;
597606
}
598607

599-
git_sortedcache_runlock(backend->refcache);
600608
return error;
601609
}
602610

0 commit comments

Comments
 (0)