reverse through mam history when loading larger chuncks
This commit is contained in:
parent
02a89f4ce2
commit
899802646c
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in a new issue