Merge branch 'nd/find-pack-entry-recent-cache-invalidation' into maint

* 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()
This commit is contained in:
Junio C Hamano 2012-02-21 14:56:36 -08:00
commit f3ccea8dd4

View file

@ -54,6 +54,8 @@ static struct cached_object empty_tree = {
0
};
static struct packed_git *last_found_pack;
static struct cached_object *find_cached_object(const unsigned char *sha1)
{
int i;
@ -720,6 +722,8 @@ void free_pack_by_name(const char *pack_name)
close_pack_index(p);
free(p->bad_object_sha1);
*pp = p->next;
if (last_found_pack == p)
last_found_pack = NULL;
free(p);
return;
}
@ -2015,54 +2019,58 @@ int is_pack_valid(struct packed_git *p)
return !open_packed_git(p);
}
static int fill_pack_entry(const unsigned char *sha1,
struct pack_entry *e,
struct packed_git *p)
{
off_t offset;
if (p->num_bad_objects) {
unsigned i;
for (i = 0; i < p->num_bad_objects; i++)
if (!hashcmp(sha1, p->bad_object_sha1 + 20 * i))
return 0;
}
offset = find_pack_entry_one(sha1, p);
if (!offset)
return 0;
/*
* We are about to tell the caller where they can locate the
* requested object. We better make sure the packfile is
* still here and can be accessed before supplying that
* answer, as it may have been deleted since the index was
* loaded!
*/
if (!is_pack_valid(p)) {
warning("packfile %s cannot be accessed", p->pack_name);
return 0;
}
e->offset = offset;
e->p = p;
hashcpy(e->sha1, sha1);
return 1;
}
static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)
{
static struct packed_git *last_found = (void *)1;
struct packed_git *p;
off_t offset;
prepare_packed_git();
if (!packed_git)
return 0;
p = (last_found == (void *)1) ? packed_git : last_found;
do {
if (p->num_bad_objects) {
unsigned i;
for (i = 0; i < p->num_bad_objects; i++)
if (!hashcmp(sha1, p->bad_object_sha1 + 20 * i))
goto next;
}
if (last_found_pack && fill_pack_entry(sha1, e, last_found_pack))
return 1;
offset = find_pack_entry_one(sha1, p);
if (offset) {
/*
* We are about to tell the caller where they can
* locate the requested object. We better make
* sure the packfile is still here and can be
* accessed before supplying that answer, as
* it may have been deleted since the index
* was loaded!
*/
if (!is_pack_valid(p)) {
warning("packfile %s cannot be accessed", p->pack_name);
goto next;
}
e->offset = offset;
e->p = p;
hashcpy(e->sha1, sha1);
last_found = p;
return 1;
}
for (p = packed_git; p; p = p->next) {
if (p == last_found_pack || !fill_pack_entry(sha1, e, p))
continue;
next:
if (p == last_found)
p = packed_git;
else
p = p->next;
if (p == last_found)
p = p->next;
} while (p);
last_found_pack = p;
return 1;
}
return 0;
}