Builders for batches and bundles.

This commit is contained in:
akwizgran
2011-07-11 12:25:04 +01:00
parent 51e371f7ca
commit 4f5eb21180
13 changed files with 162 additions and 119 deletions

View File

@@ -7,6 +7,7 @@ import net.sf.briar.api.ContactId;
import net.sf.briar.api.Rating;
import net.sf.briar.api.protocol.AuthorId;
import net.sf.briar.api.protocol.Bundle;
import net.sf.briar.api.protocol.BundleBuilder;
import net.sf.briar.api.protocol.GroupId;
import net.sf.briar.api.protocol.Message;
@@ -48,7 +49,7 @@ public interface DatabaseComponent {
* Generates a bundle of acknowledgements, subscriptions, and batches of
* messages for the given contact.
*/
void generateBundle(ContactId c, Bundle b) throws DbException;
Bundle generateBundle(ContactId c, BundleBuilder bundleBuilder) throws DbException;
/** Returns the IDs of all contacts. */
Set<ContactId> getContacts() throws DbException;

View File

@@ -5,12 +5,7 @@ public interface Batch {
public static final long CAPACITY = 1024L * 1024L;
/** Prepares the batch for transmission and generates its identifier. */
public void seal();
/**
* Returns the batch's unique identifier. Cannot be called before seal().
*/
/** Returns the batch's unique identifier. */
BatchId getId();
/** Returns the size of the batch in bytes. */
@@ -18,7 +13,4 @@ public interface Batch {
/** Returns the messages contained in the batch. */
Iterable<Message> getMessages();
/** Adds a message to the batch. Cannot be called after seal(). */
void addMessage(Message m);
}

View File

@@ -0,0 +1,10 @@
package net.sf.briar.api.protocol;
public interface BatchBuilder {
/** Adds a message to the batch. */
void addMessage(Message m);
/** Builds and returns the batch. */
Batch build();
}

View File

@@ -5,12 +5,7 @@ import java.util.Map;
/** A bundle of acknowledgements, subscriptions, and batches of messages. */
public interface Bundle {
/** Prepares the bundle for transmission and generates its identifier. */
public void seal();
/**
* Returns the bundle's unique identifier. Cannot be called before seal().
*/
/** Returns the bundle's unique identifier. */
BundleId getId();
/** Returns the bundle's capacity in bytes. */
@@ -22,26 +17,12 @@ public interface Bundle {
/** Returns the acknowledgements contained in the bundle. */
Iterable<BatchId> getAcks();
/** Adds an acknowledgement to the bundle. Cannot be called after seal(). */
void addAck(BatchId b);
/** Returns the subscriptions contained in the bundle. */
Iterable<GroupId> getSubscriptions();
/** Adds a subscription to the bundle. Cannot be called after seal(). */
void addSubscription(GroupId g);
/** Returns the transport details contained in the bundle. */
Map<String, String> getTransports();
/** Adds a transport detail to the bundle. Cannot be called after seal(). */
void addTransport(String key, String value);
/** Returns the batches of messages contained in the bundle. */
Iterable<Batch> getBatches();
/**
* Adds a batch of messages to the bundle. Cannot be called after seal().
*/
void addBatch(Batch b);
}

View File

@@ -0,0 +1,22 @@
package net.sf.briar.api.protocol;
public interface BundleBuilder {
/** Returns the bundle's capacity in bytes. */
long getCapacity();
/** Adds an acknowledgement to the bundle. */
void addAck(BatchId b);
/** Adds a subscription to the bundle. */
void addSubscription(GroupId g);
/** Adds a transport detail to the bundle. */
void addTransport(String key, String value);
/** Adds a batch of messages to the bundle. */
void addBatch(Batch b);
/** Builds and returns the bundle. */
Bundle build();
}

View File

@@ -9,7 +9,7 @@ import net.sf.briar.api.db.DatabaseComponent;
import net.sf.briar.api.db.DbException;
import net.sf.briar.api.db.Status;
import net.sf.briar.api.protocol.AuthorId;
import net.sf.briar.api.protocol.Batch;
import net.sf.briar.api.protocol.BatchBuilder;
import net.sf.briar.api.protocol.Message;
import net.sf.briar.api.protocol.MessageId;
@@ -27,7 +27,7 @@ DatabaseCleaner.Callback {
protected final Database<Txn> db;
protected final DatabaseCleaner cleaner;
protected final Provider<Batch> batchProvider;
protected final Provider<BatchBuilder> batchBuilderProvider;
private final Object spaceLock = new Object();
private final Object writeLock = new Object();
@@ -36,10 +36,10 @@ DatabaseCleaner.Callback {
private volatile boolean writesAllowed = true;
DatabaseComponentImpl(Database<Txn> db, DatabaseCleaner cleaner,
Provider<Batch> batchProvider) {
Provider<BatchBuilder> batchBuilderProvider) {
this.db = db;
this.cleaner = cleaner;
this.batchProvider = batchProvider;
this.batchBuilderProvider = batchBuilderProvider;
}
public void open(boolean resume) throws DbException {

View File

@@ -15,8 +15,10 @@ import net.sf.briar.api.db.DbException;
import net.sf.briar.api.db.NoSuchContactException;
import net.sf.briar.api.protocol.AuthorId;
import net.sf.briar.api.protocol.Batch;
import net.sf.briar.api.protocol.BatchBuilder;
import net.sf.briar.api.protocol.BatchId;
import net.sf.briar.api.protocol.Bundle;
import net.sf.briar.api.protocol.BundleBuilder;
import net.sf.briar.api.protocol.GroupId;
import net.sf.briar.api.protocol.Message;
import net.sf.briar.api.protocol.MessageId;
@@ -53,8 +55,8 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
@Inject
ReadWriteLockDatabaseComponent(Database<Txn> db, DatabaseCleaner cleaner,
Provider<Batch> batchProvider) {
super(db, cleaner, batchProvider);
Provider<BatchBuilder> batchBuilderProvider) {
super(db, cleaner, batchBuilderProvider);
}
public void close() throws DbException {
@@ -184,7 +186,8 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
}
}
public void generateBundle(ContactId c, Bundle b) throws DbException {
public Bundle generateBundle(ContactId c, BundleBuilder b)
throws DbException {
if(LOG.isLoggable(Level.FINE)) LOG.fine("Generating bundle for " + c);
// Ack all batches received from c
contactLock.readLock().lock();
@@ -277,10 +280,11 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
// more messages trickling in but we can't wait forever
if(size * 2 < Batch.CAPACITY) break;
}
b.seal();
Bundle bundle = b.build();
if(LOG.isLoggable(Level.FINE))
LOG.fine("Bundle sent, " + b.getSize() + " bytes");
LOG.fine("Bundle generated, " + bundle.getSize() + " bytes");
System.gc();
return bundle;
}
private Batch fillBatch(ContactId c, long capacity) throws DbException {
@@ -290,7 +294,8 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
messageLock.readLock().lock();
try {
Set<MessageId> sent;
Batch b;
BatchBuilder b;
Batch batch;
messageStatusLock.readLock().lock();
try {
Txn txn = db.startTransaction();
@@ -303,13 +308,13 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
return null; // No more messages to send
}
sent = new HashSet<MessageId>();
b = batchProvider.get();
b = batchBuilderProvider.get();
while(it.hasNext()) {
MessageId m = it.next();
b.addMessage(db.getMessage(txn, m));
sent.add(m);
}
b.seal();
batch = b.build();
db.commitTransaction(txn);
} catch(DbException e) {
db.abortTransaction(txn);
@@ -324,9 +329,9 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
Txn txn = db.startTransaction();
try {
assert !sent.isEmpty();
db.addOutstandingBatch(txn, c, b.getId(), sent);
db.addOutstandingBatch(txn, c, batch.getId(), sent);
db.commitTransaction(txn);
return b;
return batch;
} catch(DbException e) {
db.abortTransaction(txn);
throw e;

View File

@@ -3,8 +3,8 @@ package net.sf.briar.db;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -14,8 +14,10 @@ import net.sf.briar.api.db.DbException;
import net.sf.briar.api.db.NoSuchContactException;
import net.sf.briar.api.protocol.AuthorId;
import net.sf.briar.api.protocol.Batch;
import net.sf.briar.api.protocol.BatchBuilder;
import net.sf.briar.api.protocol.BatchId;
import net.sf.briar.api.protocol.Bundle;
import net.sf.briar.api.protocol.BundleBuilder;
import net.sf.briar.api.protocol.GroupId;
import net.sf.briar.api.protocol.Message;
import net.sf.briar.api.protocol.MessageId;
@@ -46,8 +48,8 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
@Inject
SynchronizedDatabaseComponent(Database<Txn> db, DatabaseCleaner cleaner,
Provider<Batch> batchProvider) {
super(db, cleaner, batchProvider);
Provider<BatchBuilder> batchBuilderProvider) {
super(db, cleaner, batchBuilderProvider);
}
public void close() throws DbException {
@@ -137,7 +139,8 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
}
}
public void generateBundle(ContactId c, Bundle b) throws DbException {
public Bundle generateBundle(ContactId c, BundleBuilder b)
throws DbException {
if(LOG.isLoggable(Level.FINE)) LOG.fine("Generating bundle for " + c);
// Ack all batches received from c
synchronized(contactLock) {
@@ -212,10 +215,11 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
// more messages trickling in but we can't wait forever
if(size * 2 < Batch.CAPACITY) break;
}
b.seal();
Bundle bundle = b.build();
if(LOG.isLoggable(Level.FINE))
LOG.fine("Bundle sent, " + b.getSize() + " bytes");
LOG.fine("Bundle generated, " + bundle.getSize() + " bytes");
System.gc();
return bundle;
}
private Batch fillBatch(ContactId c, long capacity) throws DbException {
@@ -232,19 +236,19 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
db.commitTransaction(txn);
return null; // No more messages to send
}
Batch b = batchProvider.get();
BatchBuilder b = batchBuilderProvider.get();
Set<MessageId> sent = new HashSet<MessageId>();
while(it.hasNext()) {
MessageId m = it.next();
b.addMessage(db.getMessage(txn, m));
sent.add(m);
}
b.seal();
Batch batch = b.build();
// Record the contents of the batch
assert !sent.isEmpty();
db.addOutstandingBatch(txn, c, b.getId(), sent);
db.addOutstandingBatch(txn, c, batch.getId(), sent);
db.commitTransaction(txn);
return b;
return batch;
} catch(DbException e) {
db.abortTransaction(txn);
throw e;

View File

@@ -20,6 +20,8 @@
<test name='net.sf.briar.i18n.FontManagerTest'/>
<test name='net.sf.briar.i18n.I18nTest'/>
<test name='net.sf.briar.invitation.InvitationWorkerTest'/>
<test name='net.sf.briar.serial.ReaderImplTest'/>
<test name='net.sf.briar.serial.WriterImplTest'/>
<test name='net.sf.briar.setup.SetupWorkerTest'/>
<test name='net.sf.briar.util.FileUtilsTest'/>
<test name='net.sf.briar.util.StringUtilsTest'/>

View File

@@ -6,7 +6,7 @@ import static net.sf.briar.api.db.DatabaseComponent.MIN_FREE_SPACE;
import java.util.Collections;
import net.sf.briar.api.db.DbException;
import net.sf.briar.api.protocol.Batch;
import net.sf.briar.api.protocol.BatchBuilder;
import net.sf.briar.api.protocol.MessageId;
import net.sf.briar.db.DatabaseCleaner.Callback;
@@ -24,7 +24,7 @@ public abstract class DatabaseComponentImplTest extends DatabaseComponentTest {
protected abstract <T> DatabaseComponentImpl<T> createDatabaseComponentImpl(
Database<T> database, DatabaseCleaner cleaner,
Provider<Batch> batchProvider);
Provider<BatchBuilder> batchBuilderProvider);
@Test
public void testNotCleanedIfEnoughFreeSpace() throws DbException {
@@ -33,13 +33,14 @@ public abstract class DatabaseComponentImplTest extends DatabaseComponentTest {
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
@SuppressWarnings("unchecked")
final Provider<Batch> batchProvider = context.mock(Provider.class);
final Provider<BatchBuilder> batchBuilderProvider =
context.mock(Provider.class);
context.checking(new Expectations() {{
oneOf(database).getFreeSpace();
will(returnValue(MIN_FREE_SPACE));
}});
Callback db = createDatabaseComponentImpl(database, cleaner,
batchProvider);
batchBuilderProvider);
db.checkFreeSpaceAndClean();
@@ -53,7 +54,8 @@ public abstract class DatabaseComponentImplTest extends DatabaseComponentTest {
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
@SuppressWarnings("unchecked")
final Provider<Batch> batchProvider = context.mock(Provider.class);
final Provider<BatchBuilder> batchBuilderProvider =
context.mock(Provider.class);
context.checking(new Expectations() {{
oneOf(database).getFreeSpace();
will(returnValue(MIN_FREE_SPACE - 1));
@@ -67,7 +69,7 @@ public abstract class DatabaseComponentImplTest extends DatabaseComponentTest {
will(returnValue(MIN_FREE_SPACE));
}});
Callback db = createDatabaseComponentImpl(database, cleaner,
batchProvider);
batchBuilderProvider);
db.checkFreeSpaceAndClean();
@@ -82,7 +84,8 @@ public abstract class DatabaseComponentImplTest extends DatabaseComponentTest {
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
@SuppressWarnings("unchecked")
final Provider<Batch> batchProvider = context.mock(Provider.class);
final Provider<BatchBuilder> batchBuilderProvider =
context.mock(Provider.class);
context.checking(new Expectations() {{
oneOf(database).getFreeSpace();
will(returnValue(MIN_FREE_SPACE - 1));
@@ -98,7 +101,7 @@ public abstract class DatabaseComponentImplTest extends DatabaseComponentTest {
will(returnValue(MIN_FREE_SPACE));
}});
Callback db = createDatabaseComponentImpl(database, cleaner,
batchProvider);
batchBuilderProvider);
db.checkFreeSpaceAndClean();
@@ -113,7 +116,8 @@ public abstract class DatabaseComponentImplTest extends DatabaseComponentTest {
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
@SuppressWarnings("unchecked")
final Provider<Batch> batchProvider = context.mock(Provider.class);
final Provider<BatchBuilder> batchBuilderProvider =
context.mock(Provider.class);
context.checking(new Expectations() {{
oneOf(database).getFreeSpace();
will(returnValue(MIN_FREE_SPACE - 1));
@@ -131,7 +135,7 @@ public abstract class DatabaseComponentImplTest extends DatabaseComponentTest {
will(returnValue(MIN_FREE_SPACE));
}});
Callback db = createDatabaseComponentImpl(database, cleaner,
batchProvider);
batchBuilderProvider);
db.checkFreeSpaceAndClean();

View File

@@ -14,8 +14,10 @@ import net.sf.briar.api.db.NoSuchContactException;
import net.sf.briar.api.db.Status;
import net.sf.briar.api.protocol.AuthorId;
import net.sf.briar.api.protocol.Batch;
import net.sf.briar.api.protocol.BatchBuilder;
import net.sf.briar.api.protocol.BatchId;
import net.sf.briar.api.protocol.Bundle;
import net.sf.briar.api.protocol.BundleBuilder;
import net.sf.briar.api.protocol.BundleId;
import net.sf.briar.api.protocol.GroupId;
import net.sf.briar.api.protocol.Message;
@@ -62,7 +64,7 @@ public abstract class DatabaseComponentTest extends TestCase {
protected abstract <T> DatabaseComponent createDatabaseComponent(
Database<T> database, DatabaseCleaner cleaner,
Provider<Batch> batchProvider);
Provider<BatchBuilder> batchBuilderProvider);
@Test
public void testSimpleCalls() throws DbException {
@@ -76,7 +78,8 @@ public abstract class DatabaseComponentTest extends TestCase {
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
@SuppressWarnings("unchecked")
final Provider<Batch> batchProvider = context.mock(Provider.class);
final Provider<BatchBuilder> batchBuilderProvider =
context.mock(Provider.class);
context.checking(new Expectations() {{
allowing(database).startTransaction();
will(returnValue(txn));
@@ -116,7 +119,7 @@ public abstract class DatabaseComponentTest extends TestCase {
oneOf(database).close();
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
batchProvider);
batchBuilderProvider);
db.open(false);
assertEquals(Rating.UNRATED, db.getRating(authorId));
@@ -141,7 +144,8 @@ public abstract class DatabaseComponentTest extends TestCase {
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
@SuppressWarnings("unchecked")
final Provider<Batch> batchProvider = context.mock(Provider.class);
final Provider<BatchBuilder> batchBuilderProvider =
context.mock(Provider.class);
context.checking(new Expectations() {{
// setRating(Rating.GOOD)
allowing(database).startTransaction();
@@ -159,7 +163,7 @@ public abstract class DatabaseComponentTest extends TestCase {
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
batchProvider);
batchBuilderProvider);
db.setRating(authorId, Rating.GOOD);
@@ -174,7 +178,8 @@ public abstract class DatabaseComponentTest extends TestCase {
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
@SuppressWarnings("unchecked")
final Provider<Batch> batchProvider = context.mock(Provider.class);
final Provider<BatchBuilder> batchBuilderProvider =
context.mock(Provider.class);
context.checking(new Expectations() {{
// setRating(Rating.GOOD)
oneOf(database).startTransaction();
@@ -195,7 +200,7 @@ public abstract class DatabaseComponentTest extends TestCase {
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
batchProvider);
batchBuilderProvider);
db.setRating(authorId, Rating.GOOD);
@@ -211,7 +216,8 @@ public abstract class DatabaseComponentTest extends TestCase {
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
@SuppressWarnings("unchecked")
final Provider<Batch> batchProvider = context.mock(Provider.class);
final Provider<BatchBuilder> batchBuilderProvider =
context.mock(Provider.class);
context.checking(new Expectations() {{
// setRating(Rating.GOOD)
oneOf(database).startTransaction();
@@ -236,7 +242,7 @@ public abstract class DatabaseComponentTest extends TestCase {
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
batchProvider);
batchBuilderProvider);
db.setRating(authorId, Rating.GOOD);
@@ -252,7 +258,8 @@ public abstract class DatabaseComponentTest extends TestCase {
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
@SuppressWarnings("unchecked")
final Provider<Batch> batchProvider = context.mock(Provider.class);
final Provider<BatchBuilder> batchBuilderProvider =
context.mock(Provider.class);
context.checking(new Expectations() {{
// setRating(Rating.GOOD)
oneOf(database).startTransaction();
@@ -280,7 +287,7 @@ public abstract class DatabaseComponentTest extends TestCase {
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
batchProvider);
batchBuilderProvider);
db.setRating(authorId, Rating.GOOD);
@@ -296,7 +303,8 @@ public abstract class DatabaseComponentTest extends TestCase {
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
@SuppressWarnings("unchecked")
final Provider<Batch> batchProvider = context.mock(Provider.class);
final Provider<BatchBuilder> batchBuilderProvider =
context.mock(Provider.class);
context.checking(new Expectations() {{
// setRating(Rating.GOOD)
oneOf(database).startTransaction();
@@ -326,7 +334,7 @@ public abstract class DatabaseComponentTest extends TestCase {
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
batchProvider);
batchBuilderProvider);
db.setRating(authorId, Rating.GOOD);
@@ -341,7 +349,8 @@ public abstract class DatabaseComponentTest extends TestCase {
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
@SuppressWarnings("unchecked")
final Provider<Batch> batchProvider = context.mock(Provider.class);
final Provider<BatchBuilder> batchBuilderProvider =
context.mock(Provider.class);
context.checking(new Expectations() {{
// addLocallyGeneratedMessage(message)
oneOf(database).startTransaction();
@@ -351,7 +360,7 @@ public abstract class DatabaseComponentTest extends TestCase {
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
batchProvider);
batchBuilderProvider);
db.addLocallyGeneratedMessage(message);
@@ -365,7 +374,8 @@ public abstract class DatabaseComponentTest extends TestCase {
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
@SuppressWarnings("unchecked")
final Provider<Batch> batchProvider = context.mock(Provider.class);
final Provider<BatchBuilder> batchBuilderProvider =
context.mock(Provider.class);
context.checking(new Expectations() {{
// addLocallyGeneratedMessage(message)
oneOf(database).startTransaction();
@@ -377,7 +387,7 @@ public abstract class DatabaseComponentTest extends TestCase {
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
batchProvider);
batchBuilderProvider);
db.addLocallyGeneratedMessage(message);
@@ -391,7 +401,8 @@ public abstract class DatabaseComponentTest extends TestCase {
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
@SuppressWarnings("unchecked")
final Provider<Batch> batchProvider = context.mock(Provider.class);
final Provider<BatchBuilder> batchBuilderProvider =
context.mock(Provider.class);
context.checking(new Expectations() {{
// addLocallyGeneratedMessage(message)
oneOf(database).startTransaction();
@@ -412,7 +423,7 @@ public abstract class DatabaseComponentTest extends TestCase {
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
batchProvider);
batchBuilderProvider);
db.addLocallyGeneratedMessage(message);
@@ -427,7 +438,8 @@ public abstract class DatabaseComponentTest extends TestCase {
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
@SuppressWarnings("unchecked")
final Provider<Batch> batchProvider = context.mock(Provider.class);
final Provider<BatchBuilder> batchBuilderProvider =
context.mock(Provider.class);
context.checking(new Expectations() {{
// addLocallyGeneratedMessage(message)
oneOf(database).startTransaction();
@@ -451,7 +463,7 @@ public abstract class DatabaseComponentTest extends TestCase {
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
batchProvider);
batchBuilderProvider);
db.addLocallyGeneratedMessage(message);
@@ -466,8 +478,9 @@ public abstract class DatabaseComponentTest extends TestCase {
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
@SuppressWarnings("unchecked")
final Provider<Batch> batchProvider = context.mock(Provider.class);
final Bundle bundle = context.mock(Bundle.class);
final Provider<BatchBuilder> batchBuilderProvider =
context.mock(Provider.class);
final BundleBuilder bundleBuilder = context.mock(BundleBuilder.class);
context.checking(new Expectations() {{
// Check that the contact is still in the DB
oneOf(database).startTransaction();
@@ -477,10 +490,10 @@ public abstract class DatabaseComponentTest extends TestCase {
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
batchProvider);
batchBuilderProvider);
try {
db.generateBundle(contactId, bundle);
db.generateBundle(contactId, bundleBuilder);
assertTrue(false);
} catch(NoSuchContactException expected) {}
@@ -494,9 +507,12 @@ public abstract class DatabaseComponentTest extends TestCase {
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
@SuppressWarnings("unchecked")
final Provider<Batch> batchProvider = context.mock(Provider.class);
final Bundle bundle = context.mock(Bundle.class);
final Provider<BatchBuilder> batchBuilderProvider =
context.mock(Provider.class);
final BundleBuilder bundleBuilder = context.mock(BundleBuilder.class);
final BatchBuilder batchBuilder = context.mock(BatchBuilder.class);
final Batch batch = context.mock(Batch.class);
final Bundle bundle = context.mock(Bundle.class);
context.checking(new Expectations() {{
allowing(database).startTransaction();
will(returnValue(txn));
@@ -506,44 +522,46 @@ public abstract class DatabaseComponentTest extends TestCase {
// Add acks to the bundle
oneOf(database).removeBatchesToAck(txn, contactId);
will(returnValue(Collections.singleton(batchId)));
oneOf(bundle).addAck(batchId);
oneOf(bundleBuilder).addAck(batchId);
// Add subscriptions to the bundle
oneOf(database).getSubscriptions(txn);
will(returnValue(Collections.singleton(groupId)));
oneOf(bundle).addSubscription(groupId);
oneOf(bundleBuilder).addSubscription(groupId);
// Add transports to the bundle
oneOf(database).getTransports(txn);
will(returnValue(Collections.singletonMap("foo", "bar")));
oneOf(bundle).addTransport("foo", "bar");
oneOf(bundleBuilder).addTransport("foo", "bar");
// Prepare to add batches to the bundle
oneOf(bundle).getCapacity();
oneOf(bundleBuilder).getCapacity();
will(returnValue((long) ONE_MEGABYTE));
// Add messages to the batch
oneOf(database).getSendableMessages(txn, contactId, ONE_MEGABYTE);
oneOf(database).getSendableMessages(txn, contactId, Batch.CAPACITY);
will(returnValue(Collections.singleton(messageId)));
oneOf(batchProvider).get();
will(returnValue(batch));
oneOf(batchBuilderProvider).get();
will(returnValue(batchBuilder));
oneOf(database).getMessage(txn, messageId);
will(returnValue(message));
oneOf(batch).addMessage(message);
oneOf(batch).seal();
oneOf(batchBuilder).addMessage(message);
oneOf(batchBuilder).build();
will(returnValue(batch));
// Record the batch as outstanding
oneOf(batch).getId();
will(returnValue(batchId));
oneOf(database).addOutstandingBatch(txn, contactId, batchId,
Collections.singleton(messageId));
// Add the batch to the bundle
oneOf(bundle).addBatch(batch);
oneOf(bundleBuilder).addBatch(batch);
// Check whether to add another batch
oneOf(batch).getSize();
will(returnValue((long) message.getSize()));
// Nope
oneOf(bundle).seal();
// No, just send the bundle
oneOf(bundleBuilder).build();
will(returnValue(bundle));
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
batchProvider);
batchBuilderProvider);
db.generateBundle(contactId, bundle);
db.generateBundle(contactId, bundleBuilder);
context.assertIsSatisfied();
}
@@ -556,7 +574,8 @@ public abstract class DatabaseComponentTest extends TestCase {
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
@SuppressWarnings("unchecked")
final Provider<Batch> batchProvider = context.mock(Provider.class);
final Provider<BatchBuilder> batchBuilderProvider =
context.mock(Provider.class);
final Bundle bundle = context.mock(Bundle.class);
context.checking(new Expectations() {{
// Check that the contact is still in the DB
@@ -567,7 +586,7 @@ public abstract class DatabaseComponentTest extends TestCase {
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
batchProvider);
batchBuilderProvider);
try {
db.receiveBundle(contactId, bundle);
@@ -586,7 +605,8 @@ public abstract class DatabaseComponentTest extends TestCase {
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
@SuppressWarnings("unchecked")
final Provider<Batch> batchProvider = context.mock(Provider.class);
final Provider<BatchBuilder> batchBuilderProvider =
context.mock(Provider.class);
final Bundle bundle = context.mock(Bundle.class);
final Batch batch = context.mock(Batch.class);
context.checking(new Expectations() {{
@@ -630,7 +650,7 @@ public abstract class DatabaseComponentTest extends TestCase {
oneOf(database).removeLostBatch(txn, contactId, batchId);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
batchProvider);
batchBuilderProvider);
db.receiveBundle(contactId, bundle);

View File

@@ -1,7 +1,7 @@
package net.sf.briar.db;
import net.sf.briar.api.db.DatabaseComponent;
import net.sf.briar.api.protocol.Batch;
import net.sf.briar.api.protocol.BatchBuilder;
import com.google.inject.Provider;
@@ -11,15 +11,16 @@ extends DatabaseComponentImplTest {
@Override
protected <T> DatabaseComponent createDatabaseComponent(
Database<T> database, DatabaseCleaner cleaner,
Provider<Batch> batchProvider) {
return createDatabaseComponentImpl(database, cleaner, batchProvider);
Provider<BatchBuilder> batchBuilderProvider) {
return createDatabaseComponentImpl(database, cleaner,
batchBuilderProvider);
}
@Override
protected <T> DatabaseComponentImpl<T> createDatabaseComponentImpl(
Database<T> database, DatabaseCleaner cleaner,
Provider<Batch> batchProvider) {
Provider<BatchBuilder> batchBuilderProvider) {
return new ReadWriteLockDatabaseComponent<T>(database, cleaner,
batchProvider);
batchBuilderProvider);
}
}

View File

@@ -1,7 +1,7 @@
package net.sf.briar.db;
import net.sf.briar.api.db.DatabaseComponent;
import net.sf.briar.api.protocol.Batch;
import net.sf.briar.api.protocol.BatchBuilder;
import com.google.inject.Provider;
@@ -11,15 +11,16 @@ extends DatabaseComponentImplTest {
@Override
protected <T> DatabaseComponent createDatabaseComponent(
Database<T> database, DatabaseCleaner cleaner,
Provider<Batch> batchProvider) {
return createDatabaseComponentImpl(database, cleaner, batchProvider);
Provider<BatchBuilder> batchBuilderProvider) {
return createDatabaseComponentImpl(database, cleaner,
batchBuilderProvider);
}
@Override
protected <T> DatabaseComponentImpl<T> createDatabaseComponentImpl(
Database<T> database, DatabaseCleaner cleaner,
Provider<Batch> batchProvider) {
Provider<BatchBuilder> batchBuilderProvider) {
return new SynchronizedDatabaseComponent<T>(database, cleaner,
batchProvider);
batchBuilderProvider);
}
}