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