Moved ConnectionWindow into the transport module and implemented

window sliding (untested).
This commit is contained in:
akwizgran
2011-08-11 13:22:23 +01:00
parent d5d03192e3
commit e0b86f1232
11 changed files with 106 additions and 56 deletions

View File

@@ -1,12 +0,0 @@
package net.sf.briar.api.db;
public interface ConnectionWindow {
long getCentre();
void setCentre(long centre);
int getBitmap();
void setBitmap(int bitmap);
}

View File

@@ -0,0 +1,12 @@
package net.sf.briar.api.transport;
public interface ConnectionWindow {
long getCentre();
int getBitmap();
boolean isSeen(long connectionNumber);
void setSeen(long connectionNumber);
}

View File

@@ -0,0 +1,6 @@
package net.sf.briar.api.transport;
public interface ConnectionWindowFactory {
ConnectionWindow createConnectionWindow(long centre, int bitmap);
}

View File

@@ -1,30 +0,0 @@
package net.sf.briar.db;
import net.sf.briar.api.db.ConnectionWindow;
class ConnectionWindowImpl implements ConnectionWindow {
private long centre;
private int bitmap;
ConnectionWindowImpl(long centre, int bitmap) {
this.centre = centre;
this.bitmap = bitmap;
}
public long getCentre() {
return centre;
}
public void setCentre(long centre) {
this.centre = centre;
}
public int getBitmap() {
return bitmap;
}
public void setBitmap(int bitmap) {
this.bitmap = bitmap;
}
}

View File

@@ -5,7 +5,6 @@ import java.util.Map;
import net.sf.briar.api.ContactId;
import net.sf.briar.api.Rating;
import net.sf.briar.api.db.ConnectionWindow;
import net.sf.briar.api.db.DbException;
import net.sf.briar.api.db.Status;
import net.sf.briar.api.protocol.AuthorId;
@@ -14,6 +13,7 @@ import net.sf.briar.api.protocol.Group;
import net.sf.briar.api.protocol.GroupId;
import net.sf.briar.api.protocol.Message;
import net.sf.briar.api.protocol.MessageId;
import net.sf.briar.api.transport.ConnectionWindow;
/**
* A low-level interface to the database (DatabaseComponent provides a

View File

@@ -14,6 +14,7 @@ import net.sf.briar.api.crypto.Password;
import net.sf.briar.api.db.DatabasePassword;
import net.sf.briar.api.db.DbException;
import net.sf.briar.api.protocol.GroupFactory;
import net.sf.briar.api.transport.ConnectionWindowFactory;
import org.apache.commons.io.FileSystemUtils;
@@ -32,8 +33,9 @@ class H2Database extends JdbcDatabase {
@Inject
H2Database(File dir, @DatabasePassword Password password, long maxSize,
ConnectionWindowFactory connectionWindowFactory,
GroupFactory groupFactory) {
super(groupFactory, "BINARY(32)", "BINARY");
super(connectionWindowFactory, groupFactory, "BINARY(32)", "BINARY");
home = new File(dir, "db");
this.password = password;
url = "jdbc:h2:split:" + home.getPath()

View File

@@ -20,7 +20,6 @@ import java.util.logging.Logger;
import net.sf.briar.api.ContactId;
import net.sf.briar.api.Rating;
import net.sf.briar.api.db.ConnectionWindow;
import net.sf.briar.api.db.DatabaseComponent;
import net.sf.briar.api.db.DbException;
import net.sf.briar.api.db.Status;
@@ -31,6 +30,8 @@ import net.sf.briar.api.protocol.GroupFactory;
import net.sf.briar.api.protocol.GroupId;
import net.sf.briar.api.protocol.Message;
import net.sf.briar.api.protocol.MessageId;
import net.sf.briar.api.transport.ConnectionWindow;
import net.sf.briar.api.transport.ConnectionWindowFactory;
import net.sf.briar.util.FileUtils;
/**
@@ -200,6 +201,7 @@ abstract class JdbcDatabase implements Database<Connection> {
// Different database libraries use different names for certain types
private final String hashType, binaryType;
private final ConnectionWindowFactory connectionWindowFactory;
private final GroupFactory groupFactory;
private final LinkedList<Connection> connections =
new LinkedList<Connection>(); // Locking: self
@@ -209,8 +211,9 @@ abstract class JdbcDatabase implements Database<Connection> {
protected abstract Connection createConnection() throws SQLException;
JdbcDatabase(GroupFactory groupFactory, String hashType,
String binaryType) {
JdbcDatabase(ConnectionWindowFactory connectionWindowFactory,
GroupFactory groupFactory, String hashType, String binaryType) {
this.connectionWindowFactory = connectionWindowFactory;
this.groupFactory = groupFactory;
this.hashType = hashType;
this.binaryType = binaryType;
@@ -750,7 +753,8 @@ abstract class JdbcDatabase implements Database<Connection> {
}
rs.close();
ps.close();
return new ConnectionWindowImpl(centre, bitmap);
return connectionWindowFactory.createConnectionWindow(centre,
bitmap);
} catch(SQLException e) {
tryToClose(rs);
tryToClose(ps);

View File

@@ -0,0 +1,11 @@
package net.sf.briar.transport;
import net.sf.briar.api.transport.ConnectionWindow;
import net.sf.briar.api.transport.ConnectionWindowFactory;
class ConnectionWindowFactoryImpl implements ConnectionWindowFactory {
public ConnectionWindow createConnectionWindow(long centre, int bitmap) {
return new ConnectionWindowImpl(centre, bitmap);
}
}

View File

@@ -0,0 +1,50 @@
package net.sf.briar.transport;
import net.sf.briar.api.transport.ConnectionWindow;
class ConnectionWindowImpl implements ConnectionWindow {
private static final long MAX_32_BIT_UNSIGNED = 4294967295L; // 2^32 - 1
private long centre;
private int bitmap;
ConnectionWindowImpl(long centre, int bitmap) {
this.centre = centre;
this.bitmap = bitmap;
}
public long getCentre() {
return centre;
}
public int getBitmap() {
return bitmap;
}
public boolean isSeen(long connectionNumber) {
int offset = getOffset(connectionNumber);
int mask = 0x80000000 >>> offset;
return (bitmap & mask) != 0;
}
public void setSeen(long connectionNumber) {
int offset = getOffset(connectionNumber);
int mask = 0x80000000 >>> offset;
bitmap |= mask;
// If the new connection number is above the centre, slide the window
if(connectionNumber >= centre) {
centre = connectionNumber + 1;
bitmap <<= offset - 16 + 1;
}
}
private int getOffset(long connectionNumber) {
if(connectionNumber < 0L) throw new IllegalArgumentException();
if(connectionNumber > MAX_32_BIT_UNSIGNED)
throw new IllegalArgumentException();
int offset = (int) (connectionNumber - centre) + 16;
if(offset < 0 || offset > 31) throw new IllegalArgumentException();
return offset;
}
}

View File

@@ -1,5 +1,6 @@
package net.sf.briar.transport;
import net.sf.briar.api.transport.ConnectionWindowFactory;
import net.sf.briar.api.transport.PacketWriter;
import com.google.inject.AbstractModule;
@@ -8,6 +9,7 @@ public class TransportModule extends AbstractModule {
@Override
protected void configure() {
bind(PacketWriter.class).to(PacketWriterImpl.class);
bind(ConnectionWindowFactory.class).to(
ConnectionWindowFactoryImpl.class);
}
}

View File

@@ -17,7 +17,6 @@ import net.sf.briar.TestUtils;
import net.sf.briar.api.ContactId;
import net.sf.briar.api.Rating;
import net.sf.briar.api.crypto.Password;
import net.sf.briar.api.db.ConnectionWindow;
import net.sf.briar.api.db.DbException;
import net.sf.briar.api.db.Status;
import net.sf.briar.api.protocol.AuthorId;
@@ -27,9 +26,12 @@ import net.sf.briar.api.protocol.GroupFactory;
import net.sf.briar.api.protocol.GroupId;
import net.sf.briar.api.protocol.Message;
import net.sf.briar.api.protocol.MessageId;
import net.sf.briar.api.transport.ConnectionWindow;
import net.sf.briar.api.transport.ConnectionWindowFactory;
import net.sf.briar.crypto.CryptoModule;
import net.sf.briar.protocol.ProtocolModule;
import net.sf.briar.serial.SerialModule;
import net.sf.briar.transport.TransportModule;
import org.apache.commons.io.FileSystemUtils;
import org.junit.After;
@@ -49,6 +51,7 @@ public class H2DatabaseTest extends TestCase {
private final String passwordString = "foo bar";
private final Password password = new TestPassword();
private final Random random = new Random();
private final ConnectionWindowFactory connectionWindowFactory;
private final GroupFactory groupFactory;
private final AuthorId authorId;
@@ -67,7 +70,9 @@ public class H2DatabaseTest extends TestCase {
public H2DatabaseTest() throws Exception {
super();
Injector i = Guice.createInjector(new CryptoModule(),
new ProtocolModule(), new SerialModule());
new ProtocolModule(), new SerialModule(),
new TransportModule());
connectionWindowFactory = i.getInstance(ConnectionWindowFactory.class);
groupFactory = i.getInstance(GroupFactory.class);
authorId = new AuthorId(TestUtils.getRandomId());
batchId = new BatchId(TestUtils.getRandomId());
@@ -1248,15 +1253,15 @@ public class H2DatabaseTest extends TestCase {
assertEquals(0, w.getBitmap());
// Update the connection window and store it
w.setCentre(1);
w.setBitmap(0x00008000);
w.setSeen(5L);
db.setConnectionWindow(txn, contactId, 123, w);
// Check that the connection window was stored
w = db.getConnectionWindow(txn, contactId, 123);
assertNotNull(w);
assertEquals(1L, w.getCentre());
assertEquals(0x00008000, w.getBitmap());
assertEquals(6L, w.getCentre());
assertTrue(w.isSeen(5L));
assertEquals(0x00010000, w.getBitmap());
db.commitTransaction(txn);
db.close();
@@ -1280,7 +1285,7 @@ public class H2DatabaseTest extends TestCase {
private Database<Connection> open(boolean resume) throws DbException {
Database<Connection> db = new H2Database(testDir, password, MAX_SIZE,
groupFactory);
connectionWindowFactory, groupFactory);
db.open(resume);
return db;
}