sparkey_returncode sparkey_logiter_hashnext()

in src/hashreader.c [196:244]


sparkey_returncode sparkey_logiter_hashnext(sparkey_logiter *iter, sparkey_hashreader *reader) {
  RETHROW(assert_reader_open(reader));

  uint8_t *hashtable = reader->data + reader->header.header_size;
  int slot_size = reader->header.address_size + reader->header.hash_size;

  while (1) {
    RETHROW(sparkey_logiter_next(iter, &reader->log));
    if (iter->state != SPARKEY_ITER_ACTIVE) {
      return SPARKEY_SUCCESS;
    }
    if (iter->type != SPARKEY_ENTRY_PUT) {
      continue;
    }
    uint64_t position = (iter->entry_block_position << reader->header.entry_block_bits) | iter->entry_count;

    uint64_t key_hash = sparkey_iter_hash(&reader->header, iter, &reader->log);
    uint64_t wanted_slot = key_hash % reader->header.hash_capacity;

    uint64_t pos = wanted_slot * slot_size;

    uint64_t displacement = 0;
    uint64_t slot = wanted_slot;

    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) {
        break;
      }
      if (position == position2) {
        // Found a match! Just reset the iterator
        RETHROW(sparkey_logiter_reset(iter, &reader->log));
        return SPARKEY_SUCCESS;
      }
      uint64_t other_displacement = get_displacement(reader->header.hash_capacity, slot, hash2);
      if (displacement > other_displacement) {
        break;
      }
      pos += slot_size;
      displacement++;
      slot++;
      if (slot >= reader->header.hash_capacity) {
        pos = 0;
        slot = 0;
      }
    }
  }
}