![PyPI Now Supports iOS and Android Wheels for Mobile Python Development](https://cdn.sanity.io/images/cgdhsj6q/production/96416c872705517a6a65ad9646ce3e7caef623a0-1024x1024.webp?w=400&fit=max&auto=format)
Security News
PyPI Now Supports iOS and Android Wheels for Mobile Python Development
PyPI now supports iOS and Android wheels, making it easier for Python developers to distribute mobile packages.
com.aitusoftware:recall-store
Advanced tools
Recall is an off-heap, allocation-free object store for the JVM.
Recall is designed for use in allocation-free or low-garbage systems. Objects are expected to be mutable in order to reduce allocation costs. For this reason, domain objects should have mutator methods for any fields that need to be serialised.
dependencies {
compile group: 'com.aitusoftware', name: 'recall-store', version: '0.2.0'
}
<dependency>
<groupId>com.aitusoftware</groupId>
<artifactId>recall-store</artifactId>
<version>0.2.0</version>
</dependency>
Recall can use either a standard JDK ByteBuffer
or an
Agrona UnsafeBuffer
for storage of
objects outside of the Java heap.
To use the Recall object store, implement the Encoder
, Decoder
, and IdAccessor
interface for
a given object and buffer type:
public class Order {
private long id;
private double quantity;
private double price;
// constructor omitted
// getters and setters omitted
}
Encoder
public class OrderEncoder implements Encoder<ByteBuffer, Order> {
public void store(ByteBuffer buffer, int offset, Order order) {
buffer.putLong(offset, order.getId());
buffer.putDouble(offset + Long.BYTES, order.getQuantity());
buffer.putDouble(offset + Long.BYTES + Double.BYTES, order.getPrice());
}
}
Decoder
public class OrderDecoder implements Decoder<ByteBuffer, Order> {
public void load(ByteBuffer buffer, int offset, Order target) {
target.setId(buffer.getLong(offset));
target.setQuantity(buffer.getDouble(offset + Long.BYTES));
target.setPrice(buffer.getDouble(offset + Long.BYTES + Double.BYTES));
}
}
IdAccessor
public class OrderIdAccessor implements IdAccessor<Order> {
public long getId(Order order) {
return order.getId();
}
}
Create a Store
:
BufferStore<ByteBuffer> store =
new BufferStore<>(24, 100, ByteBuffer::allocateDirect, new ByteBufferOps());
Optionally wrap it in a SingleTypeStore
(if only one type is going to be stored):
SingleTypeStore<ByteBuffer, Order> typeStore =
new SingleTypeStore<>(store, new OrderDecoder(), new OrderEncoder(),
new OrderIdAccessor());
Domain objects can be serialised to off-heap storage, and retrieved at a later time:
long orderId = 42L;
Order testOrder = new Order(orderId, 12.34D, 56.78D);
typeStore.store(testOrder);
Order container = new Order(-1, -1, -1);
assert typeStore.load(orderId, container);
assert container.getQuantity() == 12.34D;
Recall is able to provide efficient off-heap storage of SBE-encoded messages.
This example uses the canonical Car
example from
SBE.
SBE objects must be generated with:
-Dsbe.java.generate.interfaces=true
this causes the Decoder
to implement MessageDecoderFlyweight
.
IdAccessor
It is necessary to implement the IdAccessor
interface for the SBE Decoder
type:
public class CarIdAccessor implements IdAccessor<CarDecoder> {
public long getId(CarDecoder decoder) {
return decoder.id();
}
}
Create a SingleTypeStore
for the type of the Decoder
:
SingleTypeStore<UnsafeBuffer, CarDecoder> messageStore =
SbeMessageStoreFactory.forSbeMessage(new CarDecoder(),
MAX_RECORD_LENGTH, 100,
len -> new UnsafeBuffer(ByteBuffer.allocateDirect(len)),
new CarIdAccessor());
Note: it is up to the application developer to determine the maximum length of any given SBE message (even in the case of variable-length fields).
If an encoded value exceeds the specified maximum record length, then the
store
method will throw an IllegalArgumentException
.
SBE messages can now be stored for later retrieval:
public void receiveCar(ReadableByteChannel channel) {
CarDecoder decoder = new CarDecoder();
UnsafeBuffer buffer = new UnsafeBuffer();
ByteBuffer inputData = ByteBuffer.allocateDirect(MAX_RECORD_LENGTH);
channel.read(inputData);
inputData.flip();
buffer.wrap(inputData);
decoder.wrap(buffer, 0, BLOCK_LENGTH, VERSION);
dispatchCarReceivedEvent(decoder);
messageStore.store(decoder);
}
public void notifyCarSold(long carId) {
CarDecoder decoder = new CarDecoder();
messageStore.load(carId, decoder);
dispatchCarSoldEvent(decoder);
}
Since it is sometimes useful to be able to store and retrieve objects by something other than an integer key, Recall also provides the ability to create mappings based on variable-length keys based on either strings, or byte-sequences.
CharSequenceMap
CharSequenceMap
is an open-addressed hash map with that can be used to store a CharSequence
against an integer identifier.
Example usage:
private final OrderByteBufferTranscoder transcoder =
new OrderByteBufferTranscoder();
private final SingleTypeStore<ByteBuffer, Order> store =
new SingleTypeStore<>(
new BufferStore<>(MAX_RECORD_LENGTH, INITIAL_SIZE,
ByteBuffer::allocateDirect, new ByteBufferOps()),
transcoder, transcoder, Order::getId);
private final CharSequenceMap orderBySymbol =
new CharSequenceMap(MAX_KEY_LENGTH, INITIAL_SIZE, Long.MIN_VALUE);
private void execute()
{
final String[] symbols = new String[INITIAL_SIZE];
for (int i = 0; i < INITIAL_SIZE; i++)
{
final Order order = Order.of(i);
store.store(order);
orderBySymbol.insert(order.getSymbol(), order.getId());
symbols[i] = order.getSymbol().toString();
}
final Order container = Order.of(-1L);
for (int i = 0; i < INITIAL_SIZE; i++)
{
final String searchTerm = symbols[i];
final long id = orderBySymbol.search(searchTerm);
assertThat(store.load(id, container)).isTrue();
System.out.printf("Order with symbol %s has id %d%n", searchTerm, id);
}
}
ByteSequenceMap
ByteSequenceMap
is an open-addressed hash map with that can be used to store a ByteBuffer
against an integer identifier.
FAQs
Recall: An off-heap garbage-free object store
We found that com.aitusoftware:recall-store demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
PyPI now supports iOS and Android wheels, making it easier for Python developers to distribute mobile packages.
Security News
Create React App is officially deprecated due to React 19 issues and lack of maintenance—developers should switch to Vite or other modern alternatives.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.