Skip to content

Commit dd5253b

Browse files
committed
Merge branch 'nd/find-pack-entry-recent-cache-invalidation'
* nd/find-pack-entry-recent-cache-invalidation: find_pack_entry(): do not keep packed_git pointer locally sha1_file.c: move the core logic of find_pack_entry() into fill_pack_entry()
2 parents 6ff63d9 + c01f51c commit dd5253b

File tree

1 file changed

+46
-38
lines changed

1 file changed

+46
-38
lines changed

sha1_file.c

Lines changed: 46 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ static struct cached_object empty_tree = {
5454
0
5555
};
5656

57+
static struct packed_git *last_found_pack;
58+
5759
static struct cached_object *find_cached_object(const unsigned char *sha1)
5860
{
5961
int i;
@@ -720,6 +722,8 @@ void free_pack_by_name(const char *pack_name)
720722
close_pack_index(p);
721723
free(p->bad_object_sha1);
722724
*pp = p->next;
725+
if (last_found_pack == p)
726+
last_found_pack = NULL;
723727
free(p);
724728
return;
725729
}
@@ -2015,54 +2019,58 @@ int is_pack_valid(struct packed_git *p)
20152019
return !open_packed_git(p);
20162020
}
20172021

2022+
static int fill_pack_entry(const unsigned char *sha1,
2023+
struct pack_entry *e,
2024+
struct packed_git *p)
2025+
{
2026+
off_t offset;
2027+
2028+
if (p->num_bad_objects) {
2029+
unsigned i;
2030+
for (i = 0; i < p->num_bad_objects; i++)
2031+
if (!hashcmp(sha1, p->bad_object_sha1 + 20 * i))
2032+
return 0;
2033+
}
2034+
2035+
offset = find_pack_entry_one(sha1, p);
2036+
if (!offset)
2037+
return 0;
2038+
2039+
/*
2040+
* We are about to tell the caller where they can locate the
2041+
* requested object. We better make sure the packfile is
2042+
* still here and can be accessed before supplying that
2043+
* answer, as it may have been deleted since the index was
2044+
* loaded!
2045+
*/
2046+
if (!is_pack_valid(p)) {
2047+
warning("packfile %s cannot be accessed", p->pack_name);
2048+
return 0;
2049+
}
2050+
e->offset = offset;
2051+
e->p = p;
2052+
hashcpy(e->sha1, sha1);
2053+
return 1;
2054+
}
2055+
20182056
static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)
20192057
{
2020-
static struct packed_git *last_found = (void *)1;
20212058
struct packed_git *p;
2022-
off_t offset;
20232059

20242060
prepare_packed_git();
20252061
if (!packed_git)
20262062
return 0;
2027-
p = (last_found == (void *)1) ? packed_git : last_found;
20282063

2029-
do {
2030-
if (p->num_bad_objects) {
2031-
unsigned i;
2032-
for (i = 0; i < p->num_bad_objects; i++)
2033-
if (!hashcmp(sha1, p->bad_object_sha1 + 20 * i))
2034-
goto next;
2035-
}
2064+
if (last_found_pack && fill_pack_entry(sha1, e, last_found_pack))
2065+
return 1;
20362066

2037-
offset = find_pack_entry_one(sha1, p);
2038-
if (offset) {
2039-
/*
2040-
* We are about to tell the caller where they can
2041-
* locate the requested object. We better make
2042-
* sure the packfile is still here and can be
2043-
* accessed before supplying that answer, as
2044-
* it may have been deleted since the index
2045-
* was loaded!
2046-
*/
2047-
if (!is_pack_valid(p)) {
2048-
warning("packfile %s cannot be accessed", p->pack_name);
2049-
goto next;
2050-
}
2051-
e->offset = offset;
2052-
e->p = p;
2053-
hashcpy(e->sha1, sha1);
2054-
last_found = p;
2055-
return 1;
2056-
}
2067+
for (p = packed_git; p; p = p->next) {
2068+
if (p == last_found_pack || !fill_pack_entry(sha1, e, p))
2069+
continue;
20572070

2058-
next:
2059-
if (p == last_found)
2060-
p = packed_git;
2061-
else
2062-
p = p->next;
2063-
if (p == last_found)
2064-
p = p->next;
2065-
} while (p);
2071+
last_found_pack = p;
2072+
return 1;
2073+
}
20662074
return 0;
20672075
}
20682076

0 commit comments

Comments
 (0)