in src/hashreader.c [130:194]
sparkey_returncode sparkey_hash_get(sparkey_hashreader *reader, const uint8_t *key, uint64_t keylen, sparkey_logiter *iter) {
RETHROW(assert_reader_open(reader));
uint64_t hash = reader->header.hash_algorithm.hash(key, keylen, reader->header.hash_seed);
uint64_t wanted_slot = hash % reader->header.hash_capacity;
int slot_size = reader->header.address_size + reader->header.hash_size;
uint64_t pos = wanted_slot * slot_size;
uint64_t displacement = 0;
uint64_t slot = wanted_slot;
uint8_t *hashtable = reader->data + reader->header.header_size;
while (1) {
uint64_t hash2 = reader->header.hash_algorithm.read_hash(hashtable, pos);
uint64_t position2 = read_addr(hashtable, pos + reader->header.hash_size, reader->header.address_size);
if (position2 == 0) {
iter->state = SPARKEY_ITER_INVALID;
return SPARKEY_SUCCESS;
}
int entry_index2 = (int) (position2) & reader->header.entry_block_bitmask;
position2 >>= reader->header.entry_block_bits;
if (hash == hash2) {
RETHROW(sparkey_logiter_seek(iter, &reader->log, position2));
RETHROW(sparkey_logiter_skip(iter, &reader->log, entry_index2));
RETHROW(sparkey_logiter_next(iter, &reader->log));
uint64_t keylen2 = iter->keylen;
if (iter->type != SPARKEY_ENTRY_PUT) {
iter->state = SPARKEY_ITER_INVALID;
return SPARKEY_INTERNAL_ERROR;
}
if (keylen == keylen2) {
uint64_t pos2 = 0;
int equals = 1;
while (pos2 < keylen) {
uint8_t *buf2;
uint64_t len2;
RETHROW(sparkey_logiter_keychunk(iter, &reader->log, keylen, &buf2, &len2));
if (memcmp(&key[pos2], buf2, len2) != 0) {
equals = 0;
break;
}
pos2 += len2;
}
if (equals) {
return SPARKEY_SUCCESS;
}
}
}
uint64_t other_displacement = get_displacement(reader->header.hash_capacity, slot, hash2);
if (displacement > other_displacement) {
iter->state = SPARKEY_ITER_INVALID;
return SPARKEY_SUCCESS;
}
pos += slot_size;
displacement++;
slot++;
if (slot >= reader->header.hash_capacity) {
pos = 0;
slot = 0;
}
}
iter->state = SPARKEY_ITER_INVALID;
return SPARKEY_INTERNAL_ERROR;
}