]>
Commit | Line | Data |
---|---|---|
bf139664 OZ |
1 | |
2 | ||
6a8d3f1c | 3 | #define HASH(type) struct { type **data; uint count, order; } |
bf139664 | 4 | #define HASH_TYPE(v) typeof(** (v).data) |
6a8d3f1c OZ |
5 | #define HASH_SIZE(v) (1 << (v).order) |
6 | #define HASH_MASK(v) ((1 << (v).order)-1) | |
bf139664 | 7 | |
6a8d3f1c OZ |
8 | |
9 | #define HASH_INIT(v,pool,init_order) \ | |
bf139664 | 10 | ({ \ |
6a8d3f1c OZ |
11 | (v).count = 0; \ |
12 | (v).order = (init_order); \ | |
13 | (v).data = mb_allocz(pool, HASH_SIZE(v) * sizeof(* (v).data)); \ | |
bf139664 OZ |
14 | }) |
15 | ||
6a8d3f1c | 16 | #define HASH_FIND(v,id,key...) \ |
bf139664 | 17 | ({ \ |
6a8d3f1c OZ |
18 | uint _h = id##_FN((key)) & HASH_MASK(v); \ |
19 | HASH_TYPE(v) *_n = (v).data[_h]; \ | |
20 | while (_n && !id##_EQ(id##_KEY(_n), (key))) \ | |
21 | _n = id##_NEXT(_n); \ | |
bf139664 OZ |
22 | _n; \ |
23 | }) | |
24 | ||
6a8d3f1c | 25 | #define HASH_INSERT(v,id,node) \ |
bf139664 | 26 | ({ \ |
6a8d3f1c OZ |
27 | uint _h = id##_FN(id##_KEY((node))) & HASH_MASK(v); \ |
28 | HASH_TYPE(v) **_nn = (v).data + _h; \ | |
29 | id##_NEXT(node) = *_nn; \ | |
bf139664 | 30 | *_nn = node; \ |
6a8d3f1c | 31 | (v).count++; \ |
bf139664 OZ |
32 | }) |
33 | ||
6a8d3f1c | 34 | #define HASH_DO_REMOVE(v,id,_nn) \ |
bf139664 | 35 | ({ \ |
bf139664 OZ |
36 | HASH_TYPE(v) *_n = *_nn; \ |
37 | if (_n) \ | |
6a8d3f1c OZ |
38 | { \ |
39 | *_nn = id##_NEXT(_n); \ | |
40 | (v).count--; \ | |
41 | } \ | |
bf139664 OZ |
42 | _n; \ |
43 | }) | |
44 | ||
6a8d3f1c OZ |
45 | #define HASH_DELETE(v,id,key...) \ |
46 | ({ \ | |
47 | uint _h = id##_FN((key)) & HASH_MASK(v); \ | |
48 | HASH_TYPE(v) **_nn = (v).data + _h; \ | |
49 | \ | |
50 | while ((*_nn) && !id##_EQ(id##_KEY((*_nn)), (key))) \ | |
51 | _nn = &(id##_NEXT((*_nn))); \ | |
52 | \ | |
53 | HASH_DO_REMOVE(v,id,_nn); \ | |
54 | }) | |
55 | ||
bf139664 OZ |
56 | #define HASH_REMOVE(v,id,node) \ |
57 | ({ \ | |
6a8d3f1c OZ |
58 | uint _h = id##_FN(id##_KEY((node))) & HASH_MASK(v); \ |
59 | HASH_TYPE(v) **_nn = (v).data + _h; \ | |
60 | \ | |
bf139664 | 61 | while ((*_nn) && (*_nn != (node))) \ |
6a8d3f1c | 62 | _nn = &(id##_NEXT((*_nn))); \ |
bf139664 | 63 | \ |
6a8d3f1c | 64 | HASH_DO_REMOVE(v,id,_nn); \ |
bf139664 OZ |
65 | }) |
66 | ||
67 | ||
6a8d3f1c OZ |
68 | #define HASH_REHASH(v,id,pool,step) \ |
69 | ({ \ | |
70 | HASH_TYPE(v) *_n, *_n2, **_od; \ | |
71 | uint _i, _s; \ | |
72 | \ | |
73 | _s = HASH_SIZE(v); \ | |
74 | _od = (v).data; \ | |
75 | (v).count = 0; \ | |
76 | (v).order += (step); \ | |
77 | (v).data = mb_allocz(pool, HASH_SIZE(v) * sizeof(* (v).data)); \ | |
78 | \ | |
79 | for (_i = 0; _i < _s; _i++) \ | |
80 | for (_n = _od[_i]; _n && (_n2 = id##_NEXT(_n), 1); _n = _n2) \ | |
81 | HASH_INSERT(v, id, _n); \ | |
82 | \ | |
83 | mb_free(_od); \ | |
84 | }) | |
85 | ||
86 | #define HASH_DEFINE_REHASH_FN(id, type) \ | |
87 | static void id##_REHASH_FN(void *v, pool *p, int step) \ | |
88 | { HASH_REHASH(* (HASH(type) *) v, id, p, step); } | |
89 | ||
90 | #define HASH_TRY_REHASH_UP(v,id,pool) \ | |
91 | ({ \ | |
92 | if (((v).order < id##_REHASH_MAX) && ((v).count > HASH_SIZE(v))) \ | |
93 | id##_REHASH_FN(&v, pool, 1); \ | |
94 | }) | |
95 | ||
96 | #define HASH_TRY_REHASH_DOWN(v,id,pool) \ | |
97 | ({ \ | |
98 | if (((v).order > id##_REHASH_MIN) && ((v).count < HASH_SIZE(v)/2)) \ | |
99 | id##_REHASH_FN(&v, pool, -1); \ | |
100 | }) | |
bf139664 OZ |
101 | |
102 | #define HASH_WALK(v,next,n) \ | |
103 | do { \ | |
104 | HASH_TYPE(v) *n; \ | |
105 | uint _i; \ | |
6a8d3f1c OZ |
106 | uint _s = HASH_SIZE(v); \ |
107 | for (_i = 0; _i < _s; _i++) \ | |
bf139664 OZ |
108 | for (n = (v).data[_i]; n; n = n->next) |
109 | ||
110 | #define HASH_WALK_END } while (0) | |
111 | ||
112 | ||
113 | #define HASH_WALK_DELSAFE(v,next,n) \ | |
114 | do { \ | |
115 | HASH_TYPE(v) *n, *_next; \ | |
116 | uint _i; \ | |
6a8d3f1c OZ |
117 | uint _s = HASH_SIZE(v); \ |
118 | for (_i = 0; _i < _s; _i++) \ | |
bf139664 OZ |
119 | for (n = (v).data[_i]; n && (_next = n->next, 1); n = _next) |
120 | ||
121 | #define HASH_WALK_DELSAFE_END } while (0) | |
122 | ||
bf139664 | 123 |