Blazingly fast multi-language serialization framework powered by JIT and zero-copy
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Apache Fury's memory management system provides high-performance binary buffer operations with platform-specific optimizations and efficient memory access patterns.
The core buffer class for efficient binary data operations with both heap and off-heap memory support.
public class MemoryBuffer {
// Buffer creation
public static MemoryBuffer newHeapBuffer(int size);
public static MemoryBuffer newDirectBuffer(int size);
// Basic read/write operations
public void writeByte(byte value);
public byte readByte();
public void writeBoolean(boolean value);
public boolean readBoolean();
public void writeChar(char value);
public char readChar();
public void writeShort(short value);
public short readShort();
public void writeInt(int value);
public int readInt();
public void writeLong(long value);
public long readLong();
public void writeFloat(float value);
public float readFloat();
public void writeDouble(double value);
public double readDouble();
// Array operations
public void writeBytes(byte[] bytes);
public void writeBytes(byte[] bytes, int offset, int length);
public byte[] readBytes(int length);
public void readBytes(byte[] bytes, int offset, int length);
// String operations
public void writeString(String str);
public String readString();
// Position management
public int writerIndex();
public void writerIndex(int writerIndex);
public int readerIndex();
public void readerIndex(int readerIndex);
public void resetWriterIndex();
public void resetReaderIndex();
// Buffer state
public int size();
public int capacity();
public int remain();
public boolean isEmpty();
// Buffer operations
public void clear();
public void reset();
public byte[] toByteArray();
public ByteBuffer asByteBuffer();
}Platform-specific memory operations and utilities.
public class MemoryUtils {
// Platform detection
public static boolean isLittleEndian();
public static boolean isBigEndian();
// Memory allocation utilities
public static long allocateMemory(long size);
public static void freeMemory(long address);
// Memory copy operations
public static void copyMemory(long srcAddress, long destAddress, long length);
public static void copyMemory(Object src, long srcOffset, Object dest, long destOffset, long length);
// Bounds checking utilities
public static void checkBounds(int index, int length, int capacity);
// Platform-specific optimizations
public static boolean isAligned(long address, int alignment);
public static long alignAddress(long address, int alignment);
}Low-level platform operations using Unsafe for maximum performance.
public class Platform {
// Direct memory access constants
public static final boolean LITTLE_ENDIAN;
public static final int BYTE_ARRAY_OFFSET;
public static final int INT_ARRAY_OFFSET;
public static final int LONG_ARRAY_OFFSET;
// Memory operations
public static byte getByte(long address);
public static void putByte(long address, byte value);
public static int getInt(long address);
public static void putInt(long address, int value);
public static long getLong(long address);
public static void putLong(long address, long value);
// Array access
public static byte getByte(Object array, long offset);
public static void putByte(Object array, long offset, byte value);
public static int getInt(Object array, long offset);
public static void putInt(Object array, long offset, int value);
}Utilities for handling byte order and endianness conversions.
public class LittleEndian {
public static short getShort(byte[] bytes, int index);
public static void putShort(byte[] bytes, int index, short value);
public static int getInt(byte[] bytes, int index);
public static void putInt(byte[] bytes, int index, int value);
public static long getLong(byte[] bytes, int index);
public static void putLong(byte[] bytes, int index, long value);
}
public class BigEndian {
public static short getShort(byte[] bytes, int index);
public static void putShort(byte[] bytes, int index, short value);
public static int getInt(byte[] bytes, int index);
public static void putInt(byte[] bytes, int index, int value);
public static long getLong(byte[] bytes, int index);
public static void putLong(byte[] bytes, int index, long value);
}Additional utilities for working with ByteBuffer and buffer operations.
public class ByteBufferUtil {
// ByteBuffer creation
public static ByteBuffer allocateDirect(int capacity);
public static ByteBuffer wrap(byte[] array);
// Buffer operations
public static void clear(ByteBuffer buffer);
public static byte[] toArray(ByteBuffer buffer);
public static int remaining(ByteBuffer buffer);
// Endianness handling
public static ByteOrder getByteOrder(ByteBuffer buffer);
public static void setByteOrder(ByteBuffer buffer, ByteOrder order);
}import org.apache.fury.memory.MemoryBuffer;
// Create heap buffer
MemoryBuffer buffer = MemoryBuffer.newHeapBuffer(1024);
// Write primitive values
buffer.writeInt(42);
buffer.writeLong(123456789L);
buffer.writeString("Hello, Fury!");
// Read back values (reset reader index first)
buffer.readerIndex(0);
int intValue = buffer.readInt();
long longValue = buffer.readLong();
String stringValue = buffer.readString();// Write byte arrays
byte[] data = {1, 2, 3, 4, 5};
buffer.writeBytes(data);
// Write partial array
buffer.writeBytes(data, 1, 3); // Write bytes at indices 1, 2, 3
// Read byte arrays
buffer.readerIndex(0);
byte[] readData = buffer.readBytes(5);
// Read into existing array
byte[] targetArray = new byte[3];
buffer.readBytes(targetArray, 0, 3);// Create direct (off-heap) buffer for large data
MemoryBuffer directBuffer = MemoryBuffer.newDirectBuffer(1024 * 1024); // 1MB
// Use for large binary data to avoid GC pressure
directBuffer.writeBytes(largeBinaryData);
// Convert to ByteBuffer for NIO operations
ByteBuffer byteBuffer = directBuffer.asByteBuffer();// Track positions
int initialWriterPos = buffer.writerIndex();
buffer.writeInt(100);
buffer.writeInt(200);
int finalWriterPos = buffer.writerIndex();
// Reset to read from beginning
buffer.readerIndex(0);
int first = buffer.readInt();
int second = buffer.readInt();
// Jump to specific position
buffer.readerIndex(initialWriterPos);// Reuse buffers to avoid allocation
MemoryBuffer reusableBuffer = MemoryBuffer.newHeapBuffer(1024);
for (Object obj : objectsToSerialize) {
reusableBuffer.clear(); // Reset for reuse
fury.serialize(reusableBuffer, obj);
// Process serialized data
byte[] serializedData = reusableBuffer.toByteArray();
// ... send over network, write to file, etc.
}import org.apache.fury.memory.Platform;
import org.apache.fury.memory.MemoryUtils;
// Check platform characteristics
if (MemoryUtils.isLittleEndian()) {
// Optimize for little-endian byte order
}
// Direct memory operations (advanced usage)
long address = MemoryUtils.allocateMemory(1024);
try {
Platform.putInt(address, 42);
int value = Platform.getInt(address);
} finally {
MemoryUtils.freeMemory(address);
}// Use buffer with Fury serialization
MemoryBuffer buffer = MemoryBuffer.newHeapBuffer(1024);
// Serialize object to buffer
fury.serialize(buffer, myObject);
// Get serialized bytes
byte[] serializedBytes = buffer.toByteArray();
// Create new buffer for deserialization
MemoryBuffer deserializeBuffer = MemoryBuffer.newHeapBuffer(serializedBytes.length);
deserializeBuffer.writeBytes(serializedBytes);
deserializeBuffer.readerIndex(0);
// Deserialize from buffer
Object restored = fury.deserialize(deserializeBuffer);// Handle large datasets efficiently
public void processLargeDataset(List<LargeObject> dataset) {
// Use larger buffer for batch processing
MemoryBuffer batchBuffer = MemoryBuffer.newDirectBuffer(10 * 1024 * 1024); // 10MB
for (int i = 0; i < dataset.size(); i++) {
if (batchBuffer.remain() < ESTIMATED_OBJECT_SIZE) {
// Process current batch
processBatch(batchBuffer);
batchBuffer.clear();
}
fury.serialize(batchBuffer, dataset.get(i));
}
// Process remaining data
if (batchBuffer.writerIndex() > 0) {
processBatch(batchBuffer);
}
}Install with Tessl CLI
npx tessl i tessl/pypi-pyfury@0.10.1