1 /* This file is derived from src/lib9p/intmap.c from plan9port */
2 /* See LICENCE.p9p for terms of use */
7 #include <9p-mixp/intmap.h>
9 #include "mixp_local.h"
20 hashid(MIXP_INTMAP
*map
, unsigned long id
) {
29 void mixp_intmap_init(MIXP_INTMAP
*m
, unsigned long nhash
, void *hash
, const char* 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*))
45 for(i
=0; i
<map
->nhash
; i
++)
47 for(p
=map
->hash
[i
]; p
; p
=nlink
)
55 mixp_thread
->rwdestroy(&map
->lk
);
58 void mixp_intmap_exec(MIXP_INTMAP
*map
, void (*run
)(void*))
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
);
70 // printf("execmap: [%s] hid=%d id=%d aux=%ld\n", map->name, i, p->id, 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
];
93 void * mixp_intmap_lookupkey(MIXP_INTMAP
*map
, unsigned long id
)
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
);
104 static void * __real_insertkey(MIXP_INTMAP
* map
, unsigned long id
, void* value
)
106 int hid
= hashid(map
,id
);
108 Intlist
* elem
= map
->hash
[hid
];
114 // printf("insertkey [%s] updating id=%d addr=%ld value=%ld\n", map->name, id, elem, value);
121 elem
= calloc(1,sizeof(Intlist
));
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);
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);
138 mixp_thread
->wlock(&map
->lk
);
139 ov
= __real_insertkey(map
, id
, value
);
140 mixp_thread
->wunlock(&map
->lk
);
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
];
156 elem
= calloc(1,sizeof(Intlist
));
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);
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
);
175 static void* __real_deletekey(MIXP_INTMAP
* map
, unsigned long id
)
180 int hid
= hashid(map
,id
);
182 if (!(elem
= map
->hash
[hid
]))
184 // printf("branch %d not existing. nothing to do\n",hid);
190 /* the first in line is our element */
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
;
197 // printf(" --> now first: %ld\n", map->hash[hid]);
201 // printf("deletekey [%s] id=%d hid=%d firstelem=%ld magic=%d\n", map->name,id,hid,elem, elem->magic);
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 */
213 elem
->link
= next
->link
;
214 // printf("deleting somewhere. next is %ld\n", next->link);
222 void* mixp_intmap_deletekey(MIXP_INTMAP
*map
, unsigned long id
)
225 mixp_thread
->wlock(&map
->lk
);
226 ov
= __real_deletekey(map
,id
);
227 mixp_thread
->wunlock(&map
->lk
);