reverse through mam history when loading larger chuncks

This commit is contained in:
iNPUTmice 2014-12-13 15:32:11 +01:00
parent 02a89f4ce2
commit 899802646c
5 changed files with 79 additions and 22 deletions

View file

@ -567,9 +567,6 @@ public class Conversation extends AbstractEntity {
public void sort() { public void sort() {
synchronized (this.messages) { synchronized (this.messages) {
for(Message message : this.messages) {
message.untie();
}
Collections.sort(this.messages,new Comparator<Message>() { Collections.sort(this.messages,new Comparator<Message>() {
@Override @Override
public int compare(Message left, Message right) { public int compare(Message left, Message right) {
@ -582,6 +579,9 @@ public class Conversation extends AbstractEntity {
} }
} }
}); });
for(Message message : this.messages) {
message.untie();
}
} }
} }

View file

@ -320,8 +320,8 @@ public class Message extends AbstractEntity {
} }
public Message next() { public Message next() {
if (this.mNextMessage == null) { synchronized (this.conversation.messages) {
synchronized (this.conversation.messages) { if (this.mNextMessage == null) {
int index = this.conversation.messages.indexOf(this); int index = this.conversation.messages.indexOf(this);
if (index < 0 if (index < 0
|| index >= this.conversation.getMessages().size() - 1) { || index >= this.conversation.getMessages().size() - 1) {
@ -331,13 +331,14 @@ public class Message extends AbstractEntity {
.get(index + 1); .get(index + 1);
} }
} }
return this.mNextMessage;
} }
return this.mNextMessage;
} }
public Message prev() { public Message prev() {
if (this.mPreviousMessage == null) { synchronized (this.conversation.messages) {
synchronized (this.conversation.messages) { if (this.mPreviousMessage == null) {
int index = this.conversation.messages.indexOf(this); int index = this.conversation.messages.indexOf(this);
if (index <= 0 || index > this.conversation.messages.size()) { if (index <= 0 || index > this.conversation.messages.size()) {
this.mPreviousMessage = null; this.mPreviousMessage = null;
@ -346,8 +347,8 @@ public class Message extends AbstractEntity {
.get(index - 1); .get(index - 1);
} }
} }
return this.mPreviousMessage;
} }
return this.mPreviousMessage;
} }
public boolean mergeable(final Message message) { public boolean mergeable(final Message message) {

View file

@ -112,8 +112,10 @@ public class IqGenerator extends AbstractGenerator {
data.put("start",getTimestamp(mam.getStart())); data.put("start",getTimestamp(mam.getStart()));
data.put("end",getTimestamp(mam.getEnd())); data.put("end",getTimestamp(mam.getEnd()));
query.addChild(data); query.addChild(data);
if (mam.getAfter() != null) { if (mam.getPagingOrder() == MessageArchiveService.PagingOrder.NORMAL) {
query.addChild("set", "http://jabber.org/protocol/rsm").addChild("after").setContent(mam.getAfter()); query.addChild("set", "http://jabber.org/protocol/rsm").addChild("after").setContent(mam.getReference());
} else {
query.addChild("set", "http://jabber.org/protocol/rsm").addChild("before").setContent(mam.getReference());
} }
return packet; return packet;
} }

View file

@ -23,6 +23,11 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
private final HashSet<Query> queries = new HashSet<Query>(); private final HashSet<Query> queries = new HashSet<Query>();
public enum PagingOrder {
NORMAL,
REVERSE
};
public MessageArchiveService(final XmppConnectionService service) { public MessageArchiveService(final XmppConnectionService service) {
this.mXmppConnectionService = service; this.mXmppConnectionService = service;
} }
@ -72,7 +77,7 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
} else if (end - start >= Config.MAX_HISTORY_AGE) { } else if (end - start >= Config.MAX_HISTORY_AGE) {
start = end - Config.MAX_HISTORY_AGE; start = end - Config.MAX_HISTORY_AGE;
} }
final Query query = new Query(conversation, start, end); final Query query = new Query(conversation, start, end,PagingOrder.REVERSE);
this.queries.add(query); this.queries.add(query);
this.execute(query); this.execute(query);
} }
@ -115,6 +120,17 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
} }
} }
public boolean queryInProgress(Conversation conversation) {
synchronized (this.queries) {
for(Query query : queries) {
if (query.conversation == conversation) {
return true;
}
}
return false;
}
}
public void processFin(Element fin) { public void processFin(Element fin) {
if (fin == null) { if (fin == null) {
return; return;
@ -126,11 +142,19 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
boolean complete = fin.getAttributeAsBoolean("complete"); boolean complete = fin.getAttributeAsBoolean("complete");
Element set = fin.findChild("set","http://jabber.org/protocol/rsm"); Element set = fin.findChild("set","http://jabber.org/protocol/rsm");
Element last = set == null ? null : set.findChild("last"); Element last = set == null ? null : set.findChild("last");
if (complete || last == null) { Element first = set == null ? null : set.findChild("first");
Element relevant = query.getPagingOrder() == PagingOrder.NORMAL ? last : first;
if (complete || relevant == null) {
this.finalizeQuery(query); this.finalizeQuery(query);
} else { } else {
final Query nextQuery = query.next(last == null ? null : last.getContent()); final Query nextQuery;
if (query.getPagingOrder() == PagingOrder.NORMAL) {
nextQuery = query.next(last == null ? null : last.getContent());
} else {
nextQuery = query.prev(first == null ? null : first.getContent());
}
this.execute(nextQuery); this.execute(nextQuery);
this.finalizeQuery(query);
synchronized (this.queries) { synchronized (this.queries) {
this.queries.remove(query); this.queries.remove(query);
this.queries.add(nextQuery); this.queries.add(nextQuery);
@ -164,9 +188,11 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
private long end; private long end;
private Jid with = null; private Jid with = null;
private String queryId; private String queryId;
private String after = null; private String reference = null;
private Account account; private Account account;
private Conversation conversation; private Conversation conversation;
private PagingOrder pagingOrder = PagingOrder.NORMAL;
public Query(Conversation conversation, long start, long end) { public Query(Conversation conversation, long start, long end) {
this(conversation.getAccount(), start, end); this(conversation.getAccount(), start, end);
@ -174,6 +200,11 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
this.with = conversation.getContactJid().toBareJid(); this.with = conversation.getContactJid().toBareJid();
} }
public Query(Conversation conversation, long start, long end, PagingOrder order) {
this(conversation,start,end);
this.pagingOrder = order;
}
public Query(Account account, long start, long end) { public Query(Account account, long start, long end) {
this.account = account; this.account = account;
this.start = start; this.start = start;
@ -181,16 +212,32 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
this.queryId = new BigInteger(50, mXmppConnectionService.getRNG()).toString(32); this.queryId = new BigInteger(50, mXmppConnectionService.getRNG()).toString(32);
} }
public Query next(String after) { private Query page(String reference) {
Query query = new Query(this.account,this.start,this.end); Query query = new Query(this.account,this.start,this.end);
query.after = after; query.reference = reference;
query.conversation = conversation; query.conversation = conversation;
query.with = with; query.with = with;
return query; return query;
} }
public String getAfter() { public Query next(String reference) {
return after; Query query = page(reference);
query.pagingOrder = PagingOrder.NORMAL;
return query;
}
public Query prev(String reference) {
Query query = page(reference);
query.pagingOrder = PagingOrder.REVERSE;
return query;
}
public String getReference() {
return reference;
}
public PagingOrder getPagingOrder() {
return this.pagingOrder;
} }
public String getQueryId() { public String getQueryId() {
@ -230,9 +277,13 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
builder.append(AbstractGenerator.getTimestamp(this.start)); builder.append(AbstractGenerator.getTimestamp(this.start));
builder.append(", end="); builder.append(", end=");
builder.append(AbstractGenerator.getTimestamp(this.end)); builder.append(AbstractGenerator.getTimestamp(this.end));
if (this.after!=null) { if (this.reference!=null) {
builder.append(", after="); if (this.pagingOrder == PagingOrder.NORMAL) {
builder.append(this.after); builder.append(", after=");
} else {
builder.append(", before=");
}
builder.append(this.reference);
} }
return builder.toString(); return builder.toString();
} }

View file

@ -956,6 +956,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
} }
public int loadMoreMessages(Conversation conversation, long timestamp) { public int loadMoreMessages(Conversation conversation, long timestamp) {
if (this.getMessageArchiveService().queryInProgress(conversation)) {
return 0;
}
List<Message> messages = databaseBackend.getMessages(conversation, 50, List<Message> messages = databaseBackend.getMessages(conversation, 50,
timestamp); timestamp);
for (Message message : messages) { for (Message message : messages) {