Avoid an unnecessary copy when parsing messages.

This commit is contained in:
akwizgran
2018-04-19 16:40:44 +01:00
parent eed1439745
commit d4b87983e8
4 changed files with 38 additions and 21 deletions

View File

@@ -7,5 +7,7 @@ public interface MessageFactory {
Message createMessage(GroupId g, long timestamp, byte[] body);
Message createMessage(byte[] raw);
Message createMessage(MessageId m, byte[] raw);
}

View File

@@ -20,6 +20,9 @@ import static org.briarproject.bramble.util.ByteUtils.INT_32_BYTES;
@NotNullByDefault
class GroupFactoryImpl implements GroupFactory {
private static final byte[] FORMAT_VERSION_BYTES =
new byte[] {FORMAT_VERSION};
private final CryptoComponent crypto;
@Inject
@@ -31,7 +34,7 @@ class GroupFactoryImpl implements GroupFactory {
public Group createGroup(ClientId c, int majorVersion, byte[] descriptor) {
byte[] majorVersionBytes = new byte[INT_32_BYTES];
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,
descriptor);
return new Group(new GroupId(hash), c, majorVersion, descriptor);

View File

@@ -24,6 +24,9 @@ import static org.briarproject.bramble.util.ByteUtils.INT_64_BYTES;
@NotNullByDefault
class MessageFactoryImpl implements MessageFactory {
private static final byte[] FORMAT_VERSION_BYTES =
new byte[] {FORMAT_VERSION};
private final CryptoComponent crypto;
@Inject
@@ -35,14 +38,7 @@ class MessageFactoryImpl implements MessageFactory {
public Message createMessage(GroupId g, long timestamp, byte[] body) {
if (body.length > MAX_MESSAGE_BODY_LENGTH)
throw new IllegalArgumentException();
byte[] versionBytes = new byte[] {FORMAT_VERSION};
// 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);
MessageId id = getMessageId(g, timestamp, body);
byte[] raw = new byte[MESSAGE_HEADER_LENGTH + body.length];
System.arraycopy(g.getBytes(), 0, raw, 0, UniqueId.LENGTH);
ByteUtils.writeUint64(timestamp, raw, UniqueId.LENGTH);
@@ -50,6 +46,32 @@ class MessageFactoryImpl implements MessageFactory {
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
public Message createMessage(MessageId m, byte[] raw) {
if (raw.length < MESSAGE_HEADER_LENGTH)

View File

@@ -6,7 +6,6 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.record.Record;
import org.briarproject.bramble.api.record.RecordReader;
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.MessageFactory;
import org.briarproject.bramble.api.sync.MessageId;
@@ -126,20 +125,11 @@ class SyncRecordReaderImpl implements SyncRecordReader {
assert nextRecord != null;
byte[] payload = nextRecord.getPayload();
if (payload.length < MESSAGE_HEADER_LENGTH) throw new FormatException();
// Group ID
byte[] id = new byte[UniqueId.LENGTH];
System.arraycopy(payload, 0, id, 0, UniqueId.LENGTH);
GroupId groupId = new GroupId(id);
// Timestamp
// Validate timestamp
long timestamp = ByteUtils.readUint64(payload, UniqueId.LENGTH);
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;
// TODO: Add a method that reuses the raw message
return messageFactory.createMessage(groupId, timestamp, body);
return messageFactory.createMessage(payload);
}
@Override