123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- /*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
- #include "headers.h"
- #define INITIALCHUNKSIZE 10
- typedef struct Entry {
- void *p;
- int32_t freechain;
- } Entry;
- struct SmbIdMap {
- Entry *array;
- uint32_t entries;
- int32_t freeindex;
- };
- SmbIdMap *
- smbidmapnew(void)
- {
- SmbIdMap *m;
- m = smbemallocz(sizeof(SmbIdMap), 1);
- m->freeindex = -1;
- return m;
- }
- void
- smbidmapremovebyid(SmbIdMap *m, int32_t id)
- {
- if (m == nil)
- return;
- assert(id > 0);
- id--;
- assert(id >= 0 && id < m->entries);
- assert(m->array[id].freechain == -2);
- m->array[id].freechain = m->freeindex;
- m->freeindex = id;
- }
- void
- smbidmapremove(SmbIdMap *m, void *thing)
- {
- int32_t id;
- if (m == nil)
- return;
- id = *(int32_t *)thing;
- smbidmapremovebyid(m, id);
- }
- void
- smbidmapremoveif(SmbIdMap *m, int (*f)(void *p, void *arg), void *arg)
- {
- int i;
- if (m == nil)
- return;
- for (i = 0; i < m->entries; i++)
- if (m->array[i].freechain == -2 && (*f)(m->array[i].p, arg))
- smbidmapremovebyid(m, i + 1);
- }
- static void
- grow(SmbIdMap *m)
- {
- int32_t x;
- int32_t oldentries = m->entries;
- if (m->entries == 0)
- m->entries = INITIALCHUNKSIZE;
- else
- m->entries *= 2;
- smberealloc(&m->array, sizeof(Entry) * m->entries);
- for (x = m->entries - 1; x >= oldentries; x--) {
- m->array[x].freechain = m->freeindex;
- m->freeindex = x;
- }
- }
- int32_t
- smbidmapadd(SmbIdMap *m, void *p)
- {
- int32_t i;
- if (m->freeindex < 0)
- grow(m);
- i = m->freeindex;
- m->freeindex = m->array[i].freechain;
- m->array[i].freechain = -2;
- m->array[i].p = p;
- *(int32_t *)p = i + 1;
- return i + 1;
- }
- void *
- smbidmapfind(SmbIdMap *m, int32_t id)
- {
- if (m == nil)
- return nil;
- if (id <= 0)
- return nil;
- id--;
- if (id < 0 || id > m->entries || m->array[id].freechain != -2)
- return nil;
- return m->array[id].p;
- }
- void
- smbidmapfree(SmbIdMap **mp, SMBIDMAPAPPLYFN *freefn, void *magic)
- {
- SmbIdMap *m = *mp;
- if (m) {
- int32_t i;
- if (freefn) {
- for (i = 0; i < m->entries; i++)
- if (m->array[i].freechain == -2)
- (*freefn)(magic, m->array[i].p);
- }
- free(m->array);
- free(m);
- *mp = nil;
- }
- }
- void
- smbidmapapply(SmbIdMap *m, SMBIDMAPAPPLYFN *applyfn, void *magic)
- {
- if (m) {
- int32_t i;
- for (i = 0; i < m->entries; i++)
- if (m->array[i].freechain == -2)
- (*applyfn)(magic, m->array[i].p);
- }
- }
|