package smartkv.client; /** * A DataStoreProxy is a proxy object that knows how to communicate with the data store. The proxy implements all the data store supported operations * at the lowest level possible. It is responsible for composing the <b>RPC</b> operations and send them over the wire to the data store. * * * <p> * <b>General Contract:</b> * <ul> * <li>This proxy handles {@code byte[]} objects as key and data input/output. Serialization/Deserialization of user data does not concern this interface.</li> * <li>The proxy should encapsulate and hide all the implementations details of the <b>RPC</b> protocol in use. This does not concern the user of the proxy implementation.</li> * </ul> * <p> * This object offers a list of CRUD based operations over the data store. The model for the data store is a key value one. This means that all the operations over the data store * will be based on keys to access values. We choose to use {@code byte[]} as keys and also values. This choice seems to be more robust as to use simple String types for keys, given * more existent code (for example based on MAP implementations) can be easily modified to use this interface. * * TODO - Explain why we do not implement a MAPinterface. * TODO - Why are there no exceptions? How to deal with error (communication system failures, etc.,) ? We throw RunTimeExceptions for communication errors. * TODO - how to key finding works (equals and hashcode). * TODO - introduce mapping expression * <p> * If a table with the given name already exists this method returns <code>false</code> * without modify the existent table. There is no way to distinguish between true failure (for example a network error) and an existent table. * The method {@link containsTable } covers this problem. * TODO it is up to the implementation to allow or dissalow null values... Changing somewhat the documented specificaton in this interface. * * * * @author fabiim * */ public interface TableDataStoreProxy{ /** * Empties all the data store data. * * After a call to this method the data store will be empty with absolutely no data (no tables and respective contents). */ public void clear(); /** * Creates a new table with the given name. * * @param tableName the name of the table to be created * @return <code>true</code> if table is successfully created; <br/> * <code>false</code> otherwise. */ public boolean createTable(String tableName); /** * Creates a new size-limited table. * <p> * Creates a new table that is limited in the number of entries that it can contain. When <code>maxSize</code> is reached, * the addition of a new element to the element will result in deleting an existing one. * The eviction policy followed is left as a decision to the implementation * of this interface. * <p> * If a table with the given name already exists this method returns <code>false</code> * without modify the existent table. There is no way to distinguish between true failure (for example a network error) and an existent table. * The method {@link containsTable } covers this problem. * * @param tableName the name of the table to be created * @param maxSize the maximum of entries allowed in this table * @return <code>true</code> if table is successfully created; <br/> * <code>false</code> otherwise. */ public boolean createTable(String tableName, long maxSize); /** * Removes an existent table. * Removes an existent table from the data store clearing all its existent content. * To be clear, a call to method {@link #containsTable(String)} that follows a call to this method with the same tableName as argument will result in <code>false</code>. * @param tableName the name of the table to remove * @return <code>true</code> if table is successfully removed; <br/> * <code>false</code> otherwise. */ public boolean removeTable(String tableName); /** * Returns <code>true</code> if this data store contains a table with the specified name. * @param tableName the name of the table. * @return <code>true</code> if table exists; <br/> * <code>false</code> otherwise. */ public boolean containsTable(String tableName); /** * Empties the specified table. * <p> * After a call to this method the all the data contained in the specified table will no longer exist. * To be clear, a call to method {@link #containsKey(String, byte[])} with the same tableName specified as argument will result in <code>false</false> no matter what the specified key is. * * @param tableName the name of the table to be deleted */ public void clear(String tableName); /** * Returns <code>true</code> if the specified table contains no entries. * * @param tableName the name of the table where the operation will be performed * @return <code>true</code> if the table contains no entries; <br/> * <code>false</code> otherwise (note that it will be false when no table with the specified name exists). */ public boolean isEmpty(String tableName); /** * Returns the number of entries present in the specified table. * @param tableName the name of the table where the operation will be performed * @return the number of entries present in the table if the table exists; <br/> * TODO - what if it does not exists? */ public int size(String tableName); /** * Returns <code>true</code> if the specified table contains the specified key. * * @param tableName the name of the table where the operation will be performed * @param key the key of the element to search for * @return <code>true</code> if the key exists; <br/> * <code>false</code> otherwise (note that it will be false when no table with the specified name exists). */ public boolean containsKey(String tableName, byte[] key); //FIXME - Should this belong here? Maybe a generic version would be cleaner, with pre-installed functions over serialized data. Maybe move up in the interface, change key to String public int getAndIncrement(String tableName, String key); /** * @param tableName * @param reference * @return */ boolean createPointerTable(String tableName, String reference); }