/* destroy */ void hashtable_destroy(struct hashtable *h, int free_values) { unsigned int i; struct entry *e, *f; struct entry **table = h->table; if (free_values) { for (i = 0; i < h->tablelength; i++) { e = table[i]; while (NULL != e) { f = e; e = e->next; freekey(f->k); free(f->v); free(f); } } } else { for (i = 0; i < h->tablelength; i++) { e = table[i]; while (NULL != e) { f = e; e = e->next; freekey(f->k); free(f); } } } free(h->table); free(h); }
/* destroy */ void hashtable_destroy(struct hashtable *h, int free_values) { #ifdef HASHTABLE_THREADED pthread_mutex_lock(&h->mutex); #endif unsigned int i; struct entry *e, *f; struct entry **table = h->table; if (free_values) { for (i = 0; i < h->tablelength; i++) { e = table[i]; while (NULL != e) { f = e; e = e->next; freekey(f->k); free(f->v); free(f); } } } else { for (i = 0; i < h->tablelength; i++) { e = table[i]; while (NULL != e) { f = e; e = e->next; freekey(f->k); free(f); } } } free(h->table); #ifdef HASHTABLE_THREADED pthread_mutex_destroy(&h->mutex); #endif free(h); }
static Key * parsechain(const char *s, const char *e, Key *spec) { const char *p, *q; Key *chain = NULL, *last = NULL; XPRINTF("Parsing chain from: '%s'\n", s); for (p = s; p < e; p = (*q == ':' ? q + 1 : q)) { Key *k; for (q = p; q < e && (isalnum(*q) || isblank(*q) || *q == '_' || *q == '+'); q++) ; if (q < e && *q != ':') q = e; k = ecalloc(1, sizeof(*k)); *k = *spec; if (!parsekey(p, q, k)) { freekey(k); freechain(chain); chain = last = NULL; break; } chain = chain ? : k; if (last) { last->func = &k_chain; last->chain = k; } last = k; } if (chain) XPRINTF("Parsed chain: %s\n", showchain(chain)); return chain; }
/* returns value associated with key */ void *hashtable_remove(struct hashtable *h, void *k) { /* TODO: consider compacting the table when the load factor drops enough, * or provide a 'compact' method. */ struct entry *e; struct entry **pE; void *v; unsigned int index = indexFor(h->tablelength,hash(h,k)); pE = &(h->table[index]); e = *pE; while (NULL != e) { if (h->eqfn(k, e->k)) { *pE = e->next; h->entrycount--; v = e->v; freekey(e->k); free(e); return v; } pE = &(e->next); e = e->next; } return NULL; }
void free_rbnode ( RBNODE node, void (*freekey)(void *), void (*freevalue)(void *) ){ assert(NULL!=node); freekey(node->key); if(NULL!=freevalue){freevalue(node->value);} free(node); }
int hashtable_iterator_remove(struct hashtable_itr *itr) { struct entry *remember_e, *remember_parent; int ret; /* Do the removal */ if (NULL == (itr->parent)) { /* element is head of a chain */ itr->h->table[itr->index] = itr->e->next; } else { /* element is mid-chain */ itr->parent->next = itr->e->next; } /* itr->e is now outside the hashtable */ remember_e = itr->e; itr->h->entrycount--; freekey(remember_e->k); /* Advance the iterator, correcting the parent */ remember_parent = itr->parent; ret = hashtable_iterator_advance(itr); if (itr->parent == remember_e) { itr->parent = remember_parent; } free(remember_e); return ret; }
int sa3adddecl (sa3cg cg, char* type, char* func, char* param) { uint32 size = 0; sa3decl* d = NULL; int saret = 0; uint16 keylen = 0; char* key = NULL; char* _func = NULL; CHK_CG (cg, saret); CHK_STR (type, saret); CHK_STR (func, saret); CHK_STR (param, saret); CALL_API (saret, getstruct (&size, (void**) &d, 3, type, func, param)); /* TODO: child thread start */ { _func = (char*) PI2PTR (d, d->func); // CALL_API (saret, getkey ("dl \0", (const char*) _func, &keylen, &key)); CALL_API (saret, put_ent (cg->pdb, _func, STRLEN(_func), (void*) d, size, DL)); } /* TODO: child thread end */ CLEANUP: if (NULL != d) { freestruct ((void**)&d); } if (NULL != key) { freekey (&key); } return saret; }
switch_hashtable_destroy(switch_hashtable_t **h) { unsigned int i; struct entry *e, *f; struct entry **table = (*h)->table; for (i = 0; i < (*h)->tablelength; i++) { e = table[i]; while (NULL != e) { f = e; e = e->next; if (f->flags & HASHTABLE_FLAG_FREE_KEY) { freekey(f->k); } if (f->flags & HASHTABLE_FLAG_FREE_VALUE) { switch_safe_free(f->v); } else if (f->destructor) { f->destructor(f->v); f->v = NULL; } switch_safe_free(f); } } switch_safe_free((*h)->table); free(*h); *h = NULL; }
int IteratorHashTableDelete(IteratorHashTable *itr) { struct entry *remember_e, *remember_parent; int ret; /* Do the removal */ if (NULL == (itr->parent)) { /* element is head of a chain */ itr->h->table[itr->index] = itr->e->next; } else { /* element is mid-chain */ itr->parent->next = itr->e->next; } /* itr->e is now outside the hashtable */ remember_e = itr->e; itr->h->entrycount--; freekey(remember_e->k); /* Advance the iterator, correcting the parent */ remember_parent = itr->parent; ret = IteratorHashTableNext(itr); if (itr->parent == remember_e) { itr->parent = remember_parent; } //FREE(remember_e); // was commented out, why? return ret; }
void * /* returns value associated with key */ hashtable_remove(struct hashtable *h, void *k) { /* TODO: consider compacting the table when the load factor drops enough, * or provide a 'compact' method. */ struct entry *e; struct entry **pE; void *v; unsigned int hashvalue, index; hashvalue = hash(h,k); index = indexFor(h->tablelength,hash(h,k)); pE = &(h->table[index]); e = *pE; while (NULL != e) { /* Check hash value to short circuit heavier comparison */ if ((hashvalue == e->h) && (h->eqfn(k, e->k))) { *pE = e->next; h->entrycount--; v = e->v; freekey(e->k); free(e); return v; } pE = &(e->next); e = e->next; } return NULL; }
/* * (*kp) and k have the same mod and keysym. Both have a non-null ->chain. * if there is a key in the (*kp)->chain list (*lp) that has the same mod and * keysm as k->chain, then free (*lp) and set its location to *kp->chain */ static void mergechain(Key *c, Key *k) { Key **lp; Key *next = k->chain; XPRINTF("Merging chain %s\n", showchain(k)); XPRINTF(" into chain %s\n", showchain(c)); k->chain = NULL; freekey(k); k = next; for (lp = &c->chain; *lp; lp = &(*lp)->cnext) if ((*lp)->mod == k->mod && (*lp)->keysym == k->keysym) break; if (*lp) { if ((*lp)->chain && k->chain) mergechain(*lp, k); else { XPRINTF("Overriding previous key alternate %s!\n", showchain(k)); k->cnext = (*lp)->cnext; (*lp)->cnext = NULL; freechain(*lp); *lp = k; } } else { k->cnext = NULL; *lp = k; } }
/* destroy */ void HashTableDestroy(HashTable *h, int free_values) { unsigned int i; struct entry *e, *f; struct entry **table = h->table; if (free_values) { for (i = 0; i < h->tablelength; i++) { e = table[i]; while (NULL != e) { f = e; e = e->next; freekey(f->k); FREE(f->v); FREE(f); } } } else { for (i = 0; i < h->tablelength; i++) { e = table[i]; while (NULL != e) { f = e; e = e->next; /* freekey(f->k); */ FREE(f); } } } FREE(h->table); FREE(h); }
/* returns value associated with key */ void * hashtable_remove(struct hashtable *h, void *k) { /* TODO: consider compacting the table when the load factor drops enough, * or provide a 'compact' method. */ struct hash_entry *e; struct hash_entry **pE; void *v; unsigned int hashvalue, index; hashvalue = hash(h,k); //NOTE: tablelength is read-only if dynamic expansion is disabled index = indexFor(h->tablelength,hash(h,k)); //Proper locking required pE = &(h->table[index]); e = *pE; while (NULL != e) { /* Check hash value to short circuit heavier comparison */ if ((hashvalue == e->h) && (h->eqfn(k, e->k))) { *pE = e->next; #ifdef ENABLE_DYNAMIC_EXPANSION h->entrycount--; #endif v = e->v; if(h->free_keys) freekey(e->k); free(e); return v; } pE = &(e->next); e = e->next; } return NULL; }
int sa3addcall (sa3cg cg, char* cr, char* cd) { /* Thread #0 parser */ uint32 size = 0; sa3call* c = NULL; int saret = 0; uint16 pklen = 0; uint16 fklen = 0; char* pk = NULL; char* tmpcr = NULL; CHK_CG (cg, saret); CHK_STR (cr, saret); CHK_STR (cd, saret); CALL_API (saret, getstruct (&size, (void**)&c, 2, cr, cd)); CALL_API (saret, put_ent (cg->pdb, NULL, 0, (void*) c, size, CR)); CLEANUP: if (NULL != pk) { freekey (&pk); } return saret; }
void update_keys(void) { Key *k; char *l, *p; numlock_mask = numlockmask(); valid_mask = 0xff & ~(numlock_mask | LockMask); while((k = key)) { key = key->lnext; ungrabkey(k); freekey(k); } for(l = p = def.keys; p && *p; p++) { if(*p == '\n') { *p = 0; if((k = getkey(l))) grabkey(k); *p = '\n'; l = p + 1; } } if(l < p && strlen(l)) { if((k = getkey(l))) grabkey(k); } }
static void * _switch_hashtable_remove(switch_hashtable_t *h, void *k, unsigned int hashvalue, unsigned int index) { /* TODO: consider compacting the table when the load factor drops enough, * or provide a 'compact' method. */ struct entry *e; struct entry **pE; void *v; pE = &(h->table[index]); e = *pE; while (NULL != e) { /* Check hash value to short circuit heavier comparison */ if ((hashvalue == e->h) && (h->eqfn(k, e->k))) { *pE = e->next; h->entrycount--; v = e->v; if (e->flags & HASHTABLE_FLAG_FREE_KEY) { freekey(e->k); } if (e->flags & HASHTABLE_FLAG_FREE_VALUE) { switch_safe_free(e->v); v = NULL; } else if (e->destructor) { e->destructor(e->v); v = e->v = NULL; } switch_safe_free(e); return v; } pE = &(e->next); e = e->next; } return NULL; }
void tdestroy(void *root, void (*freekey)(void *)) { struct node *r = root; if (r == 0) return; tdestroy(r->left, freekey); tdestroy(r->right, freekey); if (freekey) freekey(r->key); free(r); }
/* destroy */ void hashtable_destroy(struct hashtable *h, int free_values) { unsigned int i; struct entry *e, *f; struct entry **table = h->table; if (free_values) { for (i = 0; i < h->tablelength; i++) { e = table[i]; while (NULL != e) { f = e; e = e->next; freekey(f->k); free(f->v); free(f); } } } else { for (i = 0; i < h->tablelength; i++) { e = table[i]; while (NULL != e) { f = e; e = e->next; freekey(f->k); free(f); } } } // Destroy locks if (pthread_rwlock_destroy(&h->globallock)) { perror("pthread_rwlock_destroy"); } if (pthread_rwlock_destroy(&h->entrycountlock)) { perror("pthread_rwlock_destroy"); } for(int i = 0; i < h->tablelength; ++i) { if (pthread_rwlock_destroy(&h->locks[i])) { perror("pthread_rwlock_destroy"); } } free(h->locks); free(h->table); free(h); }
hashtable_destroy(struct hashtable *h) { unsigned int i; struct entry *e, *f; struct entry **table = h->table; for (i = 0; i < h->tablelength; i++) { e = table[i]; while (NULL != e) { f = e; e = e->next; if (f->flags & HASHTABLE_FLAG_FREE_KEY) freekey(f->k); if (f->flags & HASHTABLE_FLAG_FREE_VALUE) free(f->v); free(f); } } free(h->table); free(h); }
void * /* returns value associated with key */ hashtable_remove(struct hashtable *h, void *k) { /* TODO: consider compacting the table when the load factor drops enough, * or provide a 'compact' method. */ struct entry *e; struct entry **pE; void *v; unsigned int hashvalue, index; // Use global read lock for hashing/indexing rwlock_rdlock(&h->globallock); hashvalue = hash(h,k); index = indexFor(h->tablelength,hash(h,k)); rwlock_rdunlock(&h->globallock); // Use local write lock for removal rwlock_wrlock(&h->locks[index]); pE = &(h->table[index]); e = *pE; while (NULL != e) { /* Check hash value to short circuit heavier comparison */ if ((hashvalue == e->h) && (h->eqfn(k, e->k))) { *pE = e->next; // Use write lock for entry count decrement rwlock_wrlock(&h->entrycountlock); h->entrycount--; rwlock_wrunlock(&h->entrycountlock); v = e->v; freekey(e->k); free(e); rwlock_wrunlock(&h->locks[index]); return v; } pE = &(e->next); e = e->next; } rwlock_wrunlock(&h->locks[index]); return NULL; }
void freechain(Key *k) { Key *c, *cnext; if (k) { XPRINTF("Freeing chain: %p: %s\n", k, showchain(k)); cnext = k->chain; k->chain = NULL; while ((c = cnext)) { cnext = c->cnext; c->cnext = NULL; freechain(c); } freekey(k); } }
int freekey_r(int key) { /* free the key */ int error; if (error = pthread_mutex_lock(&listlock)) { /* no mutex, give up */ errno = error; return -1; } if (freekey(key) == -1) { error = errno; pthread_mutex_unlock(&listlock); errno = error; return -1; } if (error = pthread_mutex_unlock(&listlock)) { errno = error; return -1; } return 0; }
static Key* getkey(const char *name) { Key *k, *r; char buf[128]; char *seq[8]; char *kstr; int mask; uint i, toks; static ushort id = 1; r = nil; if((k = name2key(name))) { ungrabkey(k); return k; } utflcpy(buf, name, sizeof buf); toks = tokenize(seq, 8, buf, ','); for(i = 0; i < toks; i++) { if(!k) r = k = emallocz(sizeof *k); else { k->next = emallocz(sizeof *k); k = k->next; } utflcpy(k->name, name, sizeof k->name); if(parsekey(seq[i], &mask, &kstr)) { k->key = keycode(kstr); k->mod = mask; } if(k->key == 0) { freekey(r); return nil; } } if(r) { r->id = id++; r->lnext = key; key = r; } return r; }