added gentoo ebuilds
[libmixp.git] / libmixp / intmap.c
blob6a4c4b8527f1f4c8a33c7e5b320d4cb8bc8d1bc2
1 /* This file is derived from src/lib9p/intmap.c from plan9port */
2 /* See LICENCE.p9p for terms of use */
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include <9p-mixp/intmap.h>
9 #include "mixp_local.h"
10 #include "util.h"
12 struct Intlist {
13 unsigned long id;
14 void* aux;
15 Intlist* link;
16 int magic;
19 static unsigned long
20 hashid(MIXP_INTMAP *map, unsigned long id) {
21 return id%map->nhash;
24 static void
25 nop(void *v) {
26 USED(v);
29 void mixp_intmap_init(MIXP_INTMAP *m, unsigned long nhash, void *hash, const char* name)
31 m->nhash = nhash;
32 m->hash = hash;
33 m->name = name;
34 memset(hash,0,sizeof(void*)*nhash);
35 mixp_thread->initrwlock(&m->lk);
38 void mixp_intmap_free(MIXP_INTMAP *map, void (*destroy)(void*))
40 int i;
41 Intlist *p, *nlink;
43 if(destroy == NULL)
44 destroy = nop;
45 for(i=0; i<map->nhash; i++)
47 for(p=map->hash[i]; p; p=nlink)
49 nlink = p->link;
50 destroy(p->aux);
51 MIXP_FREE(p);
55 mixp_thread->rwdestroy(&map->lk);
58 void mixp_intmap_exec(MIXP_INTMAP *map, void (*run)(void*))
60 int i;
61 Intlist *p, *nlink;
63 mixp_thread->rlock(&map->lk);
64 for(i=0; i<map->nhash; i++)
66 for(p=map->hash[i]; p; p=nlink)
68 mixp_thread->runlock(&map->lk);
69 nlink = p->link;
70 // printf("execmap: [%s] hid=%d id=%d aux=%ld\n", map->name, i, p->id, p->aux);
71 run(p->aux);
72 mixp_thread->rlock(&map->lk);
75 mixp_thread->runlock(&map->lk);
78 static void * __real_lookupkey(MIXP_INTMAP* map, unsigned long id)
80 int hid=hashid(map,id);
82 Intlist * elem = map->hash[hid];
83 while (elem)
85 if (elem->id == id)
86 return elem->aux;
87 elem = elem->link;
90 return NULL;
93 void * mixp_intmap_lookupkey(MIXP_INTMAP *map, unsigned long id)
95 void *v;
97 // printf("mixp_intmap_lookupkey [%s] id=%d\n", map->name, id);
98 mixp_thread->rlock(&map->lk);
99 v = __real_lookupkey(map,id);
100 mixp_thread->runlock(&map->lk);
101 return v;
104 static void * __real_insertkey(MIXP_INTMAP* map, unsigned long id, void* value)
106 int hid = hashid(map,id);
107 void* ov = NULL;
108 Intlist* elem = map->hash[hid];
110 while (elem)
112 if (elem->id==id)
114 // printf("insertkey [%s] updating id=%d addr=%ld value=%ld\n", map->name, id, elem, value);
115 ov = elem->aux;
116 elem->aux=value;
117 return ov;
121 elem = calloc(1,sizeof(Intlist));
122 elem->id = id;
123 elem->aux = value;
124 elem->link = map->hash[hid];
125 elem->magic = 666777;
126 map->hash[hid] = elem;
128 // printf("insertkey() [%s] added elem: id=%d addr=%ld value=%ld next=%ld\n",
129 // map->name, id, elem, value, elem->link);
130 return NULL;
133 void * mixp_intmap_insertkey(MIXP_INTMAP *map, unsigned long id, void* value)
135 // printf("insertkey [%s] id=%d value=%ld\n", map->name, id, value);
137 void* ov;
138 mixp_thread->wlock(&map->lk);
139 ov = __real_insertkey(map, id, value);
140 mixp_thread->wunlock(&map->lk);
141 return ov;
144 static int __real_caninsertkey(MIXP_INTMAP* map, unsigned long id, void* value)
146 int hid = hashid(map,id);
147 Intlist* elem=map->hash[hid];
149 while(elem)
151 if (elem->id==id)
152 return 0;
153 elem = elem->link;
156 elem = calloc(1,sizeof(Intlist));
157 elem->id = id;
158 elem->aux = value;
159 elem->link = map->hash[hid];
160 elem->magic = 777666;
161 map->hash[hid] = elem;
163 // printf("caninsertkey [%s] added: id=%d elem=%ld nextelem=%ld nn=%ld\n", map->name, id, elem, elem->link,map->hash[hid]->link);
164 return 1;
167 int mixp_intmap_caninsertkey(MIXP_INTMAP *map, unsigned long id, void *v)
169 mixp_thread->wlock(&map->lk);
170 int rv = __real_caninsertkey(map,id,v);
171 mixp_thread->wunlock(&map->lk);
172 return rv;
175 static void* __real_deletekey(MIXP_INTMAP* map, unsigned long id)
177 void *ov = NULL;
178 Intlist* elem;
180 int hid = hashid(map,id);
182 if (!(elem = map->hash[hid]))
184 // printf("branch %d not existing. nothing to do\n",hid);
185 return NULL;
188 if (elem->id == id)
190 /* the first in line is our element */
191 ov = elem->aux;
192 // printf("deletekey [%s] hid=%d id=%d\n", map->name, hid, id);
193 // printf(" -> deleting first in line: %ld (magic %d). next is: %ld\n", elem, elem->magic, elem->link);
194 map->hash[hid] = elem->link;
195 elem->aux = NULL;
196 MIXP_FREE(elem);
197 // printf(" --> now first: %ld\n", map->hash[hid]);
198 return ov;
201 // printf("deletekey [%s] id=%d hid=%d firstelem=%ld magic=%d\n", map->name,id,hid,elem, elem->magic);
203 Intlist *next;
204 while ((next = elem->link))
206 // printf("trying next: %ld\n", next);
207 // printf(" -> next->id=%d\n", next->id);
209 /* found it somewhere later in line */
210 if (next->id == id)
212 ov = next->aux;
213 elem->link = next->link;
214 // printf("deleting somewhere. next is %ld\n", next->link);
215 next->aux = NULL;
216 MIXP_FREE(next);
219 return ov;
222 void* mixp_intmap_deletekey(MIXP_INTMAP *map, unsigned long id)
224 void* ov;
225 mixp_thread->wlock(&map->lk);
226 ov = __real_deletekey(map,id);
227 mixp_thread->wunlock(&map->lk);
228 return ov;