-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathhtable.h
128 lines (105 loc) · 3.71 KB
/
htable.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
* htable.h : A generic hash table implementation
*
*
* Copyright (c) 2018 Partha Susarla <[email protected]>
*/
#ifndef XML2JSON_HTABLE_H
#define XML2JSON_HTABLE_H
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define ITER_IDX_END UINT_MAX
unsigned int bufhash(const void *buf, size_t len);
/* Comparison function */
typedef int (*htable_cmp_fn)(const void *data, const void *entry1,
const void *entry2, const void *kdata);
/* struct htable_entry represents an entry in the hash table
* and should be the first member in the user data structure for
* the entry.
*/
struct htable_entry {
struct htable_entry *next; /* next element in case of collision */
unsigned int hash;
unsigned int count; /* count of members in this entry */
unsigned int iter_prev, iter_next;
};
struct htable {
struct htable_entry **table;
htable_cmp_fn cmpfn;
const void *cmpfndata;
unsigned int count; /* number of entries */
size_t size; /* allocated size of the table */
unsigned int grow_mark;
unsigned int shrink_mark;
unsigned int iter_head, iter_tail;
};
extern void htable_init(struct htable *ht, htable_cmp_fn cmp_fn,
const void *cmpfndata, size_t size);
extern void htable_free(struct htable *ht, int free_entries);
/* htable_entry_init():
* initialise htable entry
*/
static inline void htable_entry_init(void *entry, unsigned int hash)
{
struct htable_entry *e = entry;
e->hash = hash;
e->next = NULL;
e->count = 0;
e->iter_prev = 0;
e->iter_next = 0;
}
/* htable_get():
* get the entry for a given key, NULL otherwise.
*/
extern void *htable_get(const struct htable *ht, const void *key,
const void *keydata);
/* htable_get_next():
* get the 'next' entry in the hash table, when there are duplicate entries
* becuase of collision, NULL if there are no duplicate entries. `entry` is
* where the lookup should start from.
*/
extern const void *htable_get_next(const struct htable *ht, const void *entry);
/* htable_put():
* adds a entry into the hash table. Allows duplicate entries.
*/
extern void htable_put(struct htable *ht, void *entry);
/* htable_replace():
* replace an entry in the hash table, if it exists. If the entry doesn't
* exist, it just adds a new entry(works like htable_add()).
* In case of replacement, it returns the current value of the entry.
*/
extern void *htable_replace(struct htable *ht, void *entry);
/* htable_remove():
* remove an entry in the hash table matching a specified key. If the key
* contains duplicate entries, only one will be removed. Returns the removed
* entry or NULL if no entry exists.
*/
extern void *htable_remove(struct htable *ht, const void *key,
const void *keydata);
/* hashtable iterator */
struct htable_iter {
struct htable *ht;
struct htable_entry *next;
unsigned int count;
unsigned int pos;
};
extern void htable_iter_init(struct htable *ht, struct htable_iter *iter);
extern void *htable_iter_next(struct htable_iter *iter);
extern void htable_iter_init_ordered(struct htable *ht,
struct htable_iter *iter);
extern void *htable_iter_ordered_get(struct htable_iter *iter);
extern void *htable_iter_next_ordered(struct htable_iter *iter);
static inline void *htable_iter_first(struct htable *ht,
struct htable_iter *iter)
{
htable_iter_init(ht, iter);
return htable_iter_next(iter);
}
#ifdef __cplusplus
}
#endif
#endif /* XML2JSON_HTABLE_H_ */