1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-05-09 10:16:08 +02:00

Merge branch 'ot/mru-on-list'

The first step to getting rid of mru API and using the
doubly-linked list API directly instead.

* ot/mru-on-list:
  mru: use double-linked list from list.h
This commit is contained in:
Junio C Hamano 2018-02-13 13:39:05 -08:00
commit afc8aa3fbf
4 changed files with 33 additions and 59 deletions

View File

@ -1009,8 +1009,8 @@ static int want_object_in_pack(const struct object_id *oid,
struct packed_git **found_pack,
off_t *found_offset)
{
struct mru_entry *entry;
int want;
struct list_head *pos;
if (!exclude && local && has_loose_object_nonlocal(oid->hash))
return 0;
@ -1026,7 +1026,8 @@ static int want_object_in_pack(const struct object_id *oid,
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;
off_t offset;

49
mru.c
View File

@ -1,50 +1,27 @@
#include "cache.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->prev = mru->tail;
cur->next = NULL;
if (mru->tail)
mru->tail->next = cur;
else
mru->head = cur;
mru->tail = cur;
list_add_tail(&cur->list, &head->list);
}
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 */
if (mru->head == entry)
return;
/* 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;
/* To mark means to put at the front of the list. */
list_del(&entry->list);
list_add(&entry->list, &head->list);
}
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) {
struct mru_entry *to_free = p;
p = p->next;
free(to_free);
list_for_each_safe(pos, tmp, &head->list) {
free(list_entry(pos, struct mru, list));
}
mru->head = mru->tail = NULL;
INIT_LIST_HEAD(&head->list);
}

31
mru.h
View File

@ -1,6 +1,8 @@
#ifndef MRU_H
#define MRU_H
#include "list.h"
/**
* A simple most-recently-used cache, backed by a doubly-linked list.
*
@ -8,18 +10,15 @@
*
* // Create a list. Zero-initialization is required.
* static struct mru cache;
* mru_append(&cache, item);
* ...
* INIT_LIST_HEAD(&cache.list);
*
* // Iterate in MRU order.
* struct mru_entry *p;
* for (p = cache.head; p; p = p->next) {
* if (matches(p->item))
* break;
* }
* // Add new item to the end of the list.
* void *item;
* ...
* mru_append(&cache, item);
*
* // 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.
* mru_clear(&cache);
@ -29,17 +28,13 @@
* you will begin traversing the whole list again.
*/
struct mru_entry {
void *item;
struct mru_entry *prev, *next;
};
struct mru {
struct mru_entry *head, *tail;
struct list_head list;
void *item;
};
void mru_append(struct mru *mru, void *item);
void mru_mark(struct mru *mru, struct mru_entry *entry);
void mru_clear(struct mru *mru);
void mru_append(struct mru *head, void *item);
void mru_mark(struct mru *head, struct mru *entry);
void mru_clear(struct mru *head);
#endif /* MRU_H */

View File

@ -45,7 +45,7 @@ static unsigned int pack_max_fds;
static size_t peak_pack_mapped;
static size_t pack_mapped;
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
static inline uintmax_t sz_fmt(size_t s) { return s; }
@ -1841,13 +1841,14 @@ static int fill_pack_entry(const unsigned char *sha1,
*/
int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)
{
struct mru_entry *p;
struct list_head *pos;
prepare_packed_git();
if (!packed_git)
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)) {
mru_mark(&packed_git_mru, p);
return 1;