Jeff King | 002f206 | 2016-07-29 00:06:59 -0400 | [diff] [blame] | 1 | #ifndef MRU_H |
| 2 | #define MRU_H |
| 3 | |
| 4 | /** |
| 5 | * A simple most-recently-used cache, backed by a doubly-linked list. |
| 6 | * |
| 7 | * Usage is roughly: |
| 8 | * |
| 9 | * // Create a list. Zero-initialization is required. |
| 10 | * static struct mru cache; |
| 11 | * mru_append(&cache, item); |
| 12 | * ... |
| 13 | * |
| 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 | * } |
| 20 | * |
| 21 | * // Mark an item as used, moving it to the front of the list. |
| 22 | * mru_mark(&cache, p); |
| 23 | * |
| 24 | * // Reset the list to empty, cleaning up all resources. |
| 25 | * mru_clear(&cache); |
| 26 | * |
| 27 | * Note that you SHOULD NOT call mru_mark() and then continue traversing the |
| 28 | * list; it reorders the marked item to the front of the list, and therefore |
| 29 | * you will begin traversing the whole list again. |
| 30 | */ |
| 31 | |
| 32 | struct mru_entry { |
| 33 | void *item; |
| 34 | struct mru_entry *prev, *next; |
| 35 | }; |
| 36 | |
| 37 | struct mru { |
| 38 | struct mru_entry *head, *tail; |
| 39 | }; |
| 40 | |
| 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); |
| 44 | |
| 45 | #endif /* MRU_H */ |