提交 12d95ef6 编写于 作者: J Jeff King 提交者: Junio C Hamano

delta_base_cache: use list.h for LRU

We keep an LRU list of entries for when we need to drop
something from an over-full cache. The list is implemented
as a circular doubly-linked list, which is exactly what
list.h provides. We can save a few lines by using the list.h
macros and functions. More importantly, this makes the code
easier to follow, as the reader sees explicit concepts like
"list_add_tail()" instead of pointer manipulation.

As a bonus, the list_entry() macro lets us place the lru
pointers anywhere inside the delta_base_cache_entry struct
(as opposed to just casting the pointer, which requires it
at the front of the struct). This will be useful in later
patches when we need to place other items at the front of
the struct (e.g., our hashmap implementation requires this).
Signed-off-by: NJeff King <peff@peff.net>
Signed-off-by: NJunio C Hamano <gitster@pobox.com>
上级 f92dd60f
......@@ -24,6 +24,7 @@
#include "streaming.h"
#include "dir.h"
#include "mru.h"
#include "list.h"
#ifndef O_NOATIME
#if defined(__linux__) && (defined(__i386__) || defined(__PPC__))
......@@ -2077,13 +2078,10 @@ static void *unpack_compressed_entry(struct packed_git *p,
static size_t delta_base_cached;
static struct delta_base_cache_lru_list {
struct delta_base_cache_lru_list *prev;
struct delta_base_cache_lru_list *next;
} delta_base_cache_lru = { &delta_base_cache_lru, &delta_base_cache_lru };
static LIST_HEAD(delta_base_cache_lru);
static struct delta_base_cache_entry {
struct delta_base_cache_lru_list lru;
struct list_head lru;
void *data;
struct packed_git *p;
off_t base_offset;
......@@ -2128,8 +2126,7 @@ static int in_delta_base_cache(struct packed_git *p, off_t base_offset)
static void detach_delta_base_cache_entry(struct delta_base_cache_entry *ent)
{
ent->data = NULL;
ent->lru.next->prev = ent->lru.prev;
ent->lru.prev->next = ent->lru.next;
list_del(&ent->lru);
delta_base_cached -= ent->size;
}
......@@ -2168,24 +2165,24 @@ static void add_delta_base_cache(struct packed_git *p, off_t base_offset,
{
unsigned long hash = pack_entry_hash(p, base_offset);
struct delta_base_cache_entry *ent = delta_base_cache + hash;
struct delta_base_cache_lru_list *lru;
struct list_head *lru;
release_delta_base_cache(ent);
delta_base_cached += base_size;
for (lru = delta_base_cache_lru.next;
delta_base_cached > delta_base_cache_limit
&& lru != &delta_base_cache_lru;
lru = lru->next) {
struct delta_base_cache_entry *f = (void *)lru;
list_for_each(lru, &delta_base_cache_lru) {
struct delta_base_cache_entry *f =
list_entry(lru, struct delta_base_cache_entry, lru);
if (delta_base_cached <= delta_base_cache_limit)
break;
if (f->type == OBJ_BLOB)
release_delta_base_cache(f);
}
for (lru = delta_base_cache_lru.next;
delta_base_cached > delta_base_cache_limit
&& lru != &delta_base_cache_lru;
lru = lru->next) {
struct delta_base_cache_entry *f = (void *)lru;
list_for_each(lru, &delta_base_cache_lru) {
struct delta_base_cache_entry *f =
list_entry(lru, struct delta_base_cache_entry, lru);
if (delta_base_cached <= delta_base_cache_limit)
break;
release_delta_base_cache(f);
}
......@@ -2194,10 +2191,7 @@ static void add_delta_base_cache(struct packed_git *p, off_t base_offset,
ent->type = type;
ent->data = base;
ent->size = base_size;
ent->lru.next = &delta_base_cache_lru;
ent->lru.prev = delta_base_cache_lru.prev;
delta_base_cache_lru.prev->next = &ent->lru;
delta_base_cache_lru.prev = &ent->lru;
list_add_tail(&ent->lru, &delta_base_cache_lru);
}
static void *read_object(const unsigned char *sha1, enum object_type *type,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册