示例#1
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;
}
示例#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 ++;
  if (sym_table->nelems > sym_table->size) {
    stbl_extend(sym_table);
  }
}