Fix OOM when paging lots of group updates.

This commit is contained in:
Cody Henthorne
2021-12-21 16:20:44 -05:00
committed by Alex Hart
parent 3eb8db00aa
commit e41c73f293
4 changed files with 227 additions and 8 deletions

View File

@@ -0,0 +1,52 @@
package org.whispersystems.signalservice.api.groupsv2;
import org.whispersystems.signalservice.internal.push.PushServiceSocket;
import java.util.List;
/**
* Wraps result of group history fetch with it's associated paging data.
*/
public final class GroupHistoryPage {
private final List<DecryptedGroupHistoryEntry> results;
private final PagingData pagingData;
public GroupHistoryPage(List<DecryptedGroupHistoryEntry> results, PagingData pagingData) {
this.results = results;
this.pagingData = pagingData;
}
public List<DecryptedGroupHistoryEntry> getResults() {
return results;
}
public PagingData getPagingData() {
return pagingData;
}
public static final class PagingData {
public static final PagingData NONE = new PagingData(false, -1);
private final boolean hasMorePages;
private final int nextPageRevision;
public static PagingData fromGroup(PushServiceSocket.GroupHistory groupHistory) {
return new PagingData(groupHistory.hasMore(), groupHistory.hasMore() ? groupHistory.getNextPageStartGroupRevision() : -1);
}
private PagingData(boolean hasMorePages, int nextPageRevision) {
this.hasMorePages = hasMorePages;
this.nextPageRevision = nextPageRevision;
}
public boolean hasMorePages() {
return hasMorePages;
}
public int getNextPageRevision() {
return nextPageRevision;
}
}
}

View File

@@ -126,6 +126,31 @@ public final class GroupsV2Api {
return result;
}
public GroupHistoryPage getGroupHistoryPage(GroupSecretParams groupSecretParams,
int fromRevision,
GroupsV2AuthorizationString authorization)
throws IOException, InvalidGroupStateException, VerificationFailedException
{
List<GroupChanges.GroupChangeState> changesList = new LinkedList<>();
PushServiceSocket.GroupHistory group;
group = socket.getGroupsV2GroupHistory(fromRevision, authorization);
changesList.addAll(group.getGroupChanges().getGroupChangesList());
ArrayList<DecryptedGroupHistoryEntry> result = new ArrayList<>(changesList.size());
GroupsV2Operations.GroupOperations groupOperations = groupsOperations.forGroup(groupSecretParams);
for (GroupChanges.GroupChangeState change : changesList) {
Optional<DecryptedGroup> decryptedGroup = change.hasGroupState () ? Optional.of(groupOperations.decryptGroup(change.getGroupState())) : Optional.absent();
Optional<DecryptedGroupChange> decryptedChange = change.hasGroupChange() ? groupOperations.decryptChange(change.getGroupChange(), false) : Optional.absent();
result.add(new DecryptedGroupHistoryEntry(decryptedGroup, decryptedChange));
}
return new GroupHistoryPage(result, GroupHistoryPage.PagingData.fromGroup(group));
}
public DecryptedGroupJoinInfo getGroupJoinInfo(GroupSecretParams groupSecretParams,
Optional<byte[]> password,
GroupsV2AuthorizationString authorization)