static sparkey_returncode hash_delete()

in src/hashwriter.c [88:167]


static sparkey_returncode hash_delete(uint64_t wanted_slot, uint64_t hash, uint8_t *hashtable, sparkey_hashheader *hash_header, sparkey_logiter *iter, sparkey_logiter *ra_iter, sparkey_logreader *log) {
  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;

  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) {
        return SPARKEY_SUCCESS;
    }
    int entry_index2 = (int) (position2) & hash_header->entry_block_bitmask;
    position2 >>= hash_header->entry_block_bits;
    if (position2 < log->header.header_size || position2 >= log->header.data_end ) {
      fprintf(stderr, "hash_delete():%d bug: found pointer outside of range %"PRIu64"\n", __LINE__, position2);
      return SPARKEY_INTERNAL_ERROR;
    }
    if (hash == hash2) {
      RETHROW(sparkey_logiter_seek(ra_iter, log, position2));
      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_delete():%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) {
          // TODO: possibly optimize this to read and write stuff to move in chunks instead of one by one, to decrease number of seeks.
          while (1) {
            uint64_t next_slot = (slot + 1) % hash_header->hash_capacity;
            uint64_t next_pos = next_slot * slot_size;

            uint64_t hash3 = hash_header->hash_algorithm.read_hash(hashtable, next_pos);
            uint64_t position3 = read_addr(hashtable, next_pos + hash_header->hash_size, hash_header->address_size);
            if (position3 == 0) {
                break;
            }
            if ((hash3 % hash_header->hash_capacity) == next_slot) {
                break;
            }

            uint64_t pos3 = slot * slot_size;
            hash_header->hash_algorithm.write_hash(&hashtable[pos3], hash3);
            write_addr(&hashtable[pos3 + hash_header->hash_size], position3, hash_header->address_size);

            slot = next_slot;
          }

          uint64_t pos3 = slot * slot_size;
          hash_header->hash_algorithm.write_hash(&hashtable[pos3], 0);
          write_addr(&hashtable[pos3 + hash_header->hash_size], 0, hash_header->address_size);
          deleted_entry(hash_header, keylen2, valuelen2);

          return SPARKEY_SUCCESS;

        }
      }
    }
    uint64_t other_displacement = get_displacement(hash_header->hash_capacity, slot, hash2);
    if (displacement > other_displacement) {
      return SPARKEY_SUCCESS;
    }
    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;
}