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>
Olga Telezhnaya committed
Sep 30, 2017 at 17:51 UTC
8865859dfc346c61f0e75fa429c5d307bd27368c
4 files changed
+33
-59
builtin/pack-objects.c
+3
-2
@@ -995,8 +995,8 @@ static int want_object_in_pack(const unsigned char *sha1,
995
struct packed_git **found_pack,
996
off_t *found_offset)
997
{
998
- struct mru_entry *entry;
998
int want;
999
+ struct list_head *pos;
1000
1001
if (!exclude && local && has_loose_object_nonlocal(sha1))
1002
return 0;
@@ -1012,7 +1012,8 @@ static int want_object_in_pack(const unsigned char *sha1,
1012
return want;
1013
}
1014
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);
1017
struct packed_git *p = entry->item;
1018
off_t offset;
1019
mru.c
+13
-36
@@ -1,50 +1,27 @@
1
#include "cache.h"
2
#include "mru.h"
3
4
-void mru_append(struct mru *mru, void *item)
4
+void mru_append(struct mru *head, void *item)
5
{
6
- struct mru_entry *cur = xmalloc(sizeof(*cur));
6
+ struct mru *cur = xmalloc(sizeof(*cur));
7
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);
9
}
10
18
-void mru_mark(struct mru *mru, struct mru_entry *entry)
11
+void mru_mark(struct mru *head, struct mru *entry)
12
{
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);
16
}
17
40
-void mru_clear(struct mru *mru)
18
+void mru_clear(struct mru *head)
19
{
42
- struct mru_entry *p = mru->head;
20
+ struct list_head *pos;
21
+ struct list_head *tmp;
22
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));
25
}
49
- mru->head = mru->tail = NULL;
26
+ INIT_LIST_HEAD(&head->list);
27
}
mru.h
+13
-18
@@ -1,6 +1,8 @@
1
#ifndef MRU_H
2
#define MRU_H
3
4
+#include "list.h"
5
+
6
/**
7
* A simple most-recently-used cache, backed by a doubly-linked list.
8
*
@@ -8,18 +10,15 @@
10
*
11
* // Create a list. Zero-initialization is required.
12
* static struct mru cache;
11
- * mru_append(&cache, item);
12
- * ...
13
+ * INIT_LIST_HEAD(&cache.list);
14
*
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);
19
*
20
* // Mark an item as used, moving it to the front of the list.
22
- * mru_mark(&cache, p);
21
+ * mru_mark(&cache, item);
22
*
23
* // Reset the list to empty, cleaning up all resources.
24
* mru_clear(&cache);
@@ -29,17 +28,13 @@
28
* you will begin traversing the whole list again.
29
*/
30
32
-struct mru_entry {
33
- void *item;
34
- struct mru_entry *prev, *next;
35
-};
36
-
31
struct mru {
38
- struct mru_entry *head, *tail;
32
+ struct list_head list;
33
+ void *item;
34
};
35
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);
39
40
#endif /* MRU_H */
packfile.c
+4
-3
@@ -40,7 +40,7 @@ static unsigned int pack_max_fds;
40
static size_t peak_pack_mapped;
41
static size_t pack_mapped;
42
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}};
44
45
#define SZ_FMT PRIuMAX
46
static inline uintmax_t sz_fmt(size_t s) { return s; }
@@ -1824,13 +1824,14 @@ static int fill_pack_entry(const unsigned char *sha1,
1824
*/
1825
int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)
1826
{
1827
- struct mru_entry *p;
1827
+ struct list_head *pos;
1828
1829
prepare_packed_git();
1830
if (!packed_git)
1831
return 0;
1832
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);
1835
if (fill_pack_entry(sha1, e, p->item)) {
1836
mru_mark(&packed_git_mru, p);
1837
return 1;