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()
This commit is contained in:
Junio C Hamano 2012-02-12 22:43:03 -08:00
commit dd5253b4bd

View File

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