Skip to content

Commit 8865859

Browse files
telezhnayagitster
authored andcommitted
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>
1 parent 20fed7c commit 8865859

File tree

4 files changed

+33
-59
lines changed

4 files changed

+33
-59
lines changed

builtin/pack-objects.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -995,8 +995,8 @@ static int want_object_in_pack(const unsigned char *sha1,
995995
struct packed_git **found_pack,
996996
off_t *found_offset)
997997
{
998-
struct mru_entry *entry;
999998
int want;
999+
struct list_head *pos;
10001000

10011001
if (!exclude && local && has_loose_object_nonlocal(sha1))
10021002
return 0;
@@ -1012,7 +1012,8 @@ static int want_object_in_pack(const unsigned char *sha1,
10121012
return want;
10131013
}
10141014

1015-
for (entry = packed_git_mru.head; entry; entry = entry->next) {
1015+
list_for_each(pos, &packed_git_mru.list) {
1016+
struct mru *entry = list_entry(pos, struct mru, list);
10161017
struct packed_git *p = entry->item;
10171018
off_t offset;
10181019

mru.c

Lines changed: 13 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,27 @@
11
#include "cache.h"
22
#include "mru.h"
33

4-
void mru_append(struct mru *mru, void *item)
4+
void mru_append(struct mru *head, void *item)
55
{
6-
struct mru_entry *cur = xmalloc(sizeof(*cur));
6+
struct mru *cur = xmalloc(sizeof(*cur));
77
cur->item = item;
8-
cur->prev = mru->tail;
9-
cur->next = NULL;
10-
11-
if (mru->tail)
12-
mru->tail->next = cur;
13-
else
14-
mru->head = cur;
15-
mru->tail = cur;
8+
list_add_tail(&cur->list, &head->list);
169
}
1710

18-
void mru_mark(struct mru *mru, struct mru_entry *entry)
11+
void mru_mark(struct mru *head, struct mru *entry)
1912
{
20-
/* If we're already at the front of the list, nothing to do */
21-
if (mru->head == entry)
22-
return;
23-
24-
/* Otherwise, remove us from our current slot... */
25-
if (entry->prev)
26-
entry->prev->next = entry->next;
27-
if (entry->next)
28-
entry->next->prev = entry->prev;
29-
else
30-
mru->tail = entry->prev;
31-
32-
/* And insert us at the beginning. */
33-
entry->prev = NULL;
34-
entry->next = mru->head;
35-
if (mru->head)
36-
mru->head->prev = entry;
37-
mru->head = entry;
13+
/* To mark means to put at the front of the list. */
14+
list_del(&entry->list);
15+
list_add(&entry->list, &head->list);
3816
}
3917

40-
void mru_clear(struct mru *mru)
18+
void mru_clear(struct mru *head)
4119
{
42-
struct mru_entry *p = mru->head;
20+
struct list_head *pos;
21+
struct list_head *tmp;
4322

44-
while (p) {
45-
struct mru_entry *to_free = p;
46-
p = p->next;
47-
free(to_free);
23+
list_for_each_safe(pos, tmp, &head->list) {
24+
free(list_entry(pos, struct mru, list));
4825
}
49-
mru->head = mru->tail = NULL;
26+
INIT_LIST_HEAD(&head->list);
5027
}

mru.h

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,24 @@
11
#ifndef MRU_H
22
#define MRU_H
33

4+
#include "list.h"
5+
46
/**
57
* A simple most-recently-used cache, backed by a doubly-linked list.
68
*
79
* Usage is roughly:
810
*
911
* // Create a list. Zero-initialization is required.
1012
* static struct mru cache;
11-
* mru_append(&cache, item);
12-
* ...
13+
* INIT_LIST_HEAD(&cache.list);
1314
*
14-
* // Iterate in MRU order.
15-
* struct mru_entry *p;
16-
* for (p = cache.head; p; p = p->next) {
17-
* if (matches(p->item))
18-
* break;
19-
* }
15+
* // Add new item to the end of the list.
16+
* void *item;
17+
* ...
18+
* mru_append(&cache, item);
2019
*
2120
* // Mark an item as used, moving it to the front of the list.
22-
* mru_mark(&cache, p);
21+
* mru_mark(&cache, item);
2322
*
2423
* // Reset the list to empty, cleaning up all resources.
2524
* mru_clear(&cache);
@@ -29,17 +28,13 @@
2928
* you will begin traversing the whole list again.
3029
*/
3130

32-
struct mru_entry {
33-
void *item;
34-
struct mru_entry *prev, *next;
35-
};
36-
3731
struct mru {
38-
struct mru_entry *head, *tail;
32+
struct list_head list;
33+
void *item;
3934
};
4035

41-
void mru_append(struct mru *mru, void *item);
42-
void mru_mark(struct mru *mru, struct mru_entry *entry);
43-
void mru_clear(struct mru *mru);
36+
void mru_append(struct mru *head, void *item);
37+
void mru_mark(struct mru *head, struct mru *entry);
38+
void mru_clear(struct mru *head);
4439

4540
#endif /* MRU_H */

packfile.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ static unsigned int pack_max_fds;
4040
static size_t peak_pack_mapped;
4141
static size_t pack_mapped;
4242
struct packed_git *packed_git;
43-
struct mru packed_git_mru;
43+
struct mru packed_git_mru = {{&packed_git_mru.list, &packed_git_mru.list}};
4444

4545
#define SZ_FMT PRIuMAX
4646
static inline uintmax_t sz_fmt(size_t s) { return s; }
@@ -1824,13 +1824,14 @@ static int fill_pack_entry(const unsigned char *sha1,
18241824
*/
18251825
int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)
18261826
{
1827-
struct mru_entry *p;
1827+
struct list_head *pos;
18281828

18291829
prepare_packed_git();
18301830
if (!packed_git)
18311831
return 0;
18321832

1833-
for (p = packed_git_mru.head; p; p = p->next) {
1833+
list_for_each(pos, &packed_git_mru.list) {
1834+
struct mru *p = list_entry(pos, struct mru, list);
18341835
if (fill_pack_entry(sha1, e, p->item)) {
18351836
mru_mark(&packed_git_mru, p);
18361837
return 1;

0 commit comments

Comments
 (0)