static void unpack_entries(register st_table *table) { st_index_t i; st_packed_entry packed_bins[MAX_PACKED_HASH]; register st_table_entry *entry, *preventry = 0, **chain; st_table tmp_table = *table; MEMCPY(packed_bins, PACKED_BINS(table), st_packed_entry, MAX_PACKED_HASH); table->as.packed.entries = packed_bins; tmp_table.entries_packed = 0; #if ST_DEFAULT_INIT_TABLE_SIZE == ST_DEFAULT_PACKED_TABLE_SIZE MEMZERO(tmp_table.bins, st_table_entry*, tmp_table.num_bins); #else tmp_table.bins = st_realloc_bins(tmp_table.bins, ST_DEFAULT_INIT_TABLE_SIZE, tmp_table.num_bins); tmp_table.num_bins = ST_DEFAULT_INIT_TABLE_SIZE; #endif i = 0; chain = &tmp_table.head; do { st_data_t key = packed_bins[i].key; st_data_t val = packed_bins[i].val; st_index_t hash = packed_bins[i].hash; entry = new_entry(&tmp_table, key, val, hash, hash_pos(hash, ST_DEFAULT_INIT_TABLE_SIZE)); *chain = entry; entry->back = preventry; preventry = entry; chain = &entry->fore; } while (++i < MAX_PACKED_HASH); *chain = NULL; tmp_table.tail = entry; *table = tmp_table; }
int st_get_key(st_table *table, register st_data_t key, st_data_t *result) { st_index_t hash_val; register st_table_entry *ptr; hash_val = do_hash(key, table); if (table->entries_packed) { st_index_t i = find_packed_index(table, hash_val, key); if (i < table->real_entries) { if (result != 0) *result = PKEY(table, i); return 1; } return 0; } ptr = find_entry(table, key, hash_val, hash_pos(hash_val, table->num_bins)); if (ptr == 0) { return 0; } else { if (result != 0) *result = ptr->key; return 1; } }
int st_lookup(st_table *table, register st_data_t key, st_data_t *value) { st_index_t hash_val; register st_table_entry *ptr; hash_val = do_hash(key, table); if (table->entries_packed) { st_index_t i = find_packed_index(table, hash_val, key); if (i < table->real_entries) { if (value != 0) *value = PVAL(table, i); return 1; } return 0; } ptr = find_entry(table, key, hash_val, hash_pos(hash_val, table->num_bins)); if (ptr == 0) { return 0; } else { if (value != 0) *value = ptr->record; return 1; } }
void st_add_direct(st_table *table, st_data_t key, st_data_t value) { st_index_t hash_val; hash_val = do_hash(key, table); if (table->entries_packed) { add_packed_direct(table, key, value, hash_val); return; } add_direct(table, key, value, hash_val, hash_pos(hash_val, table->num_bins)); }
static void add_packed_direct(st_table *table, st_data_t key, st_data_t value, st_index_t hash_val) { if (table->real_entries < MAX_PACKED_HASH) { st_index_t i = table->real_entries++; PKEY_SET(table, i, key); PVAL_SET(table, i, value); PHASH_SET(table, i, hash_val); table->num_entries++; } else { unpack_entries(table); add_direct(table, key, value, hash_val, hash_pos(hash_val, table->num_bins)); } }
static void rehash(register st_table *table) { register st_table_entry *ptr, **new_bins; st_index_t new_num_bins, hash_val; new_num_bins = new_size(table->num_bins+1); new_bins = st_realloc_bins(table->bins, new_num_bins, table->num_bins); table->num_bins = new_num_bins; table->bins = new_bins; if ((ptr = table->head) != 0) { do { hash_val = hash_pos(ptr->hash, new_num_bins); ptr->next = new_bins[hash_val]; new_bins[hash_val] = ptr; } while ((ptr = ptr->fore) != 0); } }
static inline void add_direct(st_table *table, st_data_t key, st_data_t value, st_index_t hash_val, register st_index_t bin_pos) { register st_table_entry *entry; if (table->num_entries > ST_DEFAULT_MAX_DENSITY * table->num_bins) { rehash(table); bin_pos = hash_pos(hash_val, table->num_bins); } entry = new_entry(table, key, value, hash_val, bin_pos); if (table->head != 0) { entry->fore = 0; (entry->back = table->tail)->fore = entry; table->tail = entry; } else { table->head = table->tail = entry; entry->fore = entry->back = 0; } table->num_entries++; }
/* Used to determine data is located in the graph's adj list * returns data's position in graph's adj list if exists, -1 otherwise. */ static int vindex_lookup(struct graph *graph, void *data) { return hash_pos(graph->vidx, data); }