@Override public int fromStream(final byte[] content, int offset) { final int size = OIntegerSerializer.INSTANCE.deserializeNative(content, offset); offset += OIntegerSerializer.INT_SIZE; dirtyPages = new HashSet<ODirtyPage>(); for (int i = 0; i < size; i++) { long pageIndex = OLongSerializer.INSTANCE.deserializeNative(content, offset); offset += OLongSerializer.LONG_SIZE; String fileName = stringSerializer.deserializeNativeObject(content, offset); offset += stringSerializer.getObjectSize(fileName); long segment = OLongSerializer.INSTANCE.deserializeNative(content, offset); offset += OLongSerializer.LONG_SIZE; long position = OLongSerializer.INSTANCE.deserializeNative(content, offset); offset += OLongSerializer.LONG_SIZE; dirtyPages.add( new ODirtyPage(fileName, pageIndex, new OLogSequenceNumber(segment, position))); } return offset; }
public OSBTreeBonsaiBucket( OCacheEntry cacheEntry, int pageOffset, boolean isLeaf, OBinarySerializer<K> keySerializer, OBinarySerializer<V> valueSerializer, OWALChangesTree changesTree) throws IOException { super(cacheEntry, changesTree); this.offset = pageOffset; this.isLeaf = isLeaf; this.keySerializer = keySerializer; this.valueSerializer = valueSerializer; setIntValue(offset + FREE_POINTER_OFFSET, MAX_BUCKET_SIZE_BYTES); setIntValue(offset + SIZE_OFFSET, 0); setByteValue(offset + IS_LEAF_OFFSET, (byte) (isLeaf ? 1 : 0)); setLongValue(offset + LEFT_SIBLING_OFFSET, -1); setLongValue(offset + RIGHT_SIBLING_OFFSET, -1); setLongValue(offset + TREE_SIZE_OFFSET, 0); setByteValue(offset + KEY_SERIALIZER_OFFSET, keySerializer.getId()); setByteValue(offset + VALUE_SERIALIZER_OFFSET, valueSerializer.getId()); }
public <K> void serializeChanges( Map<K, Change> changes, OBinarySerializer<K> keySerializer, byte[] stream, int offset) { OIntegerSerializer.INSTANCE.serializeLiteral(changes.size(), stream, offset); offset += OIntegerSerializer.INT_SIZE; for (Map.Entry<K, Change> entry : changes.entrySet()) { K key = entry.getKey(); if (((OIdentifiable) key).getIdentity().isTemporary()) key = ((OIdentifiable) key).getRecord(); keySerializer.serialize(key, stream, offset); offset += keySerializer.getObjectSize(key); offset += entry.getValue().serialize(stream, offset); } }
@Override public int serializedSize() { int size = OIntegerSerializer.INT_SIZE; for (ODirtyPage dirtyPage : dirtyPages) { size += 3 * OLongSerializer.LONG_SIZE; size += stringSerializer.getObjectSize(dirtyPage.getFileName()); } return size; }
public int updateValue(int index, V value) throws IOException { assert valueSerializer.isFixedLength(); int entryPosition = getIntValue(offset + index * OIntegerSerializer.INT_SIZE + POSITIONS_ARRAY_OFFSET); entryPosition += getObjectSizeInDirectMemory(keySerializer, offset + entryPosition); final int size = valueSerializer.getFixedLength(); byte[] serializedValue = new byte[size]; valueSerializer.serializeNativeObject(value, serializedValue, 0); byte[] oldSerializedValue = getBinaryValue(offset + entryPosition, size); if (ODefaultComparator.INSTANCE.compare(oldSerializedValue, serializedValue) == 0) return 0; setBinaryValue(offset + entryPosition, serializedValue); return 1; }
@Override public int toStream(final byte[] content, int offset) { OIntegerSerializer.INSTANCE.serializeNative(dirtyPages.size(), content, offset); offset += OIntegerSerializer.INT_SIZE; for (ODirtyPage dirtyPage : dirtyPages) { OLongSerializer.INSTANCE.serializeNative(dirtyPage.getPageIndex(), content, offset); offset += OLongSerializer.LONG_SIZE; stringSerializer.serializeNativeObject(dirtyPage.getFileName(), content, offset); offset += stringSerializer.getObjectSize(dirtyPage.getFileName()); OLongSerializer.INSTANCE.serializeNative(dirtyPage.getLsn().getSegment(), content, offset); offset += OLongSerializer.LONG_SIZE; OLongSerializer.INSTANCE.serializeNative(dirtyPage.getLsn().getPosition(), content, offset); offset += OLongSerializer.LONG_SIZE; } return offset; }
public void remove(int entryIndex) throws IOException { int entryPosition = getIntValue(offset + POSITIONS_ARRAY_OFFSET + entryIndex * OIntegerSerializer.INT_SIZE); int entrySize = getObjectSizeInDirectMemory(keySerializer, offset + entryPosition); if (isLeaf) { assert valueSerializer.isFixedLength(); entrySize += valueSerializer.getFixedLength(); } else { throw new IllegalStateException("Remove is applies to leaf buckets only"); } int size = size(); if (entryIndex < size - 1) { moveData( offset + POSITIONS_ARRAY_OFFSET + (entryIndex + 1) * OIntegerSerializer.INT_SIZE, offset + POSITIONS_ARRAY_OFFSET + entryIndex * OIntegerSerializer.INT_SIZE, (size - entryIndex - 1) * OIntegerSerializer.INT_SIZE); } size--; setIntValue(offset + SIZE_OFFSET, size); int freePointer = getIntValue(offset + FREE_POINTER_OFFSET); if (size > 0 && entryPosition > freePointer) { moveData(offset + freePointer, offset + freePointer + entrySize, entryPosition - freePointer); } setIntValue(offset + FREE_POINTER_OFFSET, freePointer + entrySize); int currentPositionOffset = offset + POSITIONS_ARRAY_OFFSET; for (int i = 0; i < size; i++) { int currentEntryPosition = getIntValue(currentPositionOffset); if (currentEntryPosition < entryPosition) setIntValue(currentPositionOffset, currentEntryPosition + entrySize); currentPositionOffset += OIntegerSerializer.INT_SIZE; } }
public boolean addEntry(int index, SBTreeEntry<K, V> treeEntry, boolean updateNeighbors) throws IOException { final int keySize = keySerializer.getObjectSize(treeEntry.key); int valueSize = 0; int entrySize = keySize; if (isLeaf) { assert valueSerializer.isFixedLength(); valueSize = valueSerializer.getFixedLength(); entrySize += valueSize; checkEntreeSize(entrySize); } else entrySize += 2 * (OLongSerializer.LONG_SIZE + OIntegerSerializer.INT_SIZE); int size = size(); int freePointer = getIntValue(offset + FREE_POINTER_OFFSET); if (freePointer - entrySize < (size + 1) * OIntegerSerializer.INT_SIZE + POSITIONS_ARRAY_OFFSET) { if (size > 1) return false; else throw new OSBTreeException( "Entry size ('key + value') is more than is more than allowed " + (freePointer - 2 * OIntegerSerializer.INT_SIZE + POSITIONS_ARRAY_OFFSET) + " bytes, either increase page size using '" + OGlobalConfiguration.SBTREEBONSAI_BUCKET_SIZE.getKey() + "' parameter, or decrease 'key + value' size."); } if (index <= size - 1) { moveData( offset + POSITIONS_ARRAY_OFFSET + index * OIntegerSerializer.INT_SIZE, offset + POSITIONS_ARRAY_OFFSET + (index + 1) * OIntegerSerializer.INT_SIZE, (size - index) * OIntegerSerializer.INT_SIZE); } freePointer -= entrySize; setIntValue(offset + FREE_POINTER_OFFSET, freePointer); setIntValue(offset + POSITIONS_ARRAY_OFFSET + index * OIntegerSerializer.INT_SIZE, freePointer); setIntValue(offset + SIZE_OFFSET, size + 1); if (isLeaf) { byte[] serializedKey = new byte[keySize]; keySerializer.serializeNativeObject(treeEntry.key, serializedKey, 0); setBinaryValue(offset + freePointer, serializedKey); freePointer += keySize; byte[] serializedValue = new byte[valueSize]; valueSerializer.serializeNativeObject(treeEntry.value, serializedValue, 0); setBinaryValue(offset + freePointer, serializedValue); } else { setBucketPointer(offset + freePointer, treeEntry.leftChild); freePointer += OLongSerializer.LONG_SIZE + OIntegerSerializer.INT_SIZE; setBucketPointer(offset + freePointer, treeEntry.rightChild); freePointer += OLongSerializer.LONG_SIZE + OIntegerSerializer.INT_SIZE; byte[] serializedKey = new byte[keySize]; keySerializer.serializeNativeObject(treeEntry.key, serializedKey, 0); setBinaryValue(offset + freePointer, serializedKey); size++; if (updateNeighbors && size > 1) { if (index < size - 1) { final int nextEntryPosition = getIntValue( offset + POSITIONS_ARRAY_OFFSET + (index + 1) * OIntegerSerializer.INT_SIZE); setBucketPointer(offset + nextEntryPosition, treeEntry.rightChild); } if (index > 0) { final int prevEntryPosition = getIntValue( offset + POSITIONS_ARRAY_OFFSET + (index - 1) * OIntegerSerializer.INT_SIZE); setBucketPointer( offset + prevEntryPosition + OLongSerializer.LONG_SIZE + OIntegerSerializer.INT_SIZE, treeEntry.leftChild); } } } return true; }