sparkey_returncode sparkey_hash_get()

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;
}