/
index-hash.c
128 lines (91 loc) · 2.4 KB
/
index-hash.c
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
#include <stdio.h>
#include <sys/types.h>
#include <errno.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <pulsecore/macro.h>
#include <pulse/xmalloc.h>
#include "index-hash.h"
struct pa_index_hash_entry {
struct pa_index_hash_entry *next;
uint32_t index;
void *value;
};
struct pa_index_hash {
uint32_t mask;
struct pa_index_hash_entry **table;
};
struct pa_index_hash *pa_index_hash_init(uint32_t bits)
{
struct pa_index_hash *hash;
uint32_t max;
size_t size;
if (bits > 16)
bits = 16;
max = 1UL << bits;
size = sizeof(struct pa_index_hash_entry *) * max;
hash = pa_xmalloc0(size);
hash->mask = max - 1;
hash->table = pa_xmalloc0(size);
return hash;
}
void pa_index_hash_free(struct pa_index_hash *hash)
{
pa_xfree(hash->table);
pa_xfree(hash);
}
void pa_index_hash_add(struct pa_index_hash *hash, uint32_t index, void *value)
{
struct pa_index_hash_entry *entry, *prev;
pa_assert(hash);
pa_assert(hash->table);
prev = (struct pa_index_hash_entry *)(hash->table + (index & hash->mask));
while ((entry = prev->next) != NULL) {
if (index == entry->index) {
entry->value = value;
return;
}
prev = entry;
}
entry = pa_xmalloc0(sizeof(struct pa_index_hash_entry));
entry->index = index;
entry->value = value;
prev->next = entry;
}
void *pa_index_hash_remove(struct pa_index_hash *hash, uint32_t index)
{
struct pa_index_hash_entry *entry, *prev;
void *value;
pa_assert(hash);
pa_assert(hash->table);
prev = (struct pa_index_hash_entry *)(hash->table + (index & hash->mask));
while ((entry = prev->next) != NULL) {
if (index == entry->index) {
prev->next = entry->next;
value = entry->value;
pa_xfree(entry);
return value;
}
prev = entry;
}
return NULL;
}
void *pa_index_hash_lookup(struct pa_index_hash *hash, uint32_t index)
{
struct pa_index_hash_entry *entry;
pa_assert(hash);
pa_assert(hash->table);
for (entry = hash->table[index & hash->mask]; entry; entry = entry->next) {
if (index == entry->index)
return entry->value;
}
return NULL;
}
/*
* Local Variables:
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*
*/