boolean foundSmall = false, foundLarge = false;
while (true) {
int pos = smallMap.nextPos();
if (pos < 0) {
K key2 = key instanceof CharSequence ? (K) key.toString() : key;
final DirectStore store = map.get(key2);
if (store == null) {
if (ifPresent && !ifAbsent)
return;
break;
}
if (ifAbsent && !ifPresent)
return;
bytes.storePositionAndSize(store, 0, store.size());
foundLarge = true;
break;
} else {
bytes.storePositionAndSize(store, pos * smallEntrySize, smallEntrySize);
K key2 = getKey();
if (equals(key, key2)) {
if (ifAbsent && !ifPresent)
return;
foundSmall = true;
break;
}
}
}
tmpBytes.clear();
if (csKey)
//noinspection ConstantConditions
tmpBytes.writeUTFΔ((CharSequence) key);
else
tmpBytes.writeObject(key);
long startOfValuePos = tmpBytes.position();
if (bytesMarshallable)
((BytesMarshallable) value).writeMarshallable(tmpBytes);
else
tmpBytes.writeObject(value);
boolean largeRemoved = false;
long size = tmpBytes.position();
if (size <= smallEntrySize) {
if (foundSmall) {
bytes.position(0);
bytes.write(tmpBytes, 0, size);
return;
} else if (foundLarge) {
remove(hash, key);
largeRemoved = true;
}
// look for a free spot.
int position = h & (entriesPerSegment - 1);
int free = usedSet.nextClearBit(position);
if (free >= entriesPerSegment)
free = usedSet.nextClearBit(0);
if (free < entriesPerSegment) {
bytes.storePositionAndSize(store, free * smallEntrySize, smallEntrySize);
bytes.write(tmpBytes, 0, size);
smallMap.put(h, free);
usedSet.set(free);
this.size++;
return;
}
}
if (foundSmall) {
remove(hash, key);
} else if (foundLarge && !largeRemoved) {
remove(hash, key);
}
size = size - startOfValuePos;
DirectStore store = new DirectStore(bmf, size);
bytes.storePositionAndSize(store, 0, size);
bytes.write(tmpBytes, startOfValuePos, size);
K key2 = key instanceof CharSequence ? (K) key.toString() : key;
map.put(key2, store);
offHeapUsed += size;