private static void delete()

in src/main/java/com/spotify/sparkey/IndexHash.java [443:537]


  private static void delete(ReadWriteData indexData, IndexHeader header, long hashCapacity, int keyLen,
                             byte[] key, BlockRandomInput logData,
                             byte[] keyBuf, HashType hashData, AddressSize addressData, int entryIndexBitmask, int entryIndexBits,
                             final long hash, final long address) throws IOException {
    long wantedSlot = getWantedSlot(hash, hashCapacity);

    final int slotSize = header.getSlotSize();
    long pos = wantedSlot * slotSize;
    indexData.seek(pos);

    long slot = wantedSlot;
    long displacement = 0;

    int entryIndex = (int) (address) & entryIndexBitmask;
    long position = address >>> entryIndexBits;

    while (true) {
      long hash2 = hashData.readHash(indexData);
      long address2 = addressData.readAddress(indexData);
      if (address2 == 0) {
        return;
      }
      int entryIndex2 = (int) (address2) & entryIndexBitmask;
      long position2 = address2 >>> entryIndexBits;
      if (hash == hash2) {
        if (keyLen == -1) {
          logData.seek(position);
          skipStuff(entryIndex, logData);
          if (0 != Util.readUnsignedVLQInt(logData)) {
            // Not a delete entry?
            throw new RuntimeException("Corrupt data");
          }
          keyLen = Util.readUnsignedVLQInt(logData);
          logData.readFully(key, 0, keyLen);
        }

        logData.seek(position2);
        skipStuff(entryIndex2, logData);
        int keyLen2 = Util.readUnsignedVLQInt(logData);
        if (keyLen2 == 0) {
          throw new RuntimeException("Invalid data - reference to delete entry");
        }
        keyLen2--;
        if (keyLen == keyLen2) {
          int valueLen2 = Util.readUnsignedVLQInt(logData);
          logData.readFully(keyBuf, 0, keyLen2);
          if (Util.equals(keyLen, key, keyBuf)) {

            // TODO: possibly optimize this to read and write stuff to move in chunks instead of one by one, to decrease number of seeks.
            while (true) {
              long nextSlot = slot + 1;
              if (nextSlot == hashCapacity) {
                nextSlot = 0;
              }
              indexData.seek(nextSlot * slotSize);
              long hash3 = hashData.readHash(indexData);
              long position3 = addressData.readAddress(indexData);

              if (position3 == 0) {
                break;
              }
              if (getWantedSlot(hash3, hashCapacity) == nextSlot) {
                break;
              }

              indexData.seek(slot * slotSize);
              hashData.writeHash(hash3, indexData);
              addressData.writeAddress(position3, indexData);

              slot = nextSlot;
            }

            indexData.seek(slot * slotSize);
            hashData.writeHash(0, indexData);
            addressData.writeAddress(0, indexData);
            header.deletedEntry(keyLen2, valueLen2);

            return;
          }
        }
      }
      long otherDisplacement = getDisplacement(hashCapacity, slot, hash2);
      if (displacement > otherDisplacement) {
        return;
      }
      displacement++;
      slot++;
      pos += slotSize;
      if (slot == hashCapacity) {
        pos = 0;
        slot = 0;
        indexData.seek(0);
      }
    }
  }