diff options
Diffstat (limited to 'pintos-progos/lib/kernel/hash.h')
| -rw-r--r-- | pintos-progos/lib/kernel/hash.h | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/pintos-progos/lib/kernel/hash.h b/pintos-progos/lib/kernel/hash.h new file mode 100644 index 0000000..db9f674 --- /dev/null +++ b/pintos-progos/lib/kernel/hash.h | |||
| @@ -0,0 +1,103 @@ | |||
| 1 | #ifndef __LIB_KERNEL_HASH_H | ||
| 2 | #define __LIB_KERNEL_HASH_H | ||
| 3 | |||
| 4 | /* Hash table. | ||
| 5 | |||
| 6 | This data structure is thoroughly documented in the Tour of | ||
| 7 | Pintos for Project 3. | ||
| 8 | |||
| 9 | This is a standard hash table with chaining. To locate an | ||
| 10 | element in the table, we compute a hash function over the | ||
| 11 | element's data and use that as an index into an array of | ||
| 12 | doubly linked lists, then linearly search the list. | ||
| 13 | |||
| 14 | The chain lists do not use dynamic allocation. Instead, each | ||
| 15 | structure that can potentially be in a hash must embed a | ||
| 16 | struct hash_elem member. All of the hash functions operate on | ||
| 17 | these `struct hash_elem's. The hash_entry macro allows | ||
| 18 | conversion from a struct hash_elem back to a structure object | ||
| 19 | that contains it. This is the same technique used in the | ||
| 20 | linked list implementation. Refer to lib/kernel/list.h for a | ||
| 21 | detailed explanation. */ | ||
| 22 | |||
| 23 | #include <stdbool.h> | ||
| 24 | #include <stddef.h> | ||
| 25 | #include <stdint.h> | ||
| 26 | #include "list.h" | ||
| 27 | |||
| 28 | /* Hash element. */ | ||
| 29 | struct hash_elem | ||
| 30 | { | ||
| 31 | struct list_elem list_elem; | ||
| 32 | }; | ||
| 33 | |||
| 34 | /* Converts pointer to hash element HASH_ELEM into a pointer to | ||
| 35 | the structure that HASH_ELEM is embedded inside. Supply the | ||
| 36 | name of the outer structure STRUCT and the member name MEMBER | ||
| 37 | of the hash element. See the big comment at the top of the | ||
| 38 | file for an example. */ | ||
| 39 | #define hash_entry(HASH_ELEM, STRUCT, MEMBER) \ | ||
| 40 | ((STRUCT *) ((uint8_t *) &(HASH_ELEM)->list_elem \ | ||
| 41 | - offsetof (STRUCT, MEMBER.list_elem))) | ||
| 42 | |||
| 43 | /* Computes and returns the hash value for hash element E, given | ||
| 44 | auxiliary data AUX. */ | ||
| 45 | typedef unsigned hash_hash_func (const struct hash_elem *e, void *aux); | ||
| 46 | |||
| 47 | /* Compares the value of two hash elements A and B, given | ||
| 48 | auxiliary data AUX. Returns true if A is less than B, or | ||
| 49 | false if A is greater than or equal to B. */ | ||
| 50 | typedef bool hash_less_func (const struct hash_elem *a, | ||
| 51 | const struct hash_elem *b, | ||
| 52 | void *aux); | ||
| 53 | |||
| 54 | /* Performs some operation on hash element E, given auxiliary | ||
| 55 | data AUX. */ | ||
| 56 | typedef void hash_action_func (struct hash_elem *e, void *aux); | ||
| 57 | |||
| 58 | /* Hash table. */ | ||
| 59 | struct hash | ||
| 60 | { | ||
| 61 | size_t elem_cnt; /* Number of elements in table. */ | ||
| 62 | size_t bucket_cnt; /* Number of buckets, a power of 2. */ | ||
| 63 | struct list *buckets; /* Array of `bucket_cnt' lists. */ | ||
| 64 | hash_hash_func *hash; /* Hash function. */ | ||
| 65 | hash_less_func *less; /* Comparison function. */ | ||
| 66 | void *aux; /* Auxiliary data for `hash' and `less'. */ | ||
| 67 | }; | ||
| 68 | |||
| 69 | /* A hash table iterator. */ | ||
| 70 | struct hash_iterator | ||
| 71 | { | ||
| 72 | struct hash *hash; /* The hash table. */ | ||
| 73 | struct list *bucket; /* Current bucket. */ | ||
| 74 | struct hash_elem *elem; /* Current hash element in current bucket. */ | ||
| 75 | }; | ||
| 76 | |||
| 77 | /* Basic life cycle. */ | ||
| 78 | bool hash_init (struct hash *, hash_hash_func *, hash_less_func *, void *aux); | ||
| 79 | void hash_clear (struct hash *, hash_action_func *); | ||
| 80 | void hash_destroy (struct hash *, hash_action_func *); | ||
| 81 | |||
| 82 | /* Search, insertion, deletion. */ | ||
| 83 | struct hash_elem *hash_insert (struct hash *, struct hash_elem *); | ||
| 84 | struct hash_elem *hash_replace (struct hash *, struct hash_elem *); | ||
| 85 | struct hash_elem *hash_find (struct hash *, struct hash_elem *); | ||
| 86 | struct hash_elem *hash_delete (struct hash *, struct hash_elem *); | ||
| 87 | |||
| 88 | /* Iteration. */ | ||
| 89 | void hash_apply (struct hash *, hash_action_func *); | ||
| 90 | void hash_first (struct hash_iterator *, struct hash *); | ||
| 91 | struct hash_elem *hash_next (struct hash_iterator *); | ||
| 92 | struct hash_elem *hash_cur (struct hash_iterator *); | ||
| 93 | |||
| 94 | /* Information. */ | ||
| 95 | size_t hash_size (struct hash *); | ||
| 96 | bool hash_empty (struct hash *); | ||
| 97 | |||
| 98 | /* Sample hash functions. */ | ||
| 99 | unsigned hash_bytes (const void *, size_t); | ||
| 100 | unsigned hash_string (const char *); | ||
| 101 | unsigned hash_int (int); | ||
| 102 | |||
| 103 | #endif /* lib/kernel/hash.h */ | ||
