/** * @param keyBytes * @param value * @param hash2 * @return */ V acquireEntry(DirectBytes keyBytes, V value, int hash2) { value = createValueIfNull(value); final int pos = nextFree(); final long offset = entriesOffset + pos * entrySize; tmpBytes.storePositionAndSize(bytes, offset, entrySize); final long keyLength = keyBytes.remaining(); tmpBytes.writeStopBit(keyLength); tmpBytes.write(keyBytes); if (value instanceof Byteable) { Byteable byteable = (Byteable) value; int length = byteable.maxSize(); tmpBytes.writeStopBit(length); tmpBytes.position(align(tmpBytes.position())); if (length > tmpBytes.remaining()) throw new IllegalStateException( "Not enough space left in entry for value, needs " + length + " but only " + tmpBytes.remaining() + " left"); tmpBytes.zeroOut(tmpBytes.position(), tmpBytes.position() + length); byteable.bytes(bytes, offset + tmpBytes.position()); } else { appendInstance(keyBytes, value); } // add to index if successful. hashLookup.put(hash2, pos); incrementSize(); return value; }
void appendValue(final Bytes value) { if (value.remaining() + 4 > tmpBytes.remaining()) throw new IllegalArgumentException( "Value too large for entry was " + (value.remaining() + 4) + ", remaining: " + tmpBytes.remaining()); tmpBytes.writeStopBit(value.remaining()); tmpBytes.position(align(tmpBytes.position())); tmpBytes.write(value); }
private void putEntry(DirectBytes keyBytes, V value, int hash2) { int pos = nextFree(); long offset = entriesOffset + pos * builder.entrySize(); tmpBytes.storePositionAndSize(bytes, offset, builder.entrySize()); long keyLength = keyBytes.remaining(); tmpBytes.writeStopBit(keyLength); tmpBytes.write(keyBytes); tmpBytes.position(align(tmpBytes.position())); appendInstance(keyBytes, value); // add to index if successful. hashLookup.put(hash2, pos); }
private void appendInstance(DirectBytes bytes, V value) { bytes.clear(); if (builder.generatedValueType()) ((BytesMarshallable) value).writeMarshallable(bytes); else bytes.writeInstance(vClass, value); bytes.flip(); if (bytes.remaining() > tmpBytes.remaining()) throw new IllegalArgumentException( "Value too large for entry was " + bytes.remaining() + ", remaining: " + tmpBytes.remaining()); tmpBytes.write(bytes); }
private V acquireEntry(DirectBytes keyBytes, V value, int hash2) { int pos = nextFree(); long offset = entriesOffset + pos * builder.entrySize(); tmpBytes.storePositionAndSize(bytes, offset, builder.entrySize()); long keyLength = keyBytes.remaining(); tmpBytes.writeStopBit(keyLength); tmpBytes.write(keyBytes); tmpBytes.position(align(tmpBytes.position())); tmpBytes.zeroOut(tmpBytes.position(), tmpBytes.limit()); V v = readObjectUsing(value, offset + tmpBytes.position()); // add to index if successful. hashLookup.put(hash2, pos); return v; }
private void writeKey(Bytes keyBytes, long offset) { tmpBytes.storePositionAndSize(bytes, offset, entrySize); long keyLength = keyBytes.remaining(); tmpBytes.writeStopBit(keyLength); tmpBytes.write(keyBytes); }
synchronized void put(long hash, K key, V value, boolean ifPresent, boolean ifAbsent) { // search for the previous entry int h = smallMap.startSearch(hash); 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) 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); long size = tmpBytes.position(); if (size <= smallEntrySize) { if (foundSmall) { bytes.position(0); bytes.write(tmpBytes, 0, size); return; } else if (foundLarge) { remove(hash, key); } // 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) { // can it be reused. if (bytes.capacity() <= size || bytes.capacity() - size < (size >> 3)) { bytes.write(tmpBytes, startOfValuePos, size); return; } 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; this.size++; }