From 484d6c34f095557ae88e35336d74e5c6607fa8d8 Mon Sep 17 00:00:00 2001 From: blue Date: Wed, 24 Apr 2019 17:50:54 +0300 Subject: [PATCH] nothing special --- core/archive.cpp | 2 +- core/contact.cpp | 179 ++++++++++++++++++++++++++++++++++++++++------- core/contact.h | 7 +- 3 files changed, 160 insertions(+), 28 deletions(-) diff --git a/core/archive.cpp b/core/archive.cpp index 49df1c0..ac8a852 100644 --- a/core/archive.cpp +++ b/core/archive.cpp @@ -261,7 +261,7 @@ std::list Core::Archive::getBefore(int count, const QString& id rc = mdb_cursor_open(txn, order, &cursor); rc = mdb_cursor_get(cursor, &lmdbKey, &lmdbData, MDB_LAST); if (rc) { - qDebug() << "Error geting before newest newest " << mdb_strerror(rc); + qDebug() << "Error geting before " << mdb_strerror(rc); mdb_cursor_close(cursor); mdb_txn_abort(txn); throw new Empty(jid.toStdString()); diff --git a/core/contact.cpp b/core/contact.cpp index 8525f96..d1a490d 100644 --- a/core/contact.cpp +++ b/core/contact.cpp @@ -31,7 +31,8 @@ Core::Contact::Contact(const QString& pJid, const QString& account, QObject* par receivedCount(0), hisoryCache(), appendCache(), - requestCache() + requestCache(), + responseCache() { archive->open(account); if (archive->isFromTheBeginning()) { @@ -115,31 +116,157 @@ void Core::Contact::requestHistory(int count, const QString& before) if (syncronizing) { requestCache.emplace_back(count, before); } else { - switch (archiveState) { - case empty: - if (appendCache.size() != 0) { - //from last - } else { - //search - } - break; - case beginning: - //from last - break; - case end: - //try - break; - case chunk: - //from last - break; - case complete: - //just give - break; - } - syncronizing = true; - requestedCount = count; - receivedCount = 0; - hisoryCache.clear(); + performRequest(count, before); } } +void Core::Contact::nextRequest() +{ + if (requestCache.size() > 0) { + std::pair request = requestCache.front(); + requestCache.pop_front(); + performRequest(request.first, request.second); + } else { + syncronizing = false; + requestedCount = 0; + receivedCount = 0; + hisoryCache.clear(); + responseCache.clear(); + } +} + +void Core::Contact::performRequest(int count, const QString& before) +{ + syncronizing = true; + requestedCount = count; + receivedCount = 0; + hisoryCache.clear(); + responseCache.clear(); + + switch (archiveState) { + case empty: + emit needEarlierHistory(before, "", QDateTime(), QDateTime()); + break; + case beginning: { + QString lBefore; + bool found = false; + if (appendCache.size() != 0) { + if (before.size() == 0) { + lBefore = appendCache.back().getId(); + } + for (std::list::const_reverse_iterator itr = appendCache.rbegin(), end = appendCache.rend(); itr != end; ++itr) { + const Shared::Message& msg = *itr; + if (found) { + responseCache.emplace_front(msg); + ++receivedCount; + } else { + if (msg.getId() == before) { + found = true; + responseCache.emplace_front(*itr); + ++receivedCount; + } + } + if (responseCache.size() == count) { + break; + } + } + if (responseCache.size() == count) { + emit historyResponse(responseCache); + nextRequest(); + break; + } + } + if (found) { + lBefore = responseCache.front().getId(); + emit needEarlierHistory(lBefore, "", QDateTime(), QDateTime()); + } else { + std::list arc; + if (responseCache.size() > 0) { + lBefore = responseCache.front().getId(); + } else { + lBefore = before; + } + if (count != -1) { + try { + arc = archive->getBefore(requestedCount - receivedCount, lBefore); + responseCache.insert(responseCache.begin(), arc.begin(), arc.end()); + emit historyResponse(responseCache); + nextRequest(); + } catch (Archive::NotFound e) { + requestCache.emplace_back(count, before); + requestedCount = -1; + emit needEarlierHistory("", archive->newestId(), QDateTime(), QDateTime()); + } + } else { + try { + arc = archive->getBefore(1, lBefore); + //just do nothing since response is not required + nextRequest(); //may be even it's a signal that the history is now complete? + } catch (Archive::NotFound e) { + emit needEarlierHistory("", archive->newestId(), QDateTime(), QDateTime()); + } + } + } + } + break; + case end: + std::list arc; + if (count != -1) { + try { + arc = archive->getBefore(requestedCount - receivedCount, before); + responseCache.insert(responseCache.begin(), arc.begin(), arc.end()); + emit historyResponse(responseCache); + nextRequest(); + } catch (Archive::NotFound e) { + requestCache.emplace_back(count, before); + requestedCount = -1; + emit needEarlierHistory("", archive->newestId(), QDateTime(), QDateTime()); + } + } else { + try { + arc = archive->getBefore(1, before); + //just do nothing since response is not required + nextRequest(); //may be even it's a signal that the history is now complete? + } catch (Archive::NotFound e) { + emit needEarlierHistory("", archive->newestId(), QDateTime(), QDateTime()); + } + } + break; + case chunk: + //from last + break; + case complete: + //just give + break; + } +} + + +void Core::Contact::appendMessageToArchive(const Shared::Message& msg) +{ + if (msg.getId().size() > 0 && msg.getBody().size() > 0) { + switch (archiveState) { + case empty: + if (archive->addElement(msg)) { + archiveState = end; + }; + requestHistory(-1, msg.getId()); + break; + case beginning: + appendCache.emplace_back(msg); + requestHistory(-1, msg.getId()); + break; + case end: + archive->addElement(msg); + break; + case chunk: + appendCache.emplace_back(msg); + requestHistory(-1, msg.getId()); + break; + case complete: + archive->addElement(msg); + break; + } + + } +} diff --git a/core/contact.h b/core/contact.h index cc3f413..49346c6 100644 --- a/core/contact.h +++ b/core/contact.h @@ -60,7 +60,7 @@ signals: void nameChanged(const QString& name); void subscriptionStateChanged(Shared::SubscriptionState state); void historyResponse(const std::list& messages); - void needEarlierHistory(const QString& before, const QString& after, int count, const QDateTime& from, const QDateTime& to); + void needEarlierHistory(const QString& before, const QString& after, const QDateTime& from, const QDateTime& to); public: const QString jid; @@ -77,7 +77,12 @@ private: int receivedCount; std::list hisoryCache; std::list appendCache; + std::list responseCache; std::list> requestCache; + +private: + void nextRequest(); + void performRequest(int count, const QString& before); }; }