mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-20 14:49:53 +01:00
Store outgoing connection numbers in the database.
This commit is contained in:
@@ -98,6 +98,12 @@ public interface DatabaseComponent {
|
|||||||
void generateTransportUpdate(ContactId c, TransportWriter t) throws
|
void generateTransportUpdate(ContactId c, TransportWriter t) throws
|
||||||
DbException, IOException;
|
DbException, IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an outgoing connection number for the given contact and
|
||||||
|
* transport.
|
||||||
|
*/
|
||||||
|
long getConnectionNumber(ContactId c, int transportId) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the connection reordering window for the given contact and
|
* Returns the connection reordering window for the given contact and
|
||||||
* transport.
|
* transport.
|
||||||
|
|||||||
@@ -165,6 +165,15 @@ interface Database<T> {
|
|||||||
*/
|
*/
|
||||||
Collection<BatchId> getBatchesToAck(T txn, ContactId c) throws DbException;
|
Collection<BatchId> getBatchesToAck(T txn, ContactId c) throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocates and returns a connection number for the given contact and
|
||||||
|
* transport.
|
||||||
|
* <p>
|
||||||
|
* Locking: contacts read, windows write.
|
||||||
|
*/
|
||||||
|
long getConnectionNumber(T txn, ContactId c, int transportId)
|
||||||
|
throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the connection reordering window for the given contact and
|
* Returns the connection reordering window for the given contact and
|
||||||
* transport.
|
* transport.
|
||||||
|
|||||||
@@ -632,6 +632,30 @@ DatabaseCleaner.Callback {
|
|||||||
LOG.fine("Added " + transports.size() + " transports to update");
|
LOG.fine("Added " + transports.size() + " transports to update");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getConnectionNumber(ContactId c, int transportId)
|
||||||
|
throws DbException {
|
||||||
|
contactLock.readLock().lock();
|
||||||
|
try {
|
||||||
|
if(!containsContact(c)) throw new NoSuchContactException();
|
||||||
|
windowLock.writeLock().lock();
|
||||||
|
try {
|
||||||
|
T txn = db.startTransaction();
|
||||||
|
try {
|
||||||
|
long outgoing = db.getConnectionNumber(txn, c, transportId);
|
||||||
|
db.commitTransaction(txn);
|
||||||
|
return outgoing;
|
||||||
|
} catch(DbException e) {
|
||||||
|
db.abortTransaction(txn);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
windowLock.writeLock().unlock();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
contactLock.readLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public ConnectionWindow getConnectionWindow(ContactId c, int transportId)
|
public ConnectionWindow getConnectionWindow(ContactId c, int transportId)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
contactLock.readLock().lock();
|
contactLock.readLock().lock();
|
||||||
|
|||||||
@@ -194,6 +194,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
+ " transportId INT NOT NULL,"
|
+ " transportId INT NOT NULL,"
|
||||||
+ " centre BIGINT NOT NULL,"
|
+ " centre BIGINT NOT NULL,"
|
||||||
+ " bitmap INT NOT NULL,"
|
+ " bitmap INT NOT NULL,"
|
||||||
|
+ " outgoing BIGINT NOT NULL,"
|
||||||
+ " PRIMARY KEY (contactId, transportId),"
|
+ " PRIMARY KEY (contactId, transportId),"
|
||||||
+ " FOREIGN KEY (contactId) REFERENCES contacts (contactId)"
|
+ " FOREIGN KEY (contactId) REFERENCES contacts (contactId)"
|
||||||
+ " ON DELETE CASCADE)";
|
+ " ON DELETE CASCADE)";
|
||||||
@@ -805,6 +806,56 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getConnectionNumber(Connection txn, ContactId c,
|
||||||
|
int transportId) throws DbException {
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
String sql = "SELECT outgoing FROM connectionWindows"
|
||||||
|
+ " WHERE contactId = ? AND transportId = ?";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setInt(1, c.getInt());
|
||||||
|
ps.setInt(2, transportId);
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
if(rs.next()) {
|
||||||
|
long outgoing = rs.getLong(1);
|
||||||
|
if(rs.next()) throw new DbStateException();
|
||||||
|
rs.close();
|
||||||
|
ps.close();
|
||||||
|
sql = "UPDATE connectionWindows SET outgoing = ?"
|
||||||
|
+ " WHERE contactId = ? AND transportId = ?";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setLong(1, outgoing + 1);
|
||||||
|
ps.setInt(2, c.getInt());
|
||||||
|
ps.setInt(3, transportId);
|
||||||
|
int affected = ps.executeUpdate();
|
||||||
|
if(affected != 1) throw new DbStateException();
|
||||||
|
ps.close();
|
||||||
|
return outgoing;
|
||||||
|
} else {
|
||||||
|
rs.close();
|
||||||
|
ps.close();
|
||||||
|
sql = "INSERT INTO connectionWindows"
|
||||||
|
+ " (contactId, transportId, centre, bitmap, outgoing)"
|
||||||
|
+ " VALUES(?, ?, ?, ?, ?)";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setInt(1, c.getInt());
|
||||||
|
ps.setInt(2, transportId);
|
||||||
|
ps.setLong(3, 0L);
|
||||||
|
ps.setInt(4, 0);
|
||||||
|
ps.setLong(5, 0L);
|
||||||
|
int affected = ps.executeUpdate();
|
||||||
|
if(affected != 1) throw new DbStateException();
|
||||||
|
ps.close();
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
} catch(SQLException e) {
|
||||||
|
tryToClose(rs);
|
||||||
|
tryToClose(ps);
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public ConnectionWindow getConnectionWindow(Connection txn, ContactId c,
|
public ConnectionWindow getConnectionWindow(Connection txn, ContactId c,
|
||||||
int transportId) throws DbException {
|
int transportId) throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
@@ -1733,23 +1784,29 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
sql = "UPDATE connectionWindows SET centre = ?, bitmap = ?"
|
sql = "UPDATE connectionWindows SET centre = ?, bitmap = ?"
|
||||||
+ " WHERE contactId = ? AND transportId = ?";
|
+ " WHERE contactId = ? AND transportId = ?";
|
||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setLong(1, w.getCentre());
|
||||||
|
ps.setInt(2, w.getBitmap());
|
||||||
|
ps.setInt(3, c.getInt());
|
||||||
|
ps.setInt(4, transportId);
|
||||||
int affected = ps.executeUpdate();
|
int affected = ps.executeUpdate();
|
||||||
if(affected != 1) throw new DbStateException();
|
if(affected != 1) throw new DbStateException();
|
||||||
|
ps.close();
|
||||||
} else {
|
} else {
|
||||||
rs.close();
|
rs.close();
|
||||||
ps.close();
|
ps.close();
|
||||||
sql = "INSERT INTO connectionWindows"
|
sql = "INSERT INTO connectionWindows"
|
||||||
+ " (contactId, transportId, centre, bitmap)"
|
+ " (contactId, transportId, centre, bitmap, outgoing)"
|
||||||
+ " VALUES(?, ?, ?, ?)";
|
+ " VALUES(?, ?, ?, ?, ?)";
|
||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
ps.setInt(1, c.getInt());
|
ps.setInt(1, c.getInt());
|
||||||
ps.setInt(2, transportId);
|
ps.setInt(2, transportId);
|
||||||
ps.setLong(3, w.getCentre());
|
ps.setLong(3, w.getCentre());
|
||||||
ps.setInt(4, w.getBitmap());
|
ps.setInt(4, w.getBitmap());
|
||||||
|
ps.setLong(5, 0L);
|
||||||
int affected = ps.executeUpdate();
|
int affected = ps.executeUpdate();
|
||||||
if(affected != 1) throw new DbStateException();
|
if(affected != 1) throw new DbStateException();
|
||||||
|
ps.close();
|
||||||
}
|
}
|
||||||
ps.close();
|
|
||||||
} catch(SQLException e) {
|
} catch(SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs);
|
||||||
tryToClose(ps);
|
tryToClose(ps);
|
||||||
|
|||||||
Reference in New Issue
Block a user