예제 #1
0
/*
 * 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]);
  }
}
예제 #2
0
/*
 * 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;
}