Exemple #1
0
/*
 * Return value of first occurrence of symbol, or -1 if symbol is not
 * present
 */
int32_t stbl_find(stbl_t *sym_table, const char *symbol) {
  uint32_t mask, i, h;
  stbl_rec_t *r;

  mask = sym_table->size - 1;
  h = jenkins_hash_string(symbol);
  i = h & mask;
  for (r = sym_table->data[i]; r != NULL; r = r->next) {
    if (r->hash == h && strcmp(symbol, r->string) == 0) {
      return r->value;
    }
  }

  return -1;
}
Exemple #2
0
/*
 * Add new mapping for symbol.
 */
void stbl_add(stbl_t *sym_table, char *symbol, int32_t value) {
  uint32_t mask, i, h;
  stbl_rec_t *r;

  assert(value >= 0);
  mask = sym_table->size - 1;
  h = jenkins_hash_string(symbol);
  i = h & mask;

  r = stbl_alloc_record(sym_table);
  stbl_init_record(r, h, value, symbol);
  r->next = sym_table->data[i];
  sym_table->data[i] = r;

  sym_table->nelems ++;
}
Exemple #3
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;
}
Exemple #4
0
/*
 * Return value of first occurrence of symbol, or -1 if symbol is not
 * present.
 * - update the cost
 */
int32_t stbl_find(stbl_t *sym_table, const char *symbol) {
  uint32_t mask, i, h, steps;
  int32_t result;
  stbl_rec_t *r;

  result = -1;
  steps = 0;
  mask = sym_table->size - 1;
  h = jenkins_hash_string(symbol);
  i = h & mask;
  for (r = sym_table->data[i]; r != NULL; r = r->next) {
    steps ++;
    if (r->hash == h && strcmp(symbol, r->string) == 0) {
      result = r->value;
      break;
    }
  }

  /*
   * Check whether the list contains many duplicates and move r to the
   * front if possible. If the list has duplicates, we reduce steps to 1,
   * since resizing won't help much.
   */
  if (steps > STBL_MAXVISITS && list_has_duplicates(sym_table, i, r)) {
    steps = 1;
  }

  /*
   * Update cost and counter. Resize if the last NLOOKUPS have a
   * high total cost.
   */
  assert(sym_table->lctr > 0);
  sym_table->cost += steps;
  sym_table->lctr --;
  if (sym_table->lctr == 0) {
    if (sym_table->cost > STBL_RESIZE_THRESHOLD && sym_table->size <= (MAX_STBL_SIZE/2)) {
      stbl_extend(sym_table);
    }
    sym_table->cost = 0;
    sym_table->lctr = STBL_NLOOKUPS;
  }

  return result;
}
Exemple #5
0
/*
 * Search for record with the given key
 * - return NULL if not found
 */
strmap_rec_t *strmap_find(strmap_t *hmap, const char *key) {
  uint32_t mask, i, h;
  strmap_rec_t *d;

  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 (d->key == NULL) return NULL;
    if (d->key != DELETED_KEY && d->hash == h && strcmp(d->key, key) == 0) {
      return d;
    }
    i ++;
    i &= mask;
  }
}
Exemple #6
0
/*
 * Remove the first occurrence of (symbol, value).
 * No effect if it's not present.
 */
void stbl_delete_mapping(stbl_t *sym_table, const char *symbol, int32_t val) {
  uint32_t h, mask, i;
  stbl_rec_t *r, *p;

  mask = sym_table->size - 1;
  h = jenkins_hash_string(symbol);
  i = h & mask;
  p = NULL;
  for (r = sym_table->data[i]; r != NULL; r = r->next) {
    if (r->hash == h && r->value == val && strcmp(symbol, r->string) == 0) {
      if (p == NULL) {
        sym_table->data[i] = r->next;
      } else {
        p->next = r->next;
      }
      sym_table->finalize(r);
      stbl_free_record(sym_table, r);
      return;
    }
    p = r;
  }
}