diff --git a/api/net/sf/briar/api/db/DatabaseComponent.java b/api/net/sf/briar/api/db/DatabaseComponent.java index 8be61c5cd0d83c18204995770e471e3397827d22..9c12e40e5ddd1719e54fa6c4db1771942390dd09 100644 --- a/api/net/sf/briar/api/db/DatabaseComponent.java +++ b/api/net/sf/briar/api/db/DatabaseComponent.java @@ -26,25 +26,22 @@ public interface DatabaseComponent { static final int CLEANER_SLEEP_MS = 1000; // 1 sec static final int RETRANSMIT_THRESHOLD = 3; - /** Waits for any open transactions to finish and closes the database. */ - void close() throws DbException; - /** Adds a locally generated message to the database. */ void addLocallyGeneratedMessage(Message m) throws DbException; /** Adds a new neighbour to the database. */ void addNeighbour(NeighbourId n) throws DbException; + /** Waits for any open transactions to finish and closes the database. */ + void close() throws DbException; + /** Generates a bundle of messages for the given neighbour. */ void generateBundle(NeighbourId n, Bundle b) throws DbException; - /** - * Returns the rating assigned to the given author, which may be - * Rating.UNRATED if no rating has been assigned. - */ + /** Returns the user's rating for the given author. */ Rating getRating(AuthorId a) throws DbException; - /** Returns the set of groups to which we subscribe. */ + /** Returns the set of groups to which the user subscribes. */ Set<GroupId> getSubscriptions() throws DbException; /** @@ -53,7 +50,7 @@ public interface DatabaseComponent { */ void receiveBundle(NeighbourId n, Bundle b) throws DbException; - /** Stores a rating for the given author. */ + /** Records the user's rating for the given author. */ void setRating(AuthorId a, Rating r) throws DbException; /** Subscribes to the given group. */ @@ -61,7 +58,7 @@ public interface DatabaseComponent { /** * Unsubscribes from the given group. Any messages belonging to the group - * will be deleted from the database. + * are deleted from the database. */ void unsubscribe(GroupId g) throws DbException; } diff --git a/components/net/sf/briar/db/Database.java b/components/net/sf/briar/db/Database.java index 29b048fd8927a9c516f855e0456e34752d7283b4..a50518218fa6426f45d98e90da269a538b9533e5 100644 --- a/components/net/sf/briar/db/Database.java +++ b/components/net/sf/briar/db/Database.java @@ -13,102 +13,227 @@ import net.sf.briar.api.protocol.GroupId; import net.sf.briar.api.protocol.Message; import net.sf.briar.api.protocol.MessageId; +/** + * A low-level interface to the database that is managed by a + * DatabaseComponent. Most operations take a transaction argument, which is + * obtained by calling startTransaction(). Every transaction must be + * terminated by calling either abortTransaction() or commitTransaction(), + * even if an exception is thrown. + */ interface Database<T> { + /** + * Opens the database. + * @param resume True to reopen an existing database, false to create a + * new one. + */ void open(boolean resume) throws DbException; + /** Waits for all open transactions to finish and closes the database. */ void close() throws DbException; + /** Starts a new transaction and returns an object representing it. */ T startTransaction(String name) throws DbException; + /** + * Aborts the given transaction - no changes made during the transaction + * will be applied to the database. + */ void abortTransaction(T txn); + /** + * Commits the given transaction - all changes made during the transaction + * will be applied to the database. + */ void commitTransaction(T txn) throws DbException; - // Locking: neighbours write + /** + * Records a received batch as needing to be acknowledged. + * Locking: neighbours write. + */ void addBatchToAck(T txn, NeighbourId n, BatchId b) throws DbException; - // Locking: neighbours write + /** + * Returns false if the given message is already in the database. Otherwise + * stores the message and returns true. + * Locking: messages write. + */ + boolean addMessage(T txn, Message m) throws DbException; + + /** + * Adds a new neighbour to the database. + * Locking: neighbours write. + */ void addNeighbour(T txn, NeighbourId n) throws DbException; - // Locking: neighbours write, messages read + /** + * Records a sent batch as needing to be acknowledged. + * Locking: neighbours write, messages read. + */ void addOutstandingBatch(T txn, NeighbourId n, BatchId b, Set<MessageId> sent) throws DbException; - // Locking: neighbours write, messages read + /** + * Records a received bundle. This should be called after processing the + * bundle's contents, and may result in outstanding messages becoming + * eligible for retransmittion. + * Locking: neighbours write, messages read. + */ Set<BatchId> addReceivedBundle(T txn, NeighbourId n, BundleId b) throws DbException; - // Locking: subscriptions write + /** + * Subscribes to the given group. + * Locking: subscriptions write. + */ void addSubscription(T txn, GroupId g) throws DbException; - // Locking: neighbours write + /** + * Records a neighbour's subscription to a group. + * Locking: neighbours write. + */ void addSubscription(T txn, NeighbourId n, GroupId g) throws DbException; - // Locking: neighbours write + /** + * Removes all recorded subscriptions for the given neighbour. + * Locking: neighbours write. + */ void clearSubscriptions(T txn, NeighbourId n) throws DbException; - // Locking: messages read + /** + * Returns true iff the database contains the given message. + * Locking: messages read. + */ boolean containsMessage(T txn, MessageId m) throws DbException; - // Locking: subscriptions read + /** + * Returns true iff the user is subscribed to the given group. + * Locking: subscriptions read. + */ boolean containsSubscription(T txn, GroupId g) throws DbException; - // Locking: messages read + /** + * Returns the amount of free storage space available to the database, in + * bytes. This is based on the minimum of the space available on the device + * where the database is stored and the database's configured size. + * Locking: messages read. + */ long getFreeSpace() throws DbException; - // Locking: messages read + /** + * Returns the message identified by the given ID. + * Locking: messages read. + */ Message getMessage(T txn, MessageId m) throws DbException; - // Locking: messages read + /** + * Returns the IDs of all messages signed by the given author. + * Locking: messages read. + */ Iterable<MessageId> getMessagesByAuthor(T txn, AuthorId a) throws DbException; - // Locking: messages read + /** + * Returns the IDs of all children of the message identified by the given + * ID that are present in the database. + * Locking: messages read. + */ Iterable<MessageId> getMessagesByParent(T txn, MessageId m) throws DbException; - // Locking: neighbours read + /** + * Returns the IDs of all neighbours + * Locking: neighbours read. + */ Set<NeighbourId> getNeighbours(T txn) throws DbException; - // Locking: messages read + /** + * Returns the IDs of the oldest messages in the database, with a total + * size less than or equal to the given size. + * Locking: messages read. + */ Iterable<MessageId> getOldMessages(T txn, long size) throws DbException; - // Locking: messages read + /** + * Returns the parent of the given message. + * Locking: messages read. + */ MessageId getParent(T txn, MessageId m) throws DbException; - // Locking: ratings read + /** + * Returns the user's rating for the given author. + * Locking: ratings read. + */ Rating getRating(T txn, AuthorId a) throws DbException; - // Locking: messages read + /** + * Returns the sendability score of the given message. Messages with + * sendability scores greater than zero are eligible to be sent to + * neighbours. + * Locking: messages read. + */ int getSendability(T txn, MessageId m) throws DbException; - // Locking: neighbours read, messages read + /** + * Returns the IDs of some messages that are eligible to be sent to the + * given neighbour, with a total size less than or equal to the given size. + * Locking: neighbours read, messages read. + */ Iterable<MessageId> getSendableMessages(T txn, NeighbourId n, long capacity) throws DbException; - // Locking: subscriptions read + /** + * Returns the groups to which the user subscribes. + * Locking: subscriptions read. + */ Set<GroupId> getSubscriptions(T txn) throws DbException; - // Locking: messages write - boolean addMessage(T txn, Message m) throws DbException; - - // Locking: ratings write - Rating setRating(T txn, AuthorId a, Rating r) throws DbException; - - // Locking: messages write - void setSendability(T txn, MessageId m, int sendability) throws DbException; - - // Locking: neighbours read, n write + /** + * Removes and returns the IDs of any batches received from the given + * neighbour that need to be acknowledged. + * Locking: neighbours write. + */ Set<BatchId> removeBatchesToAck(T txn, NeighbourId n) throws DbException; - // Locking: neighbours write, messages read + /** + * Removes an outstanding batch that is considered to have been lost. Any + * messages in the batch that are still considered outstanding + * (Status.SENT) with respect to the given neighbour are now considered + * unsent (Status.NEW). + * Locking: neighbours write, messages read. + */ void removeLostBatch(T txn, NeighbourId n, BatchId b) throws DbException; - // Locking: neighbours write, messages write + /** + * Removes a message from the database. + * Locking: neighbours write, messages write. + */ void removeMessage(T txn, MessageId m) throws DbException; - // Locking: neighbours write + /** + * Removes an outstanding batch that has been acknowledged. The status of + * the acknowledged messages is not updated. + * Locking: neighbours write. + */ Set<MessageId> removeOutstandingBatch(T txn, NeighbourId n, BatchId b) throws DbException; - // Locking: subscriptions write, neighbours write, messages write + /** + * Unsubscribes from the given group. Any messages belonging to the group + * are deleted from the database. + * Locking: subscriptions write, neighbours write, messages write. + */ void removeSubscription(T txn, GroupId g) throws DbException; - // Locking: neighbours write, messages read + /** + * Records the user's rating for the given author. + * Locking: ratings write. + */ + Rating setRating(T txn, AuthorId a, Rating r) throws DbException; + + /** + * Records the sendability score of the given message. + * Locking: messages write. + */ + void setSendability(T txn, MessageId m, int sendability) throws DbException; + + /** + * Sets the status of the given message with respect to the given neighbour. + * Locking: neighbours write, messages read + */ void setStatus(T txn, NeighbourId n, MessageId m, Status s) throws DbException; }