[Krafton Jungle] PintOS 2.0.0
크래프톤 정글 PintOS
 
Loading...
Searching...
No Matches
hash.c File Reference
#include "hash.h"
#include "../debug.h"
#include "threads/malloc.h"
Include dependency graph for hash.c:

Macros

#define list_elem_to_hash_elem(LIST_ELEM)    list_entry(LIST_ELEM, struct hash_elem, list_elem)
 
#define FNV_64_PRIME   0x00000100000001B3UL
 
#define FNV_64_BASIS   0xcbf29ce484222325UL
 
#define MIN_ELEMS_PER_BUCKET   1 /* Elems/bucket < 1: reduce # of buckets. */
 
#define BEST_ELEMS_PER_BUCKET   2 /* Ideal elems/bucket. */
 
#define MAX_ELEMS_PER_BUCKET   4 /* Elems/bucket > 4: increase # of buckets. */
 

Functions

static struct listfind_bucket (struct hash *, struct hash_elem *)
 
static struct hash_elemfind_elem (struct hash *, struct list *, struct hash_elem *)
 
static void insert_elem (struct hash *, struct list *, struct hash_elem *)
 
static void remove_elem (struct hash *, struct hash_elem *)
 
static void rehash (struct hash *)
 
bool hash_init (struct hash *h, hash_hash_func *hash, hash_less_func *less, void *aux)
 
void hash_clear (struct hash *h, hash_action_func *destructor)
 
void hash_destroy (struct hash *h, hash_action_func *destructor)
 
struct hash_elemhash_insert (struct hash *h, struct hash_elem *new)
 
struct hash_elemhash_replace (struct hash *h, struct hash_elem *new)
 
struct hash_elemhash_find (struct hash *h, struct hash_elem *e)
 
struct hash_elemhash_delete (struct hash *h, struct hash_elem *e)
 
void hash_apply (struct hash *h, hash_action_func *action)
 
void hash_first (struct hash_iterator *i, struct hash *h)
 
struct hash_elemhash_next (struct hash_iterator *i)
 
struct hash_elemhash_cur (struct hash_iterator *i)
 
size_t hash_size (struct hash *h)
 
bool hash_empty (struct hash *h)
 
uint64_t hash_bytes (const void *buf_, size_t size)
 
uint64_t hash_string (const char *s_)
 
uint64_t hash_int (int i)
 
static size_t turn_off_least_1bit (size_t x)
 
static size_t is_power_of_2 (size_t x)
 

Macro Definition Documentation

◆ BEST_ELEMS_PER_BUCKET

#define BEST_ELEMS_PER_BUCKET   2 /* Ideal elems/bucket. */

◆ FNV_64_BASIS

#define FNV_64_BASIS   0xcbf29ce484222325UL

◆ FNV_64_PRIME

#define FNV_64_PRIME   0x00000100000001B3UL

◆ list_elem_to_hash_elem

#define list_elem_to_hash_elem (   LIST_ELEM)     list_entry(LIST_ELEM, struct hash_elem, list_elem)

◆ MAX_ELEMS_PER_BUCKET

#define MAX_ELEMS_PER_BUCKET   4 /* Elems/bucket > 4: increase # of buckets. */

◆ MIN_ELEMS_PER_BUCKET

#define MIN_ELEMS_PER_BUCKET   1 /* Elems/bucket < 1: reduce # of buckets. */

Function Documentation

◆ find_bucket()

static struct list * find_bucket ( struct hash h,
struct hash_elem e 
)
static
283 {
284 size_t bucket_idx = h->hash (e, h->aux) & (h->bucket_cnt - 1);
285 return &h->buckets[bucket_idx];
286}
hash_hash_func * hash
Definition: hash.h:62
void * aux
Definition: hash.h:64
size_t bucket_cnt
Definition: hash.h:60
struct list * buckets
Definition: hash.h:61
Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_elem()

static struct hash_elem * find_elem ( struct hash h,
struct list bucket,
struct hash_elem e 
)
static
291 {
292 struct list_elem *i;
293
294 for (i = list_begin (bucket); i != list_end (bucket); i = list_next (i)) {
295 struct hash_elem *hi = list_elem_to_hash_elem (i);
296 if (!h->less (hi, e, h->aux) && !h->less (e, hi, h->aux))
297 return hi;
298 }
299 return NULL;
300}
#define list_elem_to_hash_elem(LIST_ELEM)
Definition: hash.c:12
struct list_elem * list_begin(struct list *)
Definition: list.c:68
struct list_elem * list_next(struct list_elem *)
Definition: list.c:77
struct list_elem * list_end(struct list *)
Definition: list.c:88
#define NULL
Definition: stddef.h:4
Definition: hash.h:29
hash_less_func * less
Definition: hash.h:63
Definition: list.h:87
Here is the call graph for this function:
Here is the caller graph for this function:

◆ hash_apply()

void hash_apply ( struct hash h,
hash_action_func action 
)
153 {
154 size_t i;
155
156 ASSERT (action != NULL);
157
158 for (i = 0; i < h->bucket_cnt; i++) {
159 struct list *bucket = &h->buckets[i];
160 struct list_elem *elem, *next;
161
162 for (elem = list_begin (bucket); elem != list_end (bucket); elem = next) {
163 next = list_next (elem);
164 action (list_elem_to_hash_elem (elem), h->aux);
165 }
166 }
167}
#define ASSERT(CONDITION)
Definition: debug.h:30
static int next(int pos)
Definition: intq.c:74
Definition: list.h:93
Here is the call graph for this function:

◆ hash_bytes()

uint64_t hash_bytes ( const void *  buf_,
size_t  size 
)
246 {
247 /* Fowler-Noll-Vo 32-bit hash, for bytes. */
248 const unsigned char *buf = buf_;
250
251 ASSERT (buf != NULL);
252
254 while (size-- > 0)
255 hash = (hash * FNV_64_PRIME) ^ *buf++;
256
257 return hash;
258}
#define FNV_64_PRIME
Definition: hash.c:241
#define FNV_64_BASIS
Definition: hash.c:242
uint16_t size
Definition: mmu.h:0
unsigned long long int uint64_t
Definition: stdint.h:29
Definition: hash.h:58
Here is the caller graph for this function:

◆ hash_clear()

void hash_clear ( struct hash h,
hash_action_func destructor 
)
51 {
52 size_t i;
53
54 for (i = 0; i < h->bucket_cnt; i++) {
55 struct list *bucket = &h->buckets[i];
56
57 if (destructor != NULL)
58 while (!list_empty (bucket)) {
59 struct list_elem *list_elem = list_pop_front (bucket);
61 destructor (hash_elem, h->aux);
62 }
63
64 list_init (bucket);
65 }
66
67 h->elem_cnt = 0;
68}
struct list_elem * list_pop_front(struct list *)
Definition: list.c:251
void list_init(struct list *)
Definition: list.c:58
bool list_empty(struct list *)
Definition: list.c:296
size_t elem_cnt
Definition: hash.h:59
Here is the call graph for this function:
Here is the caller graph for this function:

◆ hash_cur()

struct hash_elem * hash_cur ( struct hash_iterator i)
224 {
225 return i->elem;
226}
struct hash_elem * elem
Definition: hash.h:71
Here is the caller graph for this function:

◆ hash_delete()

struct hash_elem * hash_delete ( struct hash h,
struct hash_elem e 
)
137 {
138 struct hash_elem *found = find_elem (h, find_bucket (h, e), e);
139 if (found != NULL) {
140 remove_elem (h, found);
141 rehash (h);
142 }
143 return found;
144}
static void remove_elem(struct hash *, struct hash_elem *)
Definition: hash.c:392
static struct hash_elem * find_elem(struct hash *, struct list *, struct hash_elem *)
Definition: hash.c:291
static struct list * find_bucket(struct hash *, struct hash_elem *)
Definition: hash.c:283
static void rehash(struct hash *)
Definition: hash.c:324
Here is the call graph for this function:
Here is the caller graph for this function:

◆ hash_destroy()

void hash_destroy ( struct hash h,
hash_action_func destructor 
)
81 {
82 if (destructor != NULL)
83 hash_clear (h, destructor);
84 free (h->buckets);
85}
void hash_clear(struct hash *h, hash_action_func *destructor)
Definition: hash.c:51
void free(void *)
Definition: malloc.c:202
Here is the call graph for this function:
Here is the caller graph for this function:

◆ hash_empty()

bool hash_empty ( struct hash h)
236 {
237 return h->elem_cnt == 0;
238}
Here is the caller graph for this function:

◆ hash_find()

struct hash_elem * hash_find ( struct hash h,
struct hash_elem e 
)
125 {
126 return find_elem (h, find_bucket (h, e), e);
127}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ hash_first()

void hash_first ( struct hash_iterator i,
struct hash h 
)
187 {
188 ASSERT (i != NULL);
189 ASSERT (h != NULL);
190
191 i->hash = h;
192 i->bucket = i->hash->buckets;
194}
struct list_elem * list_head(struct list *)
Definition: list.c:141
struct hash * hash
Definition: hash.h:69
struct list * bucket
Definition: hash.h:70
Here is the call graph for this function:
Here is the caller graph for this function:

◆ hash_init()

bool hash_init ( struct hash h,
hash_hash_func hash,
hash_less_func less,
void *  aux 
)
26 {
27 h->elem_cnt = 0;
28 h->bucket_cnt = 4;
29 h->buckets = malloc (sizeof *h->buckets * h->bucket_cnt);
30 h->hash = hash;
31 h->less = less;
32 h->aux = aux;
33
34 if (h->buckets != NULL) {
35 hash_clear (h, NULL);
36 return true;
37 } else
38 return false;
39}
void * malloc(size_t) __attribute__((malloc))
Definition: malloc.c:85
Here is the call graph for this function:
Here is the caller graph for this function:

◆ hash_insert()

struct hash_elem * hash_insert ( struct hash h,
struct hash_elem new 
)
94 {
95 struct list *bucket = find_bucket (h, new);
96 struct hash_elem *old = find_elem (h, bucket, new);
97
98 if (old == NULL)
99 insert_elem (h, bucket, new);
100
101 rehash (h);
102
103 return old;
104}
static void insert_elem(struct hash *, struct list *, struct hash_elem *)
Definition: hash.c:385
Here is the call graph for this function:
Here is the caller graph for this function:

◆ hash_int()

uint64_t hash_int ( int  i)
277 {
278 return hash_bytes (&i, sizeof i);
279}
uint64_t hash_bytes(const void *buf_, size_t size)
Definition: hash.c:246
Here is the call graph for this function:

◆ hash_next()

struct hash_elem * hash_next ( struct hash_iterator i)
205 {
206 ASSERT (i != NULL);
207
209 while (i->elem == list_elem_to_hash_elem (list_end (i->bucket))) {
210 if (++i->bucket >= i->hash->buckets + i->hash->bucket_cnt) {
211 i->elem = NULL;
212 break;
213 }
215 }
216
217 return i->elem;
218}
struct list_elem list_elem
Definition: hash.h:30
Here is the call graph for this function:
Here is the caller graph for this function:

◆ hash_replace()

struct hash_elem * hash_replace ( struct hash h,
struct hash_elem new 
)
109 {
110 struct list *bucket = find_bucket (h, new);
111 struct hash_elem *old = find_elem (h, bucket, new);
112
113 if (old != NULL)
114 remove_elem (h, old);
115 insert_elem (h, bucket, new);
116
117 rehash (h);
118
119 return old;
120}
Here is the call graph for this function:

◆ hash_size()

size_t hash_size ( struct hash h)
230 {
231 return h->elem_cnt;
232}

◆ hash_string()

uint64_t hash_string ( const char *  s_)
262 {
263 const unsigned char *s = (const unsigned char *) s_;
265
266 ASSERT (s != NULL);
267
269 while (*s != '\0')
270 hash = (hash * FNV_64_PRIME) ^ *s++;
271
272 return hash;
273}
static uint8_t s[256]
Definition: random.c:17

◆ insert_elem()

static void insert_elem ( struct hash h,
struct list bucket,
struct hash_elem e 
)
static
385 {
386 h->elem_cnt++;
387 list_push_front (bucket, &e->list_elem);
388}
void list_push_front(struct list *, struct list_elem *)
Definition: list.c:195
Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_power_of_2()

static size_t is_power_of_2 ( size_t  x)
inlinestatic
310 {
311 return x != 0 && turn_off_least_1bit (x) == 0;
312}
static size_t turn_off_least_1bit(size_t x)
Definition: hash.c:304
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rehash()

static void rehash ( struct hash h)
static
324 {
325 size_t old_bucket_cnt, new_bucket_cnt;
326 struct list *new_buckets, *old_buckets;
327 size_t i;
328
329 ASSERT (h != NULL);
330
331 /* Save old bucket info for later use. */
332 old_buckets = h->buckets;
333 old_bucket_cnt = h->bucket_cnt;
334
335 /* Calculate the number of buckets to use now.
336 We want one bucket for about every BEST_ELEMS_PER_BUCKET.
337 We must have at least four buckets, and the number of
338 buckets must be a power of 2. */
339 new_bucket_cnt = h->elem_cnt / BEST_ELEMS_PER_BUCKET;
340 if (new_bucket_cnt < 4)
341 new_bucket_cnt = 4;
342 while (!is_power_of_2 (new_bucket_cnt))
343 new_bucket_cnt = turn_off_least_1bit (new_bucket_cnt);
344
345 /* Don't do anything if the bucket count wouldn't change. */
346 if (new_bucket_cnt == old_bucket_cnt)
347 return;
348
349 /* Allocate new buckets and initialize them as empty. */
350 new_buckets = malloc (sizeof *new_buckets * new_bucket_cnt);
351 if (new_buckets == NULL) {
352 /* Allocation failed. This means that use of the hash table will
353 be less efficient. However, it is still usable, so
354 there's no reason for it to be an error. */
355 return;
356 }
357 for (i = 0; i < new_bucket_cnt; i++)
358 list_init (&new_buckets[i]);
359
360 /* Install new bucket info. */
361 h->buckets = new_buckets;
362 h->bucket_cnt = new_bucket_cnt;
363
364 /* Move each old element into the appropriate new bucket. */
365 for (i = 0; i < old_bucket_cnt; i++) {
366 struct list *old_bucket;
367 struct list_elem *elem, *next;
368
369 old_bucket = &old_buckets[i];
370 for (elem = list_begin (old_bucket);
371 elem != list_end (old_bucket); elem = next) {
372 struct list *new_bucket
374 next = list_next (elem);
375 list_remove (elem);
376 list_push_front (new_bucket, elem);
377 }
378 }
379
380 free (old_buckets);
381}
static size_t is_power_of_2(size_t x)
Definition: hash.c:310
#define BEST_ELEMS_PER_BUCKET
Definition: hash.c:316
struct list_elem * list_remove(struct list_elem *)
Definition: list.c:241
Here is the call graph for this function:
Here is the caller graph for this function:

◆ remove_elem()

static void remove_elem ( struct hash h,
struct hash_elem e 
)
static
392 {
393 h->elem_cnt--;
395}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ turn_off_least_1bit()

static size_t turn_off_least_1bit ( size_t  x)
inlinestatic
304 {
305 return x & (x - 1);
306}
Here is the caller graph for this function: