mru: use double-linked list from list.h
Simplify mru.[ch] and related code by reusing the double-linked list implementation from list.h instead of a custom one. This commit is an intermediate step. Our final goal is to get rid of mru.[ch] at all and inline all logic. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored by: Jeff King <peff@peff.net> Signed-off-by: Olga Telezhnaia <olyatelezhnaya@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
20fed7cad4
commit
8865859dfc
@ -995,8 +995,8 @@ static int want_object_in_pack(const unsigned char *sha1,
|
|||||||
struct packed_git **found_pack,
|
struct packed_git **found_pack,
|
||||||
off_t *found_offset)
|
off_t *found_offset)
|
||||||
{
|
{
|
||||||
struct mru_entry *entry;
|
|
||||||
int want;
|
int want;
|
||||||
|
struct list_head *pos;
|
||||||
|
|
||||||
if (!exclude && local && has_loose_object_nonlocal(sha1))
|
if (!exclude && local && has_loose_object_nonlocal(sha1))
|
||||||
return 0;
|
return 0;
|
||||||
@ -1012,7 +1012,8 @@ static int want_object_in_pack(const unsigned char *sha1,
|
|||||||
return want;
|
return want;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (entry = packed_git_mru.head; entry; entry = entry->next) {
|
list_for_each(pos, &packed_git_mru.list) {
|
||||||
|
struct mru *entry = list_entry(pos, struct mru, list);
|
||||||
struct packed_git *p = entry->item;
|
struct packed_git *p = entry->item;
|
||||||
off_t offset;
|
off_t offset;
|
||||||
|
|
||||||
|
49
mru.c
49
mru.c
@ -1,50 +1,27 @@
|
|||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
#include "mru.h"
|
#include "mru.h"
|
||||||
|
|
||||||
void mru_append(struct mru *mru, void *item)
|
void mru_append(struct mru *head, void *item)
|
||||||
{
|
{
|
||||||
struct mru_entry *cur = xmalloc(sizeof(*cur));
|
struct mru *cur = xmalloc(sizeof(*cur));
|
||||||
cur->item = item;
|
cur->item = item;
|
||||||
cur->prev = mru->tail;
|
list_add_tail(&cur->list, &head->list);
|
||||||
cur->next = NULL;
|
|
||||||
|
|
||||||
if (mru->tail)
|
|
||||||
mru->tail->next = cur;
|
|
||||||
else
|
|
||||||
mru->head = cur;
|
|
||||||
mru->tail = cur;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mru_mark(struct mru *mru, struct mru_entry *entry)
|
void mru_mark(struct mru *head, struct mru *entry)
|
||||||
{
|
{
|
||||||
/* If we're already at the front of the list, nothing to do */
|
/* To mark means to put at the front of the list. */
|
||||||
if (mru->head == entry)
|
list_del(&entry->list);
|
||||||
return;
|
list_add(&entry->list, &head->list);
|
||||||
|
|
||||||
/* Otherwise, remove us from our current slot... */
|
|
||||||
if (entry->prev)
|
|
||||||
entry->prev->next = entry->next;
|
|
||||||
if (entry->next)
|
|
||||||
entry->next->prev = entry->prev;
|
|
||||||
else
|
|
||||||
mru->tail = entry->prev;
|
|
||||||
|
|
||||||
/* And insert us at the beginning. */
|
|
||||||
entry->prev = NULL;
|
|
||||||
entry->next = mru->head;
|
|
||||||
if (mru->head)
|
|
||||||
mru->head->prev = entry;
|
|
||||||
mru->head = entry;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mru_clear(struct mru *mru)
|
void mru_clear(struct mru *head)
|
||||||
{
|
{
|
||||||
struct mru_entry *p = mru->head;
|
struct list_head *pos;
|
||||||
|
struct list_head *tmp;
|
||||||
|
|
||||||
while (p) {
|
list_for_each_safe(pos, tmp, &head->list) {
|
||||||
struct mru_entry *to_free = p;
|
free(list_entry(pos, struct mru, list));
|
||||||
p = p->next;
|
|
||||||
free(to_free);
|
|
||||||
}
|
}
|
||||||
mru->head = mru->tail = NULL;
|
INIT_LIST_HEAD(&head->list);
|
||||||
}
|
}
|
||||||
|
31
mru.h
31
mru.h
@ -1,6 +1,8 @@
|
|||||||
#ifndef MRU_H
|
#ifndef MRU_H
|
||||||
#define MRU_H
|
#define MRU_H
|
||||||
|
|
||||||
|
#include "list.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple most-recently-used cache, backed by a doubly-linked list.
|
* A simple most-recently-used cache, backed by a doubly-linked list.
|
||||||
*
|
*
|
||||||
@ -8,18 +10,15 @@
|
|||||||
*
|
*
|
||||||
* // Create a list. Zero-initialization is required.
|
* // Create a list. Zero-initialization is required.
|
||||||
* static struct mru cache;
|
* static struct mru cache;
|
||||||
* mru_append(&cache, item);
|
* INIT_LIST_HEAD(&cache.list);
|
||||||
* ...
|
|
||||||
*
|
*
|
||||||
* // Iterate in MRU order.
|
* // Add new item to the end of the list.
|
||||||
* struct mru_entry *p;
|
* void *item;
|
||||||
* for (p = cache.head; p; p = p->next) {
|
* ...
|
||||||
* if (matches(p->item))
|
* mru_append(&cache, item);
|
||||||
* break;
|
|
||||||
* }
|
|
||||||
*
|
*
|
||||||
* // Mark an item as used, moving it to the front of the list.
|
* // Mark an item as used, moving it to the front of the list.
|
||||||
* mru_mark(&cache, p);
|
* mru_mark(&cache, item);
|
||||||
*
|
*
|
||||||
* // Reset the list to empty, cleaning up all resources.
|
* // Reset the list to empty, cleaning up all resources.
|
||||||
* mru_clear(&cache);
|
* mru_clear(&cache);
|
||||||
@ -29,17 +28,13 @@
|
|||||||
* you will begin traversing the whole list again.
|
* you will begin traversing the whole list again.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct mru_entry {
|
|
||||||
void *item;
|
|
||||||
struct mru_entry *prev, *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct mru {
|
struct mru {
|
||||||
struct mru_entry *head, *tail;
|
struct list_head list;
|
||||||
|
void *item;
|
||||||
};
|
};
|
||||||
|
|
||||||
void mru_append(struct mru *mru, void *item);
|
void mru_append(struct mru *head, void *item);
|
||||||
void mru_mark(struct mru *mru, struct mru_entry *entry);
|
void mru_mark(struct mru *head, struct mru *entry);
|
||||||
void mru_clear(struct mru *mru);
|
void mru_clear(struct mru *head);
|
||||||
|
|
||||||
#endif /* MRU_H */
|
#endif /* MRU_H */
|
||||||
|
@ -40,7 +40,7 @@ static unsigned int pack_max_fds;
|
|||||||
static size_t peak_pack_mapped;
|
static size_t peak_pack_mapped;
|
||||||
static size_t pack_mapped;
|
static size_t pack_mapped;
|
||||||
struct packed_git *packed_git;
|
struct packed_git *packed_git;
|
||||||
struct mru packed_git_mru;
|
struct mru packed_git_mru = {{&packed_git_mru.list, &packed_git_mru.list}};
|
||||||
|
|
||||||
#define SZ_FMT PRIuMAX
|
#define SZ_FMT PRIuMAX
|
||||||
static inline uintmax_t sz_fmt(size_t s) { return s; }
|
static inline uintmax_t sz_fmt(size_t s) { return s; }
|
||||||
@ -1824,13 +1824,14 @@ static int fill_pack_entry(const unsigned char *sha1,
|
|||||||
*/
|
*/
|
||||||
int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)
|
int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)
|
||||||
{
|
{
|
||||||
struct mru_entry *p;
|
struct list_head *pos;
|
||||||
|
|
||||||
prepare_packed_git();
|
prepare_packed_git();
|
||||||
if (!packed_git)
|
if (!packed_git)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for (p = packed_git_mru.head; p; p = p->next) {
|
list_for_each(pos, &packed_git_mru.list) {
|
||||||
|
struct mru *p = list_entry(pos, struct mru, list);
|
||||||
if (fill_pack_entry(sha1, e, p->item)) {
|
if (fill_pack_entry(sha1, e, p->item)) {
|
||||||
mru_mark(&packed_git_mru, p);
|
mru_mark(&packed_git_mru, p);
|
||||||
return 1;
|
return 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user