From 2edb18aee05f894f931c0817e8296795d1028970 Mon Sep 17 00:00:00 2001 From: akwizgran <akwizgran@users.sourceforge.net> Date: Wed, 28 Sep 2011 19:24:22 +0100 Subject: [PATCH] Store outgoing connection numbers in the database. --- .../sf/briar/api/db/DatabaseComponent.java | 6 ++ components/net/sf/briar/db/Database.java | 9 +++ .../sf/briar/db/DatabaseComponentImpl.java | 24 +++++++ components/net/sf/briar/db/JdbcDatabase.java | 63 ++++++++++++++++++- 4 files changed, 99 insertions(+), 3 deletions(-) diff --git a/api/net/sf/briar/api/db/DatabaseComponent.java b/api/net/sf/briar/api/db/DatabaseComponent.java index 5d4e595a93..db220b5122 100644 --- a/api/net/sf/briar/api/db/DatabaseComponent.java +++ b/api/net/sf/briar/api/db/DatabaseComponent.java @@ -98,6 +98,12 @@ public interface DatabaseComponent { void generateTransportUpdate(ContactId c, TransportWriter t) throws 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 * transport. diff --git a/components/net/sf/briar/db/Database.java b/components/net/sf/briar/db/Database.java index 648f231d77..6f1141d27e 100644 --- a/components/net/sf/briar/db/Database.java +++ b/components/net/sf/briar/db/Database.java @@ -165,6 +165,15 @@ interface Database<T> { */ 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 * transport. diff --git a/components/net/sf/briar/db/DatabaseComponentImpl.java b/components/net/sf/briar/db/DatabaseComponentImpl.java index 7ef8202db8..25e9025277 100644 --- a/components/net/sf/briar/db/DatabaseComponentImpl.java +++ b/components/net/sf/briar/db/DatabaseComponentImpl.java @@ -632,6 +632,30 @@ DatabaseCleaner.Callback { 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) throws DbException { contactLock.readLock().lock(); diff --git a/components/net/sf/briar/db/JdbcDatabase.java b/components/net/sf/briar/db/JdbcDatabase.java index 8e29f1f942..65f8b40e16 100644 --- a/components/net/sf/briar/db/JdbcDatabase.java +++ b/components/net/sf/briar/db/JdbcDatabase.java @@ -194,6 +194,7 @@ abstract class JdbcDatabase implements Database<Connection> { + " transportId INT NOT NULL," + " centre BIGINT NOT NULL," + " bitmap INT NOT NULL," + + " outgoing BIGINT NOT NULL," + " PRIMARY KEY (contactId, transportId)," + " FOREIGN KEY (contactId) REFERENCES contacts (contactId)" + " 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, int transportId) throws DbException { PreparedStatement ps = null; @@ -1733,23 +1784,29 @@ abstract class JdbcDatabase implements Database<Connection> { sql = "UPDATE connectionWindows SET centre = ?, bitmap = ?" + " WHERE contactId = ? AND transportId = ?"; 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(); if(affected != 1) throw new DbStateException(); + ps.close(); } else { rs.close(); ps.close(); sql = "INSERT INTO connectionWindows" - + " (contactId, transportId, centre, bitmap)" - + " VALUES(?, ?, ?, ?)"; + + " (contactId, transportId, centre, bitmap, outgoing)" + + " VALUES(?, ?, ?, ?, ?)"; ps = txn.prepareStatement(sql); ps.setInt(1, c.getInt()); ps.setInt(2, transportId); ps.setLong(3, w.getCentre()); ps.setInt(4, w.getBitmap()); + ps.setLong(5, 0L); int affected = ps.executeUpdate(); if(affected != 1) throw new DbStateException(); + ps.close(); } - ps.close(); } catch(SQLException e) { tryToClose(rs); tryToClose(ps); -- GitLab