mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-15 20:29:52 +01:00
Retrieve messages from the database in raw form to avoid creating unnecessary short-lived objects. Added timestamps to headers.
This commit is contained in:
@@ -158,11 +158,11 @@ interface Database<T> {
|
||||
Set<BatchId> getLostBatches(T txn, ContactId c) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the message identified by the given ID.
|
||||
* Returns the message identified by the given ID, in raw format.
|
||||
* <p>
|
||||
* Locking: messages read.
|
||||
*/
|
||||
Message getMessage(T txn, MessageId m) throws DbException;
|
||||
byte[] getMessage(T txn, MessageId m) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the IDs of all messages signed by the given author.
|
||||
|
||||
@@ -4,7 +4,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
public class DatabaseCleanerImpl implements DatabaseCleaner, Runnable {
|
||||
class DatabaseCleanerImpl implements DatabaseCleaner, Runnable {
|
||||
|
||||
private final Callback db;
|
||||
private final int msBetweenSweeps;
|
||||
|
||||
@@ -12,7 +12,6 @@ import java.util.logging.Logger;
|
||||
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.MessageFactory;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
@@ -28,9 +27,8 @@ class H2Database extends JdbcDatabase {
|
||||
private final long maxSize;
|
||||
|
||||
@Inject
|
||||
H2Database(File dir, MessageFactory messageFactory,
|
||||
@DatabasePassword Password password, long maxSize) {
|
||||
super(messageFactory, "BINARY(32)", "BIGINT");
|
||||
H2Database(File dir, @DatabasePassword Password password, long maxSize) {
|
||||
super("BINARY(32)", "BIGINT");
|
||||
home = new File(dir, "db");
|
||||
this.password = password;
|
||||
url = "jdbc:h2:split:" + home.getPath()
|
||||
|
||||
@@ -27,7 +27,6 @@ import net.sf.briar.api.protocol.AuthorId;
|
||||
import net.sf.briar.api.protocol.BatchId;
|
||||
import net.sf.briar.api.protocol.GroupId;
|
||||
import net.sf.briar.api.protocol.Message;
|
||||
import net.sf.briar.api.protocol.MessageFactory;
|
||||
import net.sf.briar.api.protocol.MessageId;
|
||||
import net.sf.briar.util.FileUtils;
|
||||
|
||||
@@ -157,7 +156,6 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(JdbcDatabase.class.getName());
|
||||
|
||||
private final MessageFactory messageFactory;
|
||||
// Different database libraries use different names for certain types
|
||||
private final String hashType, bigIntType;
|
||||
private final LinkedList<Connection> connections =
|
||||
@@ -168,9 +166,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
|
||||
protected abstract Connection createConnection() throws SQLException;
|
||||
|
||||
JdbcDatabase(MessageFactory messageFactory, String hashType,
|
||||
String bigIntType) {
|
||||
this.messageFactory = messageFactory;
|
||||
JdbcDatabase(String hashType, String bigIntType) {
|
||||
this.hashType = hashType;
|
||||
this.bigIntType = bigIntType;
|
||||
}
|
||||
@@ -683,32 +679,25 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
}
|
||||
}
|
||||
|
||||
public Message getMessage(Connection txn, MessageId m) throws DbException {
|
||||
public byte[] getMessage(Connection txn, MessageId m) throws DbException {
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
String sql =
|
||||
"SELECT parentId, groupId, authorId, timestamp, size, raw"
|
||||
+ " FROM messages WHERE messageId = ?";
|
||||
String sql = "SELECT size, raw FROM messages WHERE messageId = ?";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setBytes(1, m.getBytes());
|
||||
rs = ps.executeQuery();
|
||||
boolean found = rs.next();
|
||||
assert found;
|
||||
MessageId parent = new MessageId(rs.getBytes(1));
|
||||
GroupId group = new GroupId(rs.getBytes(2));
|
||||
AuthorId author = new AuthorId(rs.getBytes(3));
|
||||
long timestamp = rs.getLong(4);
|
||||
int size = rs.getInt(5);
|
||||
Blob b = rs.getBlob(6);
|
||||
int size = rs.getInt(1);
|
||||
Blob b = rs.getBlob(2);
|
||||
byte[] raw = b.getBytes(1, size);
|
||||
assert raw.length == size;
|
||||
boolean more = rs.next();
|
||||
assert !more;
|
||||
rs.close();
|
||||
ps.close();
|
||||
return messageFactory.createMessage(m, parent, group, author,
|
||||
timestamp, raw);
|
||||
return raw;
|
||||
} catch(SQLException e) {
|
||||
tryToClose(rs);
|
||||
tryToClose(ps);
|
||||
|
||||
@@ -25,6 +25,8 @@ import net.sf.briar.api.protocol.GroupId;
|
||||
import net.sf.briar.api.protocol.Header;
|
||||
import net.sf.briar.api.protocol.Message;
|
||||
import net.sf.briar.api.protocol.MessageId;
|
||||
import net.sf.briar.api.serial.Raw;
|
||||
import net.sf.briar.api.serial.RawByteArray;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
@@ -282,8 +284,8 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
||||
try {
|
||||
Txn txn = db.startTransaction();
|
||||
try {
|
||||
long capacity = Math.min(b.getRemainingCapacity(),
|
||||
Batch.MAX_SIZE);
|
||||
long capacity =
|
||||
Math.min(b.getRemainingCapacity(), Batch.MAX_SIZE);
|
||||
Iterator<MessageId> it =
|
||||
db.getSendableMessages(txn, c, capacity).iterator();
|
||||
if(!it.hasNext()) {
|
||||
@@ -291,12 +293,12 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
||||
return false; // No more messages to send
|
||||
}
|
||||
sent = new HashSet<MessageId>();
|
||||
List<Message> messages = new ArrayList<Message>();
|
||||
List<Raw> messages = new ArrayList<Raw>();
|
||||
while(it.hasNext()) {
|
||||
MessageId m = it.next();
|
||||
Message message = db.getMessage(txn, m);
|
||||
bytesSent += message.getSize();
|
||||
messages.add(message);
|
||||
byte[] message = db.getMessage(txn, m);
|
||||
bytesSent += message.length;
|
||||
messages.add(new RawByteArray(message));
|
||||
sent.add(m);
|
||||
}
|
||||
batchId = b.addBatch(messages);
|
||||
|
||||
@@ -25,6 +25,8 @@ import net.sf.briar.api.protocol.GroupId;
|
||||
import net.sf.briar.api.protocol.Header;
|
||||
import net.sf.briar.api.protocol.Message;
|
||||
import net.sf.briar.api.protocol.MessageId;
|
||||
import net.sf.briar.api.serial.Raw;
|
||||
import net.sf.briar.api.serial.RawByteArray;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
@@ -212,8 +214,8 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
||||
synchronized(messageStatusLock) {
|
||||
Txn txn = db.startTransaction();
|
||||
try {
|
||||
long capacity = Math.min(b.getRemainingCapacity(),
|
||||
Batch.MAX_SIZE);
|
||||
long capacity =
|
||||
Math.min(b.getRemainingCapacity(), Batch.MAX_SIZE);
|
||||
Iterator<MessageId> it =
|
||||
db.getSendableMessages(txn, c, capacity).iterator();
|
||||
if(!it.hasNext()) {
|
||||
@@ -221,13 +223,13 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
||||
return false; // No more messages to send
|
||||
}
|
||||
Set<MessageId> sent = new HashSet<MessageId>();
|
||||
List<Message> messages = new ArrayList<Message>();
|
||||
List<Raw> messages = new ArrayList<Raw>();
|
||||
int bytesSent = 0;
|
||||
while(it.hasNext()) {
|
||||
MessageId m = it.next();
|
||||
Message message = db.getMessage(txn, m);
|
||||
bytesSent += message.getSize();
|
||||
messages.add(message);
|
||||
byte[] message = db.getMessage(txn, m);
|
||||
bytesSent += message.length;
|
||||
messages.add(new RawByteArray(message));
|
||||
sent.add(m);
|
||||
}
|
||||
BatchId batchId = b.addBatch(messages);
|
||||
|
||||
@@ -20,6 +20,7 @@ import javax.swing.UIManager;
|
||||
import net.sf.briar.api.i18n.FontManager;
|
||||
import net.sf.briar.util.FileUtils;
|
||||
|
||||
// Needs to be public for installer
|
||||
public class FontManagerImpl implements FontManager {
|
||||
|
||||
private static final Logger LOG =
|
||||
|
||||
@@ -21,6 +21,7 @@ import net.sf.briar.api.i18n.FontManager;
|
||||
import net.sf.briar.api.i18n.I18n;
|
||||
import net.sf.briar.util.FileUtils;
|
||||
|
||||
// Needs to be public for installer
|
||||
public class I18nImpl implements I18n {
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,7 +6,7 @@ import net.sf.briar.api.protocol.Batch;
|
||||
import net.sf.briar.api.protocol.BatchId;
|
||||
import net.sf.briar.api.protocol.Message;
|
||||
|
||||
public class BatchFactoryImpl implements BatchFactory {
|
||||
class BatchFactoryImpl implements BatchFactory {
|
||||
|
||||
public Batch createBatch(BatchId id, List<Message> messages) {
|
||||
return new BatchImpl(id, messages);
|
||||
|
||||
@@ -81,12 +81,13 @@ class BundleReaderImpl implements BundleReader {
|
||||
}
|
||||
Map<String, String> transports =
|
||||
r.readMap(String.class, String.class);
|
||||
long timestamp = r.readInt64();
|
||||
in.setSigning(false);
|
||||
// Read and verify the signature
|
||||
byte[] sig = r.readRaw();
|
||||
if(!signature.verify(sig)) throw new SignatureException();
|
||||
// Build and return the header
|
||||
return headerFactory.createHeader(acks, subs, transports);
|
||||
return headerFactory.createHeader(acks, subs, transports, timestamp);
|
||||
}
|
||||
|
||||
public Batch getNextBatch() throws IOException, GeneralSecurityException {
|
||||
|
||||
@@ -11,7 +11,7 @@ import java.util.Map;
|
||||
import net.sf.briar.api.protocol.BatchId;
|
||||
import net.sf.briar.api.protocol.BundleWriter;
|
||||
import net.sf.briar.api.protocol.GroupId;
|
||||
import net.sf.briar.api.protocol.Message;
|
||||
import net.sf.briar.api.serial.Raw;
|
||||
import net.sf.briar.api.serial.Writer;
|
||||
import net.sf.briar.api.serial.WriterFactory;
|
||||
|
||||
@@ -59,6 +59,7 @@ class BundleWriterImpl implements BundleWriter {
|
||||
for(GroupId sub : subs) w.writeRaw(sub);
|
||||
w.writeListEnd();
|
||||
w.writeMap(transports);
|
||||
w.writeInt64(System.currentTimeMillis());
|
||||
out.setSigning(false);
|
||||
// Create and write the signature
|
||||
byte[] sig = signature.sign();
|
||||
@@ -67,7 +68,7 @@ class BundleWriterImpl implements BundleWriter {
|
||||
state = State.FIRST_BATCH;
|
||||
}
|
||||
|
||||
public BatchId addBatch(Iterable<Message> messages) throws IOException,
|
||||
public BatchId addBatch(Iterable<Raw> messages) throws IOException,
|
||||
GeneralSecurityException {
|
||||
if(state == State.FIRST_BATCH) {
|
||||
w.writeListStart();
|
||||
@@ -81,7 +82,7 @@ class BundleWriterImpl implements BundleWriter {
|
||||
out.setDigesting(true);
|
||||
out.setSigning(true);
|
||||
w.writeListStart();
|
||||
for(Message m : messages) w.writeRaw(m);
|
||||
for(Raw message : messages) w.writeRaw(message);
|
||||
w.writeListEnd();
|
||||
out.setSigning(false);
|
||||
// Create and write the signature
|
||||
|
||||
@@ -10,5 +10,5 @@ import net.sf.briar.api.protocol.Header;
|
||||
interface HeaderFactory {
|
||||
|
||||
Header createHeader(Set<BatchId> acks, Set<GroupId> subs,
|
||||
Map<String, String> transports);
|
||||
Map<String, String> transports, long timestamp);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import net.sf.briar.api.protocol.Header;
|
||||
class HeaderFactoryImpl implements HeaderFactory {
|
||||
|
||||
public Header createHeader(Set<BatchId> acks, Set<GroupId> subs,
|
||||
Map<String, String> transports) {
|
||||
return new HeaderImpl(acks, subs, transports);
|
||||
Map<String, String> transports, long timestamp) {
|
||||
return new HeaderImpl(acks, subs, transports, timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,12 +13,14 @@ class HeaderImpl implements Header {
|
||||
private final Set<BatchId> acks;
|
||||
private final Set<GroupId> subs;
|
||||
private final Map<String, String> transports;
|
||||
private final long timestamp;
|
||||
|
||||
HeaderImpl(Set<BatchId> acks, Set<GroupId> subs,
|
||||
Map<String, String> transports) {
|
||||
Map<String, String> transports, long timestamp) {
|
||||
this.acks = acks;
|
||||
this.subs = subs;
|
||||
this.transports = transports;
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public Set<BatchId> getAcks() {
|
||||
@@ -32,4 +34,8 @@ class HeaderImpl implements Header {
|
||||
public Map<String, String> getTransports() {
|
||||
return transports;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import net.sf.briar.api.protocol.Message;
|
||||
import net.sf.briar.api.protocol.MessageId;
|
||||
|
||||
/** A simple in-memory implementation of a message. */
|
||||
public class MessageImpl implements Message {
|
||||
class MessageImpl implements Message {
|
||||
|
||||
private final MessageId id, parent;
|
||||
private final GroupId group;
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
package net.sf.briar.serial;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import net.sf.briar.api.serial.Raw;
|
||||
|
||||
class RawImpl implements Raw {
|
||||
|
||||
private final byte[] bytes;
|
||||
|
||||
RawImpl(byte[] bytes) {
|
||||
this.bytes = bytes;
|
||||
}
|
||||
|
||||
public byte[] getBytes() {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if(o instanceof Raw) return Arrays.equals(bytes, ((Raw) o).getBytes());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import java.io.InputStream;
|
||||
import net.sf.briar.api.serial.Reader;
|
||||
import net.sf.briar.api.serial.ReaderFactory;
|
||||
|
||||
public class ReaderFactoryImpl implements ReaderFactory {
|
||||
class ReaderFactoryImpl implements ReaderFactory {
|
||||
|
||||
public Reader createReader(InputStream in) {
|
||||
return new ReaderImpl(in);
|
||||
|
||||
@@ -8,6 +8,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.sf.briar.api.serial.FormatException;
|
||||
import net.sf.briar.api.serial.RawByteArray;
|
||||
import net.sf.briar.api.serial.Reader;
|
||||
import net.sf.briar.api.serial.Tag;
|
||||
|
||||
@@ -308,7 +309,7 @@ class ReaderImpl implements Reader {
|
||||
if(hasFloat32()) return Float.valueOf(readFloat32());
|
||||
if(hasFloat64()) return Double.valueOf(readFloat64());
|
||||
if(hasUtf8()) return readUtf8();
|
||||
if(hasRaw()) return new RawImpl(readRaw());
|
||||
if(hasRaw()) return new RawByteArray(readRaw());
|
||||
if(hasList()) return readList();
|
||||
if(hasMap()) return readMap();
|
||||
if(hasNull()) {
|
||||
|
||||
@@ -5,7 +5,7 @@ import java.io.OutputStream;
|
||||
import net.sf.briar.api.serial.Writer;
|
||||
import net.sf.briar.api.serial.WriterFactory;
|
||||
|
||||
public class WriterFactoryImpl implements WriterFactory {
|
||||
class WriterFactoryImpl implements WriterFactory {
|
||||
|
||||
public Writer createWriter(OutputStream out) {
|
||||
return new WriterImpl(out);
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.sf.briar.api.setup.SetupParameters;
|
||||
import net.sf.briar.api.setup.SetupWorkerFactory;
|
||||
import net.sf.briar.util.FileUtils;
|
||||
|
||||
// Needs to be public for installer
|
||||
public class SetupWorkerFactoryImpl implements SetupWorkerFactory {
|
||||
|
||||
private final I18n i18n;
|
||||
|
||||
Reference in New Issue
Block a user