Group messages by group ID when fetching them from database.

This commit is contained in:
akwizgran
2021-02-26 12:45:26 +00:00
committed by Torsten Grote
parent 56e0d62597
commit 43b437af92
6 changed files with 30 additions and 39 deletions

View File

@@ -342,7 +342,7 @@ public interface DatabaseComponent extends TransactionManager {
* <p/>
* Read-only.
*/
Map<MessageId, GroupId> getMessagesToDelete(Transaction txn)
Map<GroupId, Collection<MessageId>> getMessagesToDelete(Transaction txn)
throws DbException;
/**

View File

@@ -20,9 +20,7 @@ import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.api.system.TaskScheduler;
import org.briarproject.bramble.api.versioning.ClientMajorVersion;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
@@ -132,39 +130,25 @@ class CleanupManagerImpl implements CleanupManager, Service, EventListener {
}
private void deleteMessages(Transaction txn) throws DbException {
Map<GroupId, ClientMajorVersion> clientCache = new HashMap<>();
Map<GroupId, Collection<MessageId>> deleted = new HashMap<>();
Map<MessageId, GroupId> ids = db.getMessagesToDelete(txn);
if (LOG.isLoggable(INFO)) LOG.info(ids.size() + " messages to delete");
for (Entry<MessageId, GroupId> e : ids.entrySet()) {
MessageId m = e.getKey();
GroupId g = e.getValue();
ClientMajorVersion cv = clientCache.get(g);
if (cv == null) {
Group group = db.getGroup(txn, g);
cv = new ClientMajorVersion(group.getClientId(),
group.getMajorVersion());
clientCache.put(g, cv);
Map<GroupId, Collection<MessageId>> ids = db.getMessagesToDelete(txn);
for (Entry<GroupId, Collection<MessageId>> e : ids.entrySet()) {
GroupId groupId = e.getKey();
Collection<MessageId> messageIds = e.getValue();
if (LOG.isLoggable(INFO)) {
LOG.info(messageIds.size() + " messages to delete");
}
Group group = db.getGroup(txn, groupId);
ClientMajorVersion cv = new ClientMajorVersion(group.getClientId(),
group.getMajorVersion());
CleanupHook hook = hooks.get(cv);
if (hook == null) {
throw new IllegalStateException("No cleanup hook for " + cv);
}
if (hook.deleteMessage(txn, g, m)) {
Collection<MessageId> messageIds = deleted.get(g);
if (messageIds == null) {
messageIds = new ArrayList<>();
deleted.put(g, messageIds);
}
messageIds.add(m);
} else {
LOG.info("Message was not deleted");
// Stop the timer so we don't keep trying to delete this message
for (MessageId m : messageIds) {
hook.deleteMessage(txn, groupId, m);
db.stopCleanupTimer(txn, m);
}
}
for (Entry<GroupId, Collection<MessageId>> e : deleted.entrySet()) {
txn.attach(new MessagesCleanedUpEvent(e.getKey(), e.getValue()));
txn.attach(new MessagesCleanedUpEvent(groupId, messageIds));
}
}

View File

@@ -510,7 +510,8 @@ interface Database<T> {
* <p/>
* Read-only.
*/
Map<MessageId, GroupId> getMessagesToDelete(T txn) throws DbException;
Map<GroupId, Collection<MessageId>> getMessagesToDelete(T txn)
throws DbException;
/**
* Returns the next time (in milliseconds since the Unix epoch) when a

View File

@@ -608,8 +608,8 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
}
@Override
public Map<MessageId, GroupId> getMessagesToDelete(Transaction transaction)
throws DbException {
public Map<GroupId, Collection<MessageId>> getMessagesToDelete(
Transaction transaction) throws DbException {
T txn = unbox(transaction);
return db.getMessagesToDelete(txn);
}

View File

@@ -2268,8 +2268,8 @@ abstract class JdbcDatabase implements Database<Connection> {
}
@Override
public Map<MessageId, GroupId> getMessagesToDelete(Connection txn)
throws DbException {
public Map<GroupId, Collection<MessageId>> getMessagesToDelete(
Connection txn) throws DbException {
long now = clock.currentTimeMillis();
PreparedStatement ps = null;
ResultSet rs = null;
@@ -2279,10 +2279,16 @@ abstract class JdbcDatabase implements Database<Connection> {
ps = txn.prepareStatement(sql);
ps.setLong(1, now);
rs = ps.executeQuery();
Map<MessageId, GroupId> ids = new HashMap<>();
Map<GroupId, Collection<MessageId>> ids = new HashMap<>();
while (rs.next()) {
ids.put(new MessageId(rs.getBytes(1)),
new GroupId(rs.getBytes(2)));
MessageId m = new MessageId(rs.getBytes(1));
GroupId g = new GroupId(rs.getBytes(2));
Collection<MessageId> messageIds = ids.get(g);
if (messageIds == null) {
messageIds = new ArrayList<>();
ids.put(g, messageIds);
}
messageIds.add(m);
}
rs.close();
ps.close();

View File

@@ -2474,14 +2474,14 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// When the timer expires, the message should be due and scheduled for
// deletion
time.set(now + duration);
assertEquals(singletonMap(messageId, groupId),
assertEquals(singletonMap(groupId, singletonList(messageId)),
db.getMessagesToDelete(txn));
assertEquals(now + duration, db.getNextCleanupDeadline(txn));
// 1 ms after the timer expires, the message should be due and
// scheduled for deletion
time.set(now + duration + 1);
assertEquals(singletonMap(messageId, groupId),
assertEquals(singletonMap(groupId, singletonList(messageId)),
db.getMessagesToDelete(txn));
assertEquals(now + duration, db.getNextCleanupDeadline(txn));