Пример #1
0
// Make a new hash table, with SIZE buckets initially.
// Hash table and its elements are allocated in region r.
HASH_FUNC_INLINE
hashset_table make_hashset_table(region r, unsigned long size //,
                                 // hash_fn hash, keyeq_fn cmp
  )
{
#if HASHSET_TABLE_SUPPORT_REGION
  if (!r) return make_hashset_table_owner(size /*, hash, cmp */);

  hashset_table ht;

  ht = ralloc(r, struct Hashset_table);
  ht->r = r;
  // ht->hash = hash;
  // ht->cmp = cmp;
  ht->used = 0;
  if (size) {
    size = hashset_init_size_pow2(ht, size);
    ht->table = rarrayalloc(ht->r, size, hash_key);
  } else {
    ht->log2size = 0;
    ht->table = NULL;
  }

  return ht;
#else
  assert(r == NULL);
  return make_hashset_table_owner(size);
#endif
}
Пример #2
0
/* Serialization */
void serialize_start(FILE *f, serialize_fn_ptr kind_map[], int length)
{
  assert(current_state == persist_raw);
  assert(f); 

  persist_rgn = newregion();
  current_state = persist_serializing;

  serialize_queue = new_persist_entry_queue(persist_rgn);
  serialized_objects = make_hash_table(persist_rgn, 128, ptr_hash, ptr_eq);
  
  current_file = f;
  num_kinds = length;
  serialize_fns = rarrayalloc(persist_rgn, length, serialize_fn_ptr);
  rarraycopy(serialize_fns, kind_map, length, serialize_fn_ptr);
}
Пример #3
0
static void add_cfg_node(region r, function_decl fd, void *n)
{
  if (fd->cfg_nextnode >= fd->cfg_size)
    {
      long oldsize = fd->cfg_size;
      node parentptr *oldnodes = fd->cfg_nodes;
      long newsize = 2 * oldsize, i;
      node parentptr *newnodes = rarrayalloc(r, newsize, node parentptr);

      for (i = 0; i < oldsize; i++)
	newnodes[i] = oldnodes[i];

      fd->cfg_size = newsize;
      fd->cfg_nodes = newnodes;
    }
  fd->cfg_nodes[fd->cfg_nextnode++] = CAST(node, n);
}
Пример #4
0
/* Reinsert all elements.  New size of table is (used*2) rounded up to a power
   of 2.  Duplicates are re-duplicated.  If using regions, the memory used by
   the old table is lost until region deletion. */
HASH_FUNC_INLINE
void hashset_rehash(hashset_table ht, hash_fn hash, keyeq_fn cmp)
{
#ifdef DEBUG
  // printf("Rehash table size=%ld, used=%ld\n", ht->size, ht->used);
#endif

  unsigned long old_table_size = hashset_table_capacity(ht);
  hash_key *old_table = ht->table;

  hashset_init_size_pow2(ht, ht->used*2);

#if HASHSET_TABLE_SUPPORT_REGION
  if (!ht->r) {
    ht->table = xcalloc(hashset_table_capacity(ht), sizeof(hash_key));
  } else {
    ht->table = rarrayalloc(ht->r, hashset_table_capacity(ht), hash_key);
  }
#else
  ht->table = xcalloc(hashset_table_capacity(ht), sizeof(hash_key));
#endif

  size_t i;
  for (i = 0; i < old_table_size; i++) {
    hash_key k = old_table[i];
    if (k == HASHSET_TOMBSTONE) {
      ht->used -= 1;
      continue;
    }

    if (k != NULL) {
      // For performance, we don't check for duplicates; use
      // hashset_rehash_check() if you want that.

      hashset_table_insert_internal(ht, hash, cmp, k);
    }
  }

#if HASHSET_TABLE_SUPPORT_REGION
  if (!ht->r) {
    free(old_table);
  }
#else
  free(old_table);
#endif
}
Пример #5
0
HASH_FUNC_INLINE
void hashset_table_convert_to_hash_mode(hashset_table ht, hash_fn hash, keyeq_fn cmp)
{
  // array mode
  hash_key *old_table = ht->table;
  size_t old_table_size = ht->used;

  // add 1 since we're about to insert after this; don't multiply by 2 because
  // the whole point of array mode is to save memory!
  hashset_init_size_pow2(ht, ht->used+1);

#if HASHSET_TABLE_SUPPORT_REGION
  if (!ht->r) {
    ht->table = xcalloc(hashset_table_capacity(ht), sizeof(hash_key));
  } else {
    ht->table = rarrayalloc(ht->r, hashset_table_capacity(ht), hash_key);
  }
#else
  ht->table = xcalloc(hashset_table_capacity(ht), sizeof(hash_key));
#endif

  size_t i;
  for (i = 0; i < old_table_size; i++) {
    hash_key k = old_table[i];
    assert(k != NULL && k != HASHSET_TOMBSTONE);
    hashset_table_insert_internal(ht, hash, cmp, k);
  }

  // ht->used doesn't change.

#if HASHSET_TABLE_SUPPORT_REGION
  if (!ht->r) {
    free(old_table);
  }
#else
  free(old_table);
#endif
}
Пример #6
0
/* Reinsert all elements, checking for duplicates */
HASH_FUNC_INLINE
void hashset_rehash_check(hashset_table ht,
                          hash_fn hash, keyeq_fn cmp)
{
  unsigned long old_table_size = hashset_table_capacity(ht);
  hash_key *old_table = ht->table;

  hashset_init_size_pow2(ht, ht->used*2);

#if HASHSET_TABLE_SUPPORT_REGION
  if (!ht->r) {
    ht->table = xcalloc(hashset_table_capacity(ht), sizeof(hash_key));
  } else {
    ht->table = rarrayalloc(ht->r, hashset_table_capacity(ht), hash_key);
  }
#else
  ht->table = xcalloc(hashset_table_capacity(ht), sizeof(hash_key));
#endif

  size_t i;
  for (i = 0; i < old_table_size; i++) {
    hash_key k = old_table[i];
    if (k == HASHSET_TOMBSTONE) {
      ht->used -= 1;
      continue;
    }

    if (k != NULL) {
      // inline the following but without hash check:
      //    hashset_table_insert(ht, key);

      size_t hashVal = hashset_find_bucket(ht, hash, k);
      size_t curIndex = hashVal;
      size_t i = 0;
      while (1) {
        hash_key key = ht->table[curIndex];

        if (key == NULL) {
          ht->table[curIndex] = k;
          break;
        }

        // no reason for the table we're creating to have tombstones!
        assert(key != HASHSET_TOMBSTONE);
        if (key == k || cmp(k, key)) {
          // duplicate!
          ht->used--;
          break;
        }

        ++i;
        curIndex = hashset_probe(ht, hashVal, i);
        assert(i < hashset_table_capacity(ht));
        assert(curIndex != hashVal);
      }
    }
  }

#if HASHSET_TABLE_SUPPORT_REGION
  if (!ht->r) {
    free(old_table);
  }
#else
  free(old_table);
#endif
}