/* * Quasar: lightweight threads and actors for the JVM. * Copyright (c) 2013-2015, Parallel Universe Software Co. All rights reserved. * * This program and the accompanying materials are dual-licensed under * either the terms of the Eclipse Public License v1.0 as published by * the Eclipse Foundation * * or (per the licensee's choosing) * * under the terms of the GNU Lesser General Public License version 3.0 * as published by the Free Software Foundation. */ package co.paralleluniverse.galaxy.quasar; import co.paralleluniverse.common.io.Persistable; import co.paralleluniverse.common.io.Streamable; import co.paralleluniverse.fibers.SuspendExecution; import co.paralleluniverse.galaxy.CacheListener; import co.paralleluniverse.galaxy.ItemState; import co.paralleluniverse.galaxy.LineFunction; import co.paralleluniverse.galaxy.StoreTransaction; import co.paralleluniverse.galaxy.TimeoutException; import java.nio.ByteBuffer; /** * * @author pron */ public interface Store { /** * Returns the maximum size, in bytes, of a data item in the grid. Attempts to store larger items will result in an * exception. This limit is set in the cache spring-bean configuration. * * @return The maximum size, in bytes, of a data item in the grid. */ int getMaxItemSize(); /** * Creates a new transaction. * <p> * A transaction can be used by more than one thread. * * @return A newly created transaction. */ StoreTransaction beginTransaction(); /** * Ends a transaction, and makes all updates visible by all other nodes in the cluster. * * @param txn The current transaction, which we wish to complete. */ void commit(StoreTransaction txn) throws InterruptedException; /** * Ends a transaction after a failure. * <p> * <b>This method must be called only after {@link #rollback(co.paralleluniverse.galaxy.StoreTransaction) rollback()} * has been called, or a manual rollback has been done.</b> * * @param txn The current transaction, which we wish to complete after failure. */ void abort(StoreTransaction txn) throws InterruptedException; /** * Reverts {@code set} operations that were performed during the transactions. * <p> * This method does not complete the * transaction. {@link #commit(co.paralleluniverse.galaxy.StoreTransaction) endTransaction()} must still be called. * * @param txn The current transaction. */ void rollback(StoreTransaction txn); /** * Releases a line that's been pinned to this node by one of the {@code gets}, {@code getx}, {@code put} operations. * <p> * This method must be called to release a line used in one of the {@code gets}, {@code getx}, {@code put} * operations, if they were called with a {@code null} transaction. * * @param id */ void release(long id); /** * Gets or possibly creates a root data item. The same item ID will be returned when this method is called on any * cluster node with the same root name. * <p/> * You can test if the root has been newly created by this transaction by calling . * * @param rootName The root's name. * @return The root item's ID. * @param txn The current transaction. May not be null. * @throws TimeoutException This exception is thrown if the operation has times-out. */ long getRoot(String rootName, StoreTransaction txn) throws TimeoutException; /** * Gets or possibly creates a root data item. The same item ID will be returned when this method is called on any * cluster node with the same root name. * <p/> * You can test if the root has been newly created by this transaction by calling . * * @param rootName The root's name. * @param id If the root does not yet exist, it will be created and given this ID. * @return The root item's ID. * @param txn The current transaction. May not be null. * @throws TimeoutException This exception is thrown if the operation has times-out. */ long getRoot(String rootName, long id, StoreTransaction txn) throws TimeoutException; /** * Tests whether a root item has been newly created. * * @param rootId The root item's ID. * @param txn The current transaction. * @return {@code true} if the root has been created by the current transaction; {@code false} if it existed before * current transaction. */ boolean isRootCreated(long rootId, StoreTransaction txn); /** * Sets a listener listening for local cache events on the given item. * * @param id The item's ID. * @param listener The listener. */ void setListener(long id, CacheListener listener); /** * Sets a listener listening for local cache events on the given item if absent. * * @param id The item's ID. * @param listener The listener. * @return The given listener if it was set or the existing one otherwise. */ CacheListener setListenerIfAbsent(long id, CacheListener listener); /** * Allocates one or more new (and empty) items in the store.<p/> * When allocating a single item, it's better to use {@link #put(byte[], StoreTransaction) put()}, but some data * structures might require allocating an array of items.<br/> * * @param count The number of items to allocate. * @param txn The current transaction. May not be null. * @return The id of the first item in the allocated array. The following {@code count - 1} IDs belong to the * following elements of the array. * @throws TimeoutException */ long alloc(int count, StoreTransaction txn) throws TimeoutException, SuspendExecution; /** * Puts a new item into the store and returns its (newly allocated) ID.<p/> * * @param data The item's contents. * @param txn The current transaction. May be null, in which case you must later call {@link #release(long) release(id)}. * @return The item's (newly allocated) ID. * @throws TimeoutException This exception is thrown if the operation has times-out. */ long put(byte[] data, StoreTransaction txn) throws TimeoutException, SuspendExecution; /** * Puts a new item into the store and returns its (newly allocated) ID.<p/> * * @param data The item's contents. * @param txn The current transaction. May be null, in which case you must later call {@link #release(long) release(id)}. * @return The item's (newly allocated) ID. * @throws TimeoutException This exception is thrown if the operation has times-out. */ long put(ByteBuffer data, StoreTransaction txn) throws TimeoutException, SuspendExecution; /** * Puts a new item into the store and returns its (newly allocated) ID.<p/> * * @param object The item's contents. * @param txn The current transaction. May be null, in which case you must later call {@link #release(long) release(id)}. * @return The item's (newly allocated) ID. * @throws TimeoutException This exception is thrown if the operation has times-out. */ long put(Persistable object, StoreTransaction txn) throws TimeoutException, SuspendExecution; /** * Retrieves a given data item. * * @param id The item's ID. * @return The contents of the item. * @throws TimeoutException This exception is thrown if the operation has times-out. */ byte[] get(long id) throws TimeoutException, SuspendExecution; /** * Retrieves a given data item into a {@link Persistable}. * * @param id The item's ID. * @param object The object into which the contents of the item will be written. * @throws TimeoutException This exception is thrown if the operation has times-out. */ void get(long id, Persistable object) throws TimeoutException, SuspendExecution; /** * Retrieves a given data item, using a hint as to its {@link #getx(long, StoreTransaction) owner} in the * cluster.<br/> * * If the item is indeed found on the hinted node, the retrieval performance might be superior. If not, the method * will still work, but performance may be worse. * * @param id The item's ID. * @param nodeHint The ID of the node the data item is probably owned by. * @return The contents of the item. * @throws TimeoutException This exception is thrown if the operation has times-out. */ byte[] get(long id, short nodeHint) throws TimeoutException, SuspendExecution; /** * Retrieves a given data item into a {@link Persistable}, using a hint as to its {@link #getx(long, StoreTransaction) owner} * in the cluster.<br/> * * If the item is indeed found on the hinted node, the retrieval performance might be superior. If not, the method * will still work, but performance may be worse. * * @param id The item's ID. * @param nodeHint The ID of the node the data item is probably owned by. * @param object The object into which the contents of the item will be written. * @throws TimeoutException This exception is thrown if the operation has times-out. */ void get(long id, short nodeHint, Persistable object) throws TimeoutException, SuspendExecution; /** * Retrieves a given data item, using a hint as to its {@link #getx(long, StoreTransaction) owner} in the cluster. * Unlike the direct hint given in {@link #get(long, short) get(long, short)}, the hinted node here is the owner of * a given item.<br/> * * If the item is indeed found on the hinted node, the retrieval performance might be superior. If not, the method * will still work, but performance may be worse. * * @param id The item's ID. * @param ownerOf The ID of an item whose owner is probably the owner of the requested item as well. * @return The contents of the item. * @throws TimeoutException This exception is thrown if the operation has times-out. */ byte[] getFromOwner(long id, long ownerOf) throws TimeoutException, SuspendExecution; /** * Retrieves a given data item, using a hint as to its {@link #getx(long, StoreTransaction) owner} in the cluster. * Unlike the direct hint given in {@link #get(long, short, Persistable) get(long, short, Persistable)}, the hinted * node here is the owner of a given item.<br/> * * If the item is indeed found on the hinted node, the retrieval performance might be superior. If not, the method * will still work, but performance may be worse. * * @param id The item's ID. * @param ownerOf The ID of an item whose owner is probably the owner of the requested item as well. * @param object The object into which the contents of the item will be written. * @throws TimeoutException This exception is thrown if the operation has times-out. */ void getFromOwner(long id, long ownerOf, Persistable object) throws TimeoutException, SuspendExecution; /** * Retrieves a given data item, and pins the shared (cached) instance to this node. What this means is that while * other nodes will be able to read the same item, no node will be able to update it until until we {@link #commit(co.paralleluniverse.galaxy.StoreTransaction) end the transaction} * or {@link #release(long) release} it. * * @param id The item's ID. * @param txn The current transaction. May be null, in which case you must later call {@link #release(long) release(id)}. * @return The contents of the item. * @throws TimeoutException This exception is thrown if the operation has times-out. */ byte[] gets(long id, StoreTransaction txn) throws TimeoutException, SuspendExecution; /** * Retrieves a given data item into a {@link Persistable}, and pins the shared (cached) instance to this node. What * this means is that while other nodes will be able to read the same item, no node will be able to update it until * until we {@link #commit(co.paralleluniverse.galaxy.StoreTransaction) end the transaction} or {@link #release(long) release} * it. * * @param id The item's ID. * @param object The object into which the contents of the item will be written. * @param txn The current transaction. May be null, in which case you must later call {@link #release(long) release(id)}. * @throws TimeoutException This exception is thrown if the operation has times-out. */ void gets(long id, Persistable object, StoreTransaction txn) throws TimeoutException, SuspendExecution; /** * Retrieves a given data item with a hint as to its {@link #getx(long, StoreTransaction) owner} in the cluster, and * pins the shared (cached) instance to this node. What this means is that while other nodes will be able to read * the same item, no node will be able to update it until until we {@link #commit(co.paralleluniverse.galaxy.StoreTransaction) end the transaction} * or {@link #release(long) release} it. <br/> * * If the item is indeed found on the hinted node, the retrieval performance might be superior. If not, the method * will still work, but performance may be worse. * * @param id The item's ID. * @param nodeHint The ID of the node the data item is probably owned by. * @param txn The current transaction. May be null, in which case you must later call {@link #release(long) release(id)}. * @return The contents of the item. * @throws TimeoutException This exception is thrown if the operation has times-out. */ byte[] gets(long id, short nodeHint, StoreTransaction txn) throws TimeoutException, SuspendExecution; /** * Retrieves a given data item into a {@link Persistable} with a hint as to its {@link #getx(long, StoreTransaction) owner} * in the cluster, and pins the shared (cached) instance to this node. What this means is that while other nodes * will be able to read the same item, no node will be able to update it until until we {@link #commit(co.paralleluniverse.galaxy.StoreTransaction) end the transaction} * or {@link #release(long) release} it.<br/> * * If the item is indeed found on the hinted node, the retrieval performance might be superior. If not, the method * will still work, but performance may be worse. * * @param id The item's ID. * @param nodeHint The ID of the node the data item is probably owned by. * @param txn The current transaction. May be null, in which case you must later call {@link #release(long) release(id)}. * @param object The object into which the contents of the item will be written. * @throws TimeoutException This exception is thrown if the operation has times-out. */ void gets(long id, short nodeHint, Persistable object, StoreTransaction txn) throws TimeoutException, SuspendExecution; /** * Retrieves a given data item with a hint as to its {@link #getx(long, StoreTransaction) owner} in the cluster, and * pins the shared (cached) instance to this node. What this means is that while other nodes will be able to update * it until until we {@link #commit(co.paralleluniverse.galaxy.StoreTransaction) end the transaction} or {@link #release(long) release} * it. Unlike the direct hint given in * {@link #gets(long, short, StoreTransaction)}, the hinted node here is the owner of a given item.<br/> * * If the item is indeed found on the hinted node, the retrieval performance might be superior. If not, the method * will still work, but performance may be worse. * * @param id The item's ID. * @param ownerOf The ID of an item whose owner is probably the owner of the requested item as well. * @param txn The current transaction. May be null, in which case you must later call {@link #release(long) release(id)}. * @return The contents of the item. * @throws TimeoutException This exception is thrown if the operation has times-out. */ byte[] getsFromOwner(long id, long ownerOf, StoreTransaction txn) throws TimeoutException, SuspendExecution; /** * Retrieves a given data item with a hint as to its {@link #getx(long, StoreTransaction) owner} in the cluster, and * pins the shared (cached) instance to this node. What this means is that while other nodes will be able to read * the same item, no node will be able to update it until until we {@link #commit(co.paralleluniverse.galaxy.StoreTransaction) end the transaction} * or {@link #release(long) release} it.<br/> Unlike the direct hint given in {@link #gets(long, short, Persistable, StoreTransaction)}, * the hinted node here is the owner of a given item.<br/> * * If the item is indeed found on the hinted node, the retrieval performance might be superior. If not, the method * will still work, but performance may be worse. * * @param id The item's ID. * @param ownerOf The ID of an item whose owner is probably the owner of the requested item as well. * @param object The object into which the contents of the item will be written. * @param txn The current transaction. May be null, in which case you must later call {@link #release(long) release(id)}. * @throws TimeoutException This exception is thrown if the operation has times-out. */ void getsFromOwner(long id, long ownerOf, Persistable object, StoreTransaction txn) throws TimeoutException, SuspendExecution; /** * Retrieves a given data item, makes this node its exclusive owner, and pins it. What this means is that no other * node will be able to read or update the same item until until we {@link #commit(co.paralleluniverse.galaxy.StoreTransaction) end the transaction} * or {@link #release(long) release} it. it. * * @param id The item's ID. * @return The contents of the item. * @param txn The current transaction. May be null, in which case you must later call {@link #release(long) release(id)}. * @throws TimeoutException This exception is thrown if the operation has times-out. */ byte[] getx(long id, StoreTransaction txn) throws TimeoutException, SuspendExecution; /** * Retrieves a given data item into a {@link Persistable}, makes this node its exclusive owner, and pins it. What * this means is that no other node will be able to read or update the same item until until we {@link #commit(co.paralleluniverse.galaxy.StoreTransaction) end the transaction} * or {@link #release(long) release} it. * * @param id The item's ID. * @param object The object into which the contents of the item will be written. * @param txn The current transaction. May be null, in which case you must later call {@link #release(long) release(id)}. * @throws TimeoutException This exception is thrown if the operation has times-out. */ void getx(long id, Persistable object, StoreTransaction txn) throws TimeoutException, SuspendExecution; /** * Retrieves a given data item with a hint as to its {@link #getx(long, StoreTransaction) owner} in the cluster, * makes this node its exclusive owner, and pins it. What this means is that no other node will be able to read or * update the same item until until we {@link #commit(co.paralleluniverse.galaxy.StoreTransaction) end the transaction} * or {@link #release(long) release} it.<br/> * * If the item is indeed found on the hinted node, the retrieval performance might be superior. If not, the method * will still work, but performance may be worse. * * @param id The item's ID. * @param nodeHint The ID of the node the data item is probably owned by. * @param txn The current transaction. May be null, in which case you must later call {@link #release(long) release(id)}. * @return The contents of the item. * @throws TimeoutException This exception is thrown if the operation has times-out. */ byte[] getx(long id, short nodeHint, StoreTransaction txn) throws TimeoutException, SuspendExecution; /** * Retrieves a given data item with a hint as to its {@link #getx(long, StoreTransaction) owner} in the cluster, * makes this node its exclusive owner, and pins it. What this means is that no other node will be able to read or * update the same item until we {@link #commit(co.paralleluniverse.galaxy.StoreTransaction) end the transaction} or {@link #release(long) release} * it.<br/> * * If the item is indeed found on the hinted node, the retrieval performance might be superior. If not, the method * will still work, but performance may be worse. * * @param id The item's ID. * @param nodeHint The ID of the node the data item is probably owned by. * @param object The object into which the contents of the item will be written. * @param txn The current transaction. May be null, in which case you must later call {@link #release(long) release(id)}. * @throws TimeoutException This exception is thrown if the operation has times-out. */ void getx(long id, short nodeHint, Persistable object, StoreTransaction txn) throws TimeoutException, SuspendExecution; /** * Retrieves a given data item with a hint as to its {@link #getx(long, StoreTransaction) owner} in the cluster, * makes this node its exclusive owner, and pins it. What this means is that no other node will be able to read or * update the same item until we {@link #commit(co.paralleluniverse.galaxy.StoreTransaction) end the transaction} or {@link #release(long) release} * it. * * Unlike the direct hint given in {@link #getx(long, short, StoreTransaction)}, the hinted node here is the owner * of a given item.<br/> * * If the item is indeed found on the hinted node, the retrieval performance might be superior. If not, the method * will still work, but performance may be worse. * * @param id The item's ID. * @param ownerOf The ID of an item whose owner is probably the owner of the requested item as well. * @param txn The current transaction. May be null, in which case you must later call {@link #release(long) release(id)}. * @return The contents of the item. * @throws TimeoutException This exception is thrown if the operation has times-out. */ byte[] getxFromOwner(long id, long ownerOf, StoreTransaction txn) throws TimeoutException, SuspendExecution; /** * Retrieves a given data item with a hint as to its {@link #getx(long, StoreTransaction) owner} in the cluster, * makes this node its exclusive owner, and pins it. What this means is that no other node will be able to read or * update the same item until we {@link #commit(co.paralleluniverse.galaxy.StoreTransaction) end the transaction} or {@link #release(long) release} * it. * * Unlike the direct hint given in {@link #getx(long, short, Persistable, StoreTransaction)}, the hinted node here * is the owner of a given item.<br/> * * If the item is indeed found on the hinted node, the retrieval performance might be superior. If not, the method * will still work, but performance may be worse. * * @param id The item's ID. * @param ownerOf The ID of an item whose owner is probably the owner of the requested item as well. * @param object The object into which the contents of the item will be written. * @param txn The current transaction. May be null, in which case you must later call {@link #release(long) release(id)}. * @throws TimeoutException This exception is thrown if the operation has times-out. */ void getxFromOwner(long id, long ownerOf, Persistable object, StoreTransaction txn) throws TimeoutException, SuspendExecution; /** * Gains ownership of an item and sets its contents. Upon return from this method, the item will be pinned if and * only if it had been pinned when the method was called. * * @param id The item's ID. * @param data The contents to write into the item. * @param txn The current transaction. May be null. * @throws TimeoutException This exception is thrown if the operation has times-out. */ void set(long id, byte[] data, StoreTransaction txn) throws TimeoutException, SuspendExecution; /** * Gains ownership of an item and sets its contents. Upon return from this method, the item will be pinned if and * only if it had been pinned when the method was called. * * @param id The item's ID. * @param data The contents to write into the item. * @param txn The current transaction. May be null. * @throws TimeoutException This exception is thrown if the operation has times-out. */ void set(long id, ByteBuffer data, StoreTransaction txn) throws TimeoutException, SuspendExecution; /** * Gains ownership of an item and sets its contents. Upon return from this method, the item will be pinned if and * only if it had been pinned when the method was called. * * @param id The item's ID. * @param object The contents to write into the item. * @param txn The current transaction. May be null. * @throws TimeoutException This exception is thrown if the operation has times-out. */ void set(long id, Persistable object, StoreTransaction txn) throws TimeoutException, SuspendExecution; /** * Deletes an item from the store. * * @param id * @param txn The current transaction. May be null. */ void del(long id, StoreTransaction txn) throws TimeoutException, SuspendExecution; <T> T invoke(long id, LineFunction<T> function) throws TimeoutException, SuspendExecution; /** * Makes the given item available in the given nodes' cache. <br/> * * While this method is never necessary for the correct operation of the grid, in some special circumstances it * might improve performance if we know that the given nodes will soon be interested in reading the item (e.g. as a * result of a message we're about to send them). * * @param id The ID of item to push. * @param toNodes The nodes to which the item is to be pushed. */ void push(long id, short... toNodes); /** * Makes the given item available in the given node's cache, and makes that node the owner of the item. <br/> * * While this method is never necessary for the correct operation of the grid, in some special circumstances it * might improve performance if we know that the given node will soon be interested in reading or updating the item * (e.g. as a result of a message we're about to send it). * * @param id The ID of item to push. * @param toNode The node to which the item is to be pushed. */ void pushx(long id, short toNode); /** * Tests whether an item is pinned on this node. * * @param id The item's ID. * @return {@code true} if the item is pinned; {@code false} otherwise. */ boolean isPinned(long id); /** * Returns an item's state in the local store. * * @param id The item's ID. * @return The item's state. */ ItemState getState(long id); /** * Item version * * @param id The item's ID. */ long getVersion(long id); /** * Sends a message to an item, which will be received by {@link CacheListener#messageReceived(byte[]) CacheListener.messageReceived} * on the item's owning node. * * @param id The item's ID. * @param msg The message. * @throws TimeoutException This exception is thrown if the operation has times-out. */ void send(long id, Streamable data) throws TimeoutException, SuspendExecution; /** * Sends a message to an item, which will be received by {@link CacheListener#messageReceived(byte[]) CacheListener.messageReceived} * on the item's owning node. * * @param id The item's ID. * @param msg The message. * @throws TimeoutException This exception is thrown if the operation has times-out. */ void send(long id, byte[] msg) throws TimeoutException, SuspendExecution; }