/* * Map name[i] to a new scope */ static void map(uint32_t i) { char *clone; assert(i < NSYMBOLS); if (scope[i] < UINT32_MAX) { clone = clone_string(name[i]); string_incref(clone); scope[i] ++; stbl_add(&sym_table, clone, scope[i]); } }
/* * Find or create record with the given key * - set is_new to true if that's a new record * - set is_new to false otherwise */ strmap_rec_t *strmap_get(strmap_t *hmap, const char *key, bool *is_new) { uint32_t mask, i, h; strmap_rec_t *d, *aux; char *clone; assert(is_power_of_two(hmap->size) && hmap->nelems + hmap->ndeleted < hmap->size); mask = hmap->size - 1; h = jenkins_hash_string(key); i = h & mask; for (;;) { d = hmap->data + i; if (! valid_key(d->key)) break; if (d->hash == h && strcmp(d->key, key) == 0) goto found; i ++; i &= mask; } aux = d; // this is where the new record will go if needed while(d->key != NULL) { i ++; i &= mask; if (d->key != DELETED_KEY && d->hash == h && strcmp(d->key, key) == 0) goto found; } // not found: add a new record hmap->nelems ++; clone = clone_string(key); string_incref(clone); if (hmap->nelems + hmap->ndeleted > hmap->resize_threshold) { // resize: we can't use the current aux strmap_extend(hmap); aux = strmap_get_clean(hmap, h); } aux->key = clone; aux->hash = h; aux->val = 0; *is_new = true; return aux; found: *is_new = false; return d; }