Skip to content
Snippets Groups Projects
Verified Commit d4b87983 authored by akwizgran's avatar akwizgran
Browse files

Avoid an unnecessary copy when parsing messages.

parent eed14397
No related branches found
No related tags found
No related merge requests found
...@@ -7,5 +7,7 @@ public interface MessageFactory { ...@@ -7,5 +7,7 @@ public interface MessageFactory {
Message createMessage(GroupId g, long timestamp, byte[] body); Message createMessage(GroupId g, long timestamp, byte[] body);
Message createMessage(byte[] raw);
Message createMessage(MessageId m, byte[] raw); Message createMessage(MessageId m, byte[] raw);
} }
...@@ -20,6 +20,9 @@ import static org.briarproject.bramble.util.ByteUtils.INT_32_BYTES; ...@@ -20,6 +20,9 @@ import static org.briarproject.bramble.util.ByteUtils.INT_32_BYTES;
@NotNullByDefault @NotNullByDefault
class GroupFactoryImpl implements GroupFactory { class GroupFactoryImpl implements GroupFactory {
private static final byte[] FORMAT_VERSION_BYTES =
new byte[] {FORMAT_VERSION};
private final CryptoComponent crypto; private final CryptoComponent crypto;
@Inject @Inject
...@@ -31,7 +34,7 @@ class GroupFactoryImpl implements GroupFactory { ...@@ -31,7 +34,7 @@ class GroupFactoryImpl implements GroupFactory {
public Group createGroup(ClientId c, int majorVersion, byte[] descriptor) { public Group createGroup(ClientId c, int majorVersion, byte[] descriptor) {
byte[] majorVersionBytes = new byte[INT_32_BYTES]; byte[] majorVersionBytes = new byte[INT_32_BYTES];
ByteUtils.writeUint32(majorVersion, majorVersionBytes, 0); ByteUtils.writeUint32(majorVersion, majorVersionBytes, 0);
byte[] hash = crypto.hash(LABEL, new byte[] {FORMAT_VERSION}, byte[] hash = crypto.hash(LABEL, FORMAT_VERSION_BYTES,
StringUtils.toUtf8(c.getString()), majorVersionBytes, StringUtils.toUtf8(c.getString()), majorVersionBytes,
descriptor); descriptor);
return new Group(new GroupId(hash), c, majorVersion, descriptor); return new Group(new GroupId(hash), c, majorVersion, descriptor);
......
...@@ -24,6 +24,9 @@ import static org.briarproject.bramble.util.ByteUtils.INT_64_BYTES; ...@@ -24,6 +24,9 @@ import static org.briarproject.bramble.util.ByteUtils.INT_64_BYTES;
@NotNullByDefault @NotNullByDefault
class MessageFactoryImpl implements MessageFactory { class MessageFactoryImpl implements MessageFactory {
private static final byte[] FORMAT_VERSION_BYTES =
new byte[] {FORMAT_VERSION};
private final CryptoComponent crypto; private final CryptoComponent crypto;
@Inject @Inject
...@@ -35,14 +38,7 @@ class MessageFactoryImpl implements MessageFactory { ...@@ -35,14 +38,7 @@ class MessageFactoryImpl implements MessageFactory {
public Message createMessage(GroupId g, long timestamp, byte[] body) { public Message createMessage(GroupId g, long timestamp, byte[] body) {
if (body.length > MAX_MESSAGE_BODY_LENGTH) if (body.length > MAX_MESSAGE_BODY_LENGTH)
throw new IllegalArgumentException(); throw new IllegalArgumentException();
byte[] versionBytes = new byte[] {FORMAT_VERSION}; MessageId id = getMessageId(g, timestamp, body);
// There's only one block, so the root hash is the hash of the block
byte[] rootHash = crypto.hash(BLOCK_LABEL, versionBytes, body);
byte[] timeBytes = new byte[INT_64_BYTES];
ByteUtils.writeUint64(timestamp, timeBytes, 0);
byte[] idHash = crypto.hash(ID_LABEL, versionBytes, g.getBytes(),
timeBytes, rootHash);
MessageId id = new MessageId(idHash);
byte[] raw = new byte[MESSAGE_HEADER_LENGTH + body.length]; byte[] raw = new byte[MESSAGE_HEADER_LENGTH + body.length];
System.arraycopy(g.getBytes(), 0, raw, 0, UniqueId.LENGTH); System.arraycopy(g.getBytes(), 0, raw, 0, UniqueId.LENGTH);
ByteUtils.writeUint64(timestamp, raw, UniqueId.LENGTH); ByteUtils.writeUint64(timestamp, raw, UniqueId.LENGTH);
...@@ -50,6 +46,32 @@ class MessageFactoryImpl implements MessageFactory { ...@@ -50,6 +46,32 @@ class MessageFactoryImpl implements MessageFactory {
return new Message(id, g, timestamp, raw); return new Message(id, g, timestamp, raw);
} }
private MessageId getMessageId(GroupId g, long timestamp, byte[] body) {
// There's only one block, so the root hash is the hash of the block
byte[] rootHash = crypto.hash(BLOCK_LABEL, FORMAT_VERSION_BYTES, body);
byte[] timeBytes = new byte[INT_64_BYTES];
ByteUtils.writeUint64(timestamp, timeBytes, 0);
byte[] idHash = crypto.hash(ID_LABEL, FORMAT_VERSION_BYTES,
g.getBytes(), timeBytes, rootHash);
return new MessageId(idHash);
}
@Override
public Message createMessage(byte[] raw) {
if (raw.length < MESSAGE_HEADER_LENGTH)
throw new IllegalArgumentException();
if (raw.length > MAX_MESSAGE_LENGTH)
throw new IllegalArgumentException();
byte[] groupId = new byte[UniqueId.LENGTH];
System.arraycopy(raw, 0, groupId, 0, UniqueId.LENGTH);
GroupId g = new GroupId(groupId);
long timestamp = ByteUtils.readUint64(raw, UniqueId.LENGTH);
byte[] body = new byte[raw.length - MESSAGE_HEADER_LENGTH];
System.arraycopy(raw, MESSAGE_HEADER_LENGTH, body, 0, body.length);
MessageId id = getMessageId(g, timestamp, body);
return new Message(id, g, timestamp, raw);
}
@Override @Override
public Message createMessage(MessageId m, byte[] raw) { public Message createMessage(MessageId m, byte[] raw) {
if (raw.length < MESSAGE_HEADER_LENGTH) if (raw.length < MESSAGE_HEADER_LENGTH)
......
...@@ -6,7 +6,6 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault; ...@@ -6,7 +6,6 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.record.Record; import org.briarproject.bramble.api.record.Record;
import org.briarproject.bramble.api.record.RecordReader; import org.briarproject.bramble.api.record.RecordReader;
import org.briarproject.bramble.api.sync.Ack; import org.briarproject.bramble.api.sync.Ack;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.Message; import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageFactory; import org.briarproject.bramble.api.sync.MessageFactory;
import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.bramble.api.sync.MessageId;
...@@ -126,20 +125,11 @@ class SyncRecordReaderImpl implements SyncRecordReader { ...@@ -126,20 +125,11 @@ class SyncRecordReaderImpl implements SyncRecordReader {
assert nextRecord != null; assert nextRecord != null;
byte[] payload = nextRecord.getPayload(); byte[] payload = nextRecord.getPayload();
if (payload.length < MESSAGE_HEADER_LENGTH) throw new FormatException(); if (payload.length < MESSAGE_HEADER_LENGTH) throw new FormatException();
// Group ID // Validate timestamp
byte[] id = new byte[UniqueId.LENGTH];
System.arraycopy(payload, 0, id, 0, UniqueId.LENGTH);
GroupId groupId = new GroupId(id);
// Timestamp
long timestamp = ByteUtils.readUint64(payload, UniqueId.LENGTH); long timestamp = ByteUtils.readUint64(payload, UniqueId.LENGTH);
if (timestamp < 0) throw new FormatException(); if (timestamp < 0) throw new FormatException();
// Body
byte[] body = new byte[payload.length - MESSAGE_HEADER_LENGTH];
System.arraycopy(payload, MESSAGE_HEADER_LENGTH, body, 0,
payload.length - MESSAGE_HEADER_LENGTH);
nextRecord = null; nextRecord = null;
// TODO: Add a method that reuses the raw message return messageFactory.createMessage(payload);
return messageFactory.createMessage(groupId, timestamp, body);
} }
@Override @Override
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment