// ---------------------------------------------------------------- // Used by get() and remove(). // Returns >=0 for where the key is *or* should go (end of chain). static int hss_find_index_for_key(hss_t* pset, char* key, int* pideal_index) { int hash = mlr_string_hash_func(key); int index = mlr_canonical_mod(hash, pset->array_length); *pideal_index = index; int num_tries = 0; while (TRUE) { hsse_t* pe = &pset->array[index]; if (pe->state == OCCUPIED) { char* ekey = pe->key; // Existing key found in chain. if (streq(key, ekey)) return index; } else if (pe->state == EMPTY) { return index; } // If the current entry has been freed, i.e. previously occupied, // the sought index may be further down the chain. So we must // continue looking. if (++num_tries >= pset->array_length) { fprintf(stderr, "internal coding error: table full even after enlargement.\n"); exit(1); } // Linear probing. if (++index >= pset->array_length) index = 0; } MLR_INTERNAL_CODING_ERROR(); }
// ---------------------------------------------------------------- // Used by get() and remove(). // Returns >0 for where the key is *or* should go (end of chain). static int lhmsv_find_index_for_key(lhmsv_t* pmap, char* key) { int hash = mlr_string_hash_func(key); int index = mlr_canonical_mod(hash, pmap->array_length); int num_tries = 0; int done = 0; while (!done) { lhmsve_t* pe = &pmap->entries[index]; if (pmap->states[index] == OCCUPIED) { char* ekey = pe->key; // Existing key found in chain. if (streq(key, ekey)) return index; } else if (pmap->states[index] == EMPTY) { return index; } // If the current entry has been deleted, i.e. previously occupied, // the sought index may be further down the chain. So we must // continue looking. if (++num_tries >= pmap->array_length) { fprintf(stderr, "Coding error: table full even after enlargement.\n"); exit(1); } // Linear probing. if (++index >= pmap->array_length) index = 0; } return -1; // xxx not reached }
// ---------------------------------------------------------------- // Used by get() and remove(). // Returns >0 for where the key is *or* should go (end of chain). static int lhmsv_find_index_for_key(lhmsv_t* pmap, char* key, int* pideal_index) { int hash = mlr_string_hash_func(key); int index = mlr_canonical_mod(hash, pmap->array_length); *pideal_index = index; int num_tries = 0; while (TRUE) { lhmsve_t* pe = &pmap->entries[index]; if (pmap->states[index] == OCCUPIED) { char* ekey = pe->key; // Existing key found in chain. if (streq(key, ekey)) return index; } else if (pmap->states[index] == EMPTY) { return index; } // If the current entry has been deleted, i.e. previously occupied, // the sought index may be further down the chain. So we must // continue looking. if (++num_tries >= pmap->array_length) { fprintf(stderr, "%s: internal coding error: table full even after enlargement.\n", MLR_GLOBALS.argv0); exit(1); } // Linear probing. if (++index >= pmap->array_length) index = 0; } fprintf(stderr, "%s: internal coding error detected in file %s at line %d.\n", MLR_GLOBALS.argv0, __FILE__, __LINE__); exit(1); }
static void lhmsv_put_no_enlarge(lhmsv_t* pmap, char* key, void* pvvalue) { int index = lhmsv_find_index_for_key(pmap, key); lhmsve_t* pe = &pmap->entries[index]; if (pmap->states[index] == OCCUPIED) { // Existing key found in chain; put value. if (streq(pe->key, key)) { pe->pvvalue = pvvalue; } } else if (pmap->states[index] == EMPTY) { // End of chain. pe->ideal_index = mlr_canonical_mod(mlr_string_hash_func(key), pmap->array_length); // xxx comment all malloced. pe->key = strdup(key); pe->pvvalue = pvvalue; pmap->states[index] = OCCUPIED; if (pmap->phead == NULL) { pe->pprev = NULL; pe->pnext = NULL; pmap->phead = pe; pmap->ptail = pe; } else { pe->pprev = pmap->ptail; pe->pnext = NULL; pmap->ptail->pnext = pe; pmap->ptail = pe; } pmap->num_occupied++; } else { fprintf(stderr, "lhmsv_find_index_for_key did not find end of chain.\n"); exit(1); } }