2 * Copyright (C) 2008 Eduard-Gabriel Munteanu
4 * This file is released under GPL version 2.
8 * Simple hashtable for storing pointer-sized keyed data.
14 #include "hashtable.h"
16 struct ht_table
*__ht_create(size_t bits
, size_t entry_size
, size_t key_offset
)
19 size_t n_entries
= 1 << bits
;
21 ret
= malloc(sizeof(struct ht_table
));
24 ret
->entry
= calloc(n_entries
, sizeof(struct ht_entry
));
26 ret
->entry_size
= entry_size
;
27 ret
->key_offset
= key_offset
;
32 void ht_destroy(struct ht_table
*table
)
38 static inline unsigned long ht_hash(uint64_t key
, size_t bits
)
40 unsigned long ret
= (unsigned long) key
;
41 unsigned long mask
= (1 << bits
) - 1;
43 return (ret
^ (ret
>> 16)) & mask
;
46 static inline uint64_t *ht_get_key_ptr(struct ht_entry
*entry
,
47 struct ht_table
*table
)
49 return (uint64_t *) (entry
->data
+ table
->key_offset
);
52 static inline void ht_set_key(struct ht_entry
*entry
,
53 struct ht_table
*table
,
56 *ht_get_key_ptr(entry
, table
) = key
;
59 static inline uint64_t ht_get_key(struct ht_entry
*entry
,
60 struct ht_table
*table
)
62 return *ht_get_key_ptr(entry
, table
);
65 struct ht_entry
*ht_update_entry(struct ht_table
*table
, uint64_t key
)
67 struct ht_entry
*entry
;
68 unsigned long bucket
= ht_hash(key
, table
->bits
);
70 entry
= &table
->entry
[bucket
];
72 entry
->data
= calloc(1, table
->entry_size
);
73 ht_set_key(entry
, table
, key
);
77 if (ht_get_key(entry
, table
) == key
)
81 calloc(1, sizeof(struct ht_entry
));
83 calloc(1, table
->entry_size
);
84 ht_set_key(entry
->next
, table
, key
);
96 void ht_action(struct ht_table
*table
, void (*action
)(struct ht_entry
*, int))
99 struct ht_entry
*entry
, *next_entry
;
101 for (i
= 0; i
< (1 << table
->bits
); i
++) {
102 entry
= &table
->entry
[i
];
104 next_entry
= entry
->next
;
110 next_entry
= entry
->next
;
117 void ht_free_entry(struct ht_entry
*entry
, int freeable
)