in src/hashwriter.c [169:233]
static sparkey_returncode hash_put(uint64_t wanted_slot, uint64_t hash, uint8_t *hashtable, sparkey_hashheader *hash_header, sparkey_logiter *iter, sparkey_logiter *ra_iter, sparkey_logreader *log, uint64_t position) {
int slot_size = hash_header->address_size + hash_header->hash_size;
uint64_t pos = wanted_slot * slot_size;
uint64_t displacement = 0;
uint64_t slot = wanted_slot;
int might_be_collision = iter != NULL && ra_iter != NULL && log != NULL;
while (1) {
uint64_t hash2 = hash_header->hash_algorithm.read_hash(hashtable, pos);
uint64_t position2 = read_addr(hashtable, pos + hash_header->hash_size, hash_header->address_size);
if (position2 == 0) {
hash_header->hash_algorithm.write_hash(&hashtable[pos], hash);
write_addr(&hashtable[pos + hash_header->hash_size], position, hash_header->address_size);
added_entry(hash_header);
return SPARKEY_SUCCESS;
}
int entry_index2 = (int) (position2) & hash_header->entry_block_bitmask;
uint64_t position3 = position2 >> hash_header->entry_block_bits;
if (might_be_collision && hash == hash2) {
RETHROW(sparkey_logiter_seek(ra_iter, log, position3));
RETHROW(sparkey_logiter_skip(ra_iter, log, entry_index2));
RETHROW(sparkey_logiter_next(ra_iter, log));
uint64_t keylen2 = ra_iter->keylen;
uint64_t valuelen2 = ra_iter->valuelen;
if (ra_iter->type != SPARKEY_ENTRY_PUT) {
fprintf(stderr, "hash_put():%d bug: expected a put entry but found %d\n", __LINE__, ra_iter->type);
return SPARKEY_INTERNAL_ERROR;
}
if (iter->keylen == keylen2) {
RETHROW(sparkey_logiter_reset(iter, log));
int cmp;
RETHROW(sparkey_logiter_keycmp(iter, ra_iter, log, &cmp));
if (cmp == 0) {
hash_header->hash_algorithm.write_hash(&hashtable[pos], hash);
write_addr(&hashtable[pos + hash_header->hash_size], position, hash_header->address_size);
replaced_entry(hash_header, keylen2, valuelen2);
return SPARKEY_SUCCESS;
}
}
}
uint64_t other_displacement = get_displacement(hash_header->hash_capacity, slot, hash2);
if (displacement > other_displacement) {
// Steal the slot, and move the other one
hash_header->hash_algorithm.write_hash(&hashtable[pos], hash);
write_addr(&hashtable[pos + hash_header->hash_size], position, hash_header->address_size);
position = position2;
displacement = other_displacement;
hash = hash2;
might_be_collision = 0;
}
pos += slot_size;
displacement++;
slot++;
if (slot >= hash_header->hash_capacity) {
pos = 0;
slot = 0;
}
}
fprintf(stderr, "hash_put():%d bug: unreachable statement\n", __LINE__);
return SPARKEY_INTERNAL_ERROR;
}