summaryrefslogtreecommitdiff
path: root/lib/hash.h
blob: 7464f140e218ebbbd56af07b5f496c244851d176 (plain)
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


#define HASH(type)		struct { type **data; uint used, size; }
#define HASH_TYPE(v)		typeof(** (v).data)
#define HASH_SIZE(v)		((v).size * sizeof(* (v).data))

#define HASH_INIT(v,pool,isize)						\
  ({									\
    (v).used = 0;							\
    (v).size = (isize);							\
    (v).data = mb_allocz(pool, HASH_SIZE(v));				\
  })

#define HASH_FIND(v,id,key)						\
  ({									\
    HASH_TYPE(v) *_n = (v).data[id##_FN(key, (v).size)];		\
    while (_n && !id##_EQ(_n, key))					\
      _n = _n->id##_NEXT;						\
    _n;									\
  })

#define HASH_INSERT(v,id,key,node)					\
  ({									\
    HASH_TYPE(v) **_nn = (v).data + id##_FN(key, (v).size);		\
    node->id##_NEXT = *_nn;						\
    *_nn = node;							\
  })

#define HASH_DELETE(v,id,key)						\
  ({									\
    HASH_TYPE(v) **_nn = (v).data + id##_FN(key, (v).size);		\
    while ((*_nn) && !id##_EQ(*_nn, key))				\
      _nn = &((*_nn)->id##_NEXT);					\
									\
    HASH_TYPE(v) *_n = *_nn;						\
    if (_n)								\
      *_nn = _n->id##_NEXT;						\
    _n;									\
  })

#define HASH_REMOVE(v,id,node)						\
  ({									\
    HASH_TYPE(v) **_nn = (v).data + id##_FN(key, (v).size);		\
    while ((*_nn) && (*_nn != (node)))					\
      _nn = &((*_nn)->id##_NEXT);					\
									\
    HASH_TYPE(v) *_n = *_nn;						\
    if (_n)								\
      *_nn = _n->id##_NEXT;						\
    _n;									\
  })



#define HASH_WALK(v,next,n)						\
  do {									\
    HASH_TYPE(v) *n;							\
    uint _i;								\
    for (_i = 0; _i < ((v).size); _i++)					\
      for (n = (v).data[_i]; n; n = n->next)

#define HASH_WALK_END } while (0)


#define HASH_WALK_DELSAFE(v,next,n)					\
  do {									\
    HASH_TYPE(v) *n, *_next;						\
    uint _i;								\
    for (_i = 0; _i < ((v).size); _i++)					\
      for (n = (v).data[_i]; n && (_next = n->next, 1); n = _next)

#define HASH_WALK_DELSAFE_END } while (0)

/*
define HASH_REHASH(s)							\
  ({									\
    type *_n;								\
    uint _i;								\
    for (_i = 0; _i < (size_f); _i++)					\
      for (_n = (hash)[_i]; _n != NULL; _n = 

*/