Query message IDs rather than metadata when only IDs are needed.

This commit is contained in:
akwizgran
2021-02-25 11:01:33 +00:00
committed by Torsten Grote
parent 00e3e64495
commit 6113b4ebee
12 changed files with 80 additions and 50 deletions

View File

@@ -17,6 +17,7 @@ import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.bramble.api.sync.MessageId;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.util.Collection;
import java.util.Map; import java.util.Map;
@NotNullByDefault @NotNullByDefault
@@ -51,9 +52,11 @@ public interface ClientHelper {
BdfDictionary getGroupMetadataAsDictionary(Transaction txn, GroupId g) BdfDictionary getGroupMetadataAsDictionary(Transaction txn, GroupId g)
throws DbException, FormatException; throws DbException, FormatException;
Collection<MessageId> getMessageIds(Transaction txn, GroupId g,
BdfDictionary query) throws DbException, FormatException;
BdfDictionary getMessageMetadataAsDictionary(MessageId m) BdfDictionary getMessageMetadataAsDictionary(MessageId m)
throws DbException, throws DbException, FormatException;
FormatException;
BdfDictionary getMessageMetadataAsDictionary(Transaction txn, MessageId m) BdfDictionary getMessageMetadataAsDictionary(Transaction txn, MessageId m)
throws DbException, FormatException; throws DbException, FormatException;

View File

@@ -288,6 +288,16 @@ public interface DatabaseComponent extends TransactionManager {
Collection<MessageId> getMessageIds(Transaction txn, GroupId g) Collection<MessageId> getMessageIds(Transaction txn, GroupId g)
throws DbException; throws DbException;
/**
* Returns the IDs of any delivered messages in the given group with
* metadata that matches all entries in the given query. If the query is
* empty, the IDs of all delivered messages are returned.
* <p/>
* Read-only.
*/
Collection<MessageId> getMessageIds(Transaction txn, GroupId g,
Metadata query) throws DbException;
/** /**
* Returns the IDs of any messages that need to be validated. * Returns the IDs of any messages that need to be validated.
* <p/> * <p/>

View File

@@ -34,6 +34,7 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
@@ -154,6 +155,12 @@ class ClientHelperImpl implements ClientHelper {
return metadataParser.parse(metadata); return metadataParser.parse(metadata);
} }
@Override
public Collection<MessageId> getMessageIds(Transaction txn, GroupId g,
BdfDictionary query) throws DbException, FormatException {
return db.getMessageIds(txn, g, metadataEncoder.encode(query));
}
@Override @Override
public BdfDictionary getMessageMetadataAsDictionary(MessageId m) public BdfDictionary getMessageMetadataAsDictionary(MessageId m)
throws DbException, FormatException { throws DbException, FormatException {

View File

@@ -576,6 +576,15 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
return db.getMessageIds(txn, g); return db.getMessageIds(txn, g);
} }
@Override
public Collection<MessageId> getMessageIds(Transaction transaction,
GroupId g, Metadata query) throws DbException {
T txn = unbox(transaction);
if (!db.containsGroup(txn, g))
throw new NoSuchGroupException();
return db.getMessageIds(txn, g, query);
}
@Override @Override
public Collection<MessageId> getMessagesToValidate(Transaction transaction) public Collection<MessageId> getMessagesToValidate(Transaction transaction)
throws DbException { throws DbException {

View File

@@ -510,11 +510,11 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
throws Exception { throws Exception {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
// Check whether the group is in the DB (which it's not) // Check whether the group is in the DB (which it's not)
exactly(8).of(database).startTransaction(); exactly(10).of(database).startTransaction();
will(returnValue(txn)); will(returnValue(txn));
exactly(8).of(database).containsGroup(txn, groupId); exactly(10).of(database).containsGroup(txn, groupId);
will(returnValue(false)); will(returnValue(false));
exactly(8).of(database).abortTransaction(txn); exactly(10).of(database).abortTransaction(txn);
// Allow other checks to pass // Allow other checks to pass
allowing(database).containsContact(txn, contactId); allowing(database).containsContact(txn, contactId);
will(returnValue(true)); will(returnValue(true));
@@ -523,7 +523,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
eventExecutor, shutdownManager); eventExecutor, shutdownManager);
try { try {
db.transaction(false, transaction -> db.transaction(true, transaction ->
db.getGroup(transaction, groupId)); db.getGroup(transaction, groupId));
fail(); fail();
} catch (NoSuchGroupException expected) { } catch (NoSuchGroupException expected) {
@@ -531,7 +531,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
} }
try { try {
db.transaction(false, transaction -> db.transaction(true, transaction ->
db.getGroupMetadata(transaction, groupId)); db.getGroupMetadata(transaction, groupId));
fail(); fail();
} catch (NoSuchGroupException expected) { } catch (NoSuchGroupException expected) {
@@ -539,7 +539,23 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
} }
try { try {
db.transaction(false, transaction -> db.transaction(true, transaction ->
db.getMessageIds(transaction, groupId));
fail();
} catch (NoSuchGroupException expected) {
// Expected
}
try {
db.transaction(true, transaction ->
db.getMessageIds(transaction, groupId, new Metadata()));
fail();
} catch (NoSuchGroupException expected) {
// Expected
}
try {
db.transaction(true, transaction ->
db.getMessageMetadata(transaction, groupId)); db.getMessageMetadata(transaction, groupId));
fail(); fail();
} catch (NoSuchGroupException expected) { } catch (NoSuchGroupException expected) {
@@ -547,7 +563,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
} }
try { try {
db.transaction(false, transaction -> db.transaction(true, transaction ->
db.getMessageMetadata(transaction, groupId, db.getMessageMetadata(transaction, groupId,
new Metadata())); new Metadata()));
fail(); fail();
@@ -556,7 +572,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
} }
try { try {
db.transaction(false, transaction -> db.transaction(true, transaction ->
db.getMessageStatus(transaction, contactId, groupId)); db.getMessageStatus(transaction, contactId, groupId));
fail(); fail();
} catch (NoSuchGroupException expected) { } catch (NoSuchGroupException expected) {

View File

@@ -38,6 +38,7 @@ import org.briarproject.briar.api.introduction.event.IntroductionAbortedEvent;
import org.briarproject.briar.api.introduction.event.IntroductionRequestReceivedEvent; import org.briarproject.briar.api.introduction.event.IntroductionRequestReceivedEvent;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.logging.Logger; import java.util.logging.Logger;
@@ -587,10 +588,9 @@ class IntroduceeProtocolEngine
BdfDictionary query = messageParser BdfDictionary query = messageParser
.getRequestsAvailableToAnswerQuery(s.getSessionId()); .getRequestsAvailableToAnswerQuery(s.getSessionId());
try { try {
Map<MessageId, BdfDictionary> results = Collection<MessageId> results = clientHelper.getMessageIds(txn,
clientHelper.getMessageMetadataAsDictionary(txn, s.getContactGroupId(), query);
s.getContactGroupId(), query); for (MessageId m : results)
for (MessageId m : results.keySet())
markRequestAvailableToAnswer(txn, m, false); markRequestAvailableToAnswer(txn, m, false);
} catch (FormatException e) { } catch (FormatException e) {
throw new AssertionError(e); throw new AssertionError(e);

View File

@@ -494,15 +494,14 @@ class IntroductionManagerImpl extends ConversationClientImpl
Contact introducer) throws DbException { Contact introducer) throws DbException {
BdfDictionary query = sessionEncoder BdfDictionary query = sessionEncoder
.getIntroduceeSessionsByIntroducerQuery(introducer.getAuthor()); .getIntroduceeSessionsByIntroducerQuery(introducer.getAuthor());
Map<MessageId, BdfDictionary> sessions; Collection<MessageId> sessionIds;
try { try {
sessions = clientHelper sessionIds = clientHelper.getMessageIds(txn, localGroup.getId(),
.getMessageMetadataAsDictionary(txn, localGroup.getId(), query);
query);
} catch (FormatException e) { } catch (FormatException e) {
throw new DbException(e); throw new DbException(e);
} }
for (MessageId id : sessions.keySet()) { for (MessageId id : sessionIds) {
db.removeMessage(txn, id); db.removeMessage(txn, id);
} }
} }
@@ -708,9 +707,7 @@ class IntroductionManagerImpl extends ConversationClientImpl
GroupId g = getContactGroup(db.getContact(txn, c)).getId(); GroupId g = getContactGroup(db.getContact(txn, c)).getId();
BdfDictionary query = messageParser.getMessagesVisibleInUiQuery(); BdfDictionary query = messageParser.getMessagesVisibleInUiQuery();
try { try {
Map<MessageId, BdfDictionary> results = return new HashSet<>(clientHelper.getMessageIds(txn, g, query));
clientHelper.getMessageMetadataAsDictionary(txn, g, query);
return results.keySet();
} catch (FormatException e) { } catch (FormatException e) {
throw new DbException(e); throw new DbException(e);
} }

View File

@@ -27,7 +27,7 @@ import org.briarproject.briar.api.privategroup.PrivateGroupFactory;
import org.briarproject.briar.api.privategroup.PrivateGroupManager; import org.briarproject.briar.api.privategroup.PrivateGroupManager;
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationManager; import org.briarproject.briar.api.privategroup.invitation.GroupInvitationManager;
import java.util.Map; import java.util.Collection;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
@@ -237,10 +237,9 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
GroupId privateGroupId = session.getPrivateGroupId(); GroupId privateGroupId = session.getPrivateGroupId();
BdfDictionary query = BdfDictionary query =
messageParser.getInvitesAvailableToAnswerQuery(privateGroupId); messageParser.getInvitesAvailableToAnswerQuery(privateGroupId);
Map<MessageId, BdfDictionary> results = Collection<MessageId> results = clientHelper.getMessageIds(txn,
clientHelper.getMessageMetadataAsDictionary(txn, session.getContactGroupId(), query);
session.getContactGroupId(), query); for (MessageId m : results)
for (MessageId m : results.keySet())
markMessageAvailableToAnswer(txn, m, false); markMessageAvailableToAnswer(txn, m, false);
} }

View File

@@ -437,10 +437,9 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
// Look up the available invite messages for each contact // Look up the available invite messages for each contact
for (Contact c : db.getContacts(txn)) { for (Contact c : db.getContacts(txn)) {
GroupId contactGroupId = getContactGroup(c).getId(); GroupId contactGroupId = getContactGroup(c).getId();
Map<MessageId, BdfDictionary> results = Collection<MessageId> results = clientHelper.getMessageIds(txn,
clientHelper.getMessageMetadataAsDictionary(txn, contactGroupId, query);
contactGroupId, query); for (MessageId m : results)
for (MessageId m : results.keySet())
items.add(parseGroupInvitationItem(txn, c, m)); items.add(parseGroupInvitationItem(txn, c, m));
} }
db.commitTransaction(txn); db.commitTransaction(txn);
@@ -769,9 +768,7 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
GroupId g = getContactGroup(db.getContact(txn, c)).getId(); GroupId g = getContactGroup(db.getContact(txn, c)).getId();
BdfDictionary query = messageParser.getMessagesVisibleInUiQuery(); BdfDictionary query = messageParser.getMessagesVisibleInUiQuery();
try { try {
Map<MessageId, BdfDictionary> results = return new HashSet<>(clientHelper.getMessageIds(txn, g, query));
clientHelper.getMessageMetadataAsDictionary(txn, g, query);
return results.keySet();
} catch (FormatException e) { } catch (FormatException e) {
throw new DbException(e); throw new DbException(e);
} }

View File

@@ -690,9 +690,7 @@ abstract class SharingManagerImpl<S extends Shareable>
GroupId g = getContactGroup(db.getContact(txn, c)).getId(); GroupId g = getContactGroup(db.getContact(txn, c)).getId();
BdfDictionary query = messageParser.getMessagesVisibleInUiQuery(); BdfDictionary query = messageParser.getMessagesVisibleInUiQuery();
try { try {
Map<MessageId, BdfDictionary> results = return new HashSet<>(clientHelper.getMessageIds(txn, g, query));
clientHelper.getMessageMetadataAsDictionary(txn, g, query);
return results.keySet();
} catch (FormatException e) { } catch (FormatException e) {
throw new DbException(e); throw new DbException(e);
} }

View File

@@ -720,10 +720,8 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
public void testGetInvitations() throws Exception { public void testGetInvitations() throws Exception {
BdfDictionary query = BdfDictionary.of(new BdfEntry("q", "u")); BdfDictionary query = BdfDictionary.of(new BdfEntry("q", "u"));
Message message2 = getMessage(contactGroup.getId()); Message message2 = getMessage(contactGroup.getId());
BdfDictionary meta2 = BdfDictionary.of(new BdfEntry("m2", "e")); Collection<MessageId> results =
Map<MessageId, BdfDictionary> results = new HashMap<>(); asList(message.getId(), message2.getId());
results.put(message.getId(), meta);
results.put(message2.getId(), meta2);
long time1 = 1L, time2 = 2L; long time1 = 1L, time2 = 2L;
String groupName = getRandomString(MAX_GROUP_NAME_LENGTH); String groupName = getRandomString(MAX_GROUP_NAME_LENGTH);
byte[] salt = getRandomBytes(GROUP_SALT_LENGTH); byte[] salt = getRandomBytes(GROUP_SALT_LENGTH);
@@ -748,8 +746,7 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact); MAJOR_VERSION, contact);
will(returnValue(contactGroup)); will(returnValue(contactGroup));
oneOf(clientHelper).getMessageMetadataAsDictionary(txn, oneOf(clientHelper).getMessageIds(txn, contactGroup.getId(), query);
contactGroup.getId(), query);
will(returnValue(results)); will(returnValue(results));
// message 1 // message 1
oneOf(messageParser).getInviteMessage(txn, message.getId()); oneOf(messageParser).getInviteMessage(txn, message.getId());

View File

@@ -10,9 +10,9 @@ import org.briarproject.briar.api.privategroup.GroupMessage;
import org.jmock.Expectations; import org.jmock.Expectations;
import org.junit.Test; import org.junit.Test;
import java.util.Collections; import java.util.Collection;
import java.util.Map;
import static java.util.Collections.singletonList;
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE; import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED; import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
import static org.briarproject.bramble.api.sync.Group.Visibility.VISIBLE; import static org.briarproject.bramble.api.sync.Group.Visibility.VISIBLE;
@@ -757,15 +757,12 @@ public class InviteeProtocolEngineTest extends AbstractProtocolEngineTest {
private void expectMarkInvitesUnavailableToAnswer() throws Exception { private void expectMarkInvitesUnavailableToAnswer() throws Exception {
BdfDictionary query = BdfDictionary.of(new BdfEntry("query", "")); BdfDictionary query = BdfDictionary.of(new BdfEntry("query", ""));
BdfDictionary meta = BdfDictionary.of(new BdfEntry("meta", "")); Collection<MessageId> invites = singletonList(lastRemoteMessageId);
Map<MessageId, BdfDictionary> invites =
Collections.singletonMap(lastRemoteMessageId, meta);
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(messageParser) oneOf(messageParser)
.getInvitesAvailableToAnswerQuery(privateGroupId); .getInvitesAvailableToAnswerQuery(privateGroupId);
will(returnValue(query)); will(returnValue(query));
oneOf(clientHelper) oneOf(clientHelper).getMessageIds(txn, contactGroupId, query);
.getMessageMetadataAsDictionary(txn, contactGroupId, query);
will(returnValue(invites)); will(returnValue(invites));
}}); }});
expectMarkMessageAvailableToAnswer(lastRemoteMessageId, false); expectMarkMessageAvailableToAnswer(lastRemoteMessageId, false);