preview: add cache for mathjax in-place preview

This commit is contained in:
Le Tan 2018-05-15 20:12:12 +08:00
parent d0c38add94
commit f2afe4b4e2
2 changed files with 74 additions and 19 deletions

View File

@ -72,6 +72,9 @@ void MathjaxBlockPreviewInfo::updateInplacePreview(const VEditor *p_editor,
}
}
#define MATHJAX_IMAGE_CACHE_SIZE_DIFF 20
#define MATHJAX_IMAGE_CACHE_TIME_DIFF 5
VMathJaxInplacePreviewHelper::VMathJaxInplacePreviewHelper(VEditor *p_editor,
VDocument *p_document,
QObject *p_parent)
@ -100,6 +103,7 @@ void VMathJaxInplacePreviewHelper::setEnabled(bool p_enabled)
if (!m_enabled) {
m_mathjaxBlocks.clear();
m_cache.clear();
}
updateInplacePreview();
@ -114,36 +118,36 @@ void VMathJaxInplacePreviewHelper::updateMathjaxBlocks(const QVector<VMathjaxBlo
++m_timeStamp;
int idx = 0;
m_mathjaxBlocks.clear();
m_mathjaxBlocks.reserve(p_blocks.size());
bool manualUpdate = true;
for (auto const & vmb : p_blocks) {
for (int i = 0; i < p_blocks.size(); ++i) {
const VMathjaxBlock &vmb = p_blocks[i];
const QString &text = vmb.m_text;
bool cached = false;
if (idx < m_mathjaxBlocks.size()) {
MathjaxBlockPreviewInfo &mb = m_mathjaxBlocks[idx];
if (mb.mathjaxBlock().equalContent(vmb)) {
cached = true;
mb.updateNonContent(m_doc, m_editor, vmb);
} else {
mb.setMathjaxBlock(vmb);
}
} else {
m_mathjaxBlocks.append(MathjaxBlockPreviewInfo(vmb));
auto it = m_cache.find(text);
if (it != m_cache.end()) {
QSharedPointer<MathjaxImageCacheEntry> &entry = it.value();
entry->m_ts = m_timeStamp;
cached = true;
m_mathjaxBlocks[i].setImageDataBa(entry->m_imgFormat, entry->m_imgDataBa);
m_mathjaxBlocks[i].updateInplacePreview(m_editor, m_doc);
}
if (m_enabled
&& (!cached || !m_mathjaxBlocks[idx].inplacePreviewReady())) {
if (!cached || !m_mathjaxBlocks[i].inplacePreviewReady()) {
manualUpdate = false;
processForInplacePreview(idx);
processForInplacePreview(i);
}
++idx;
}
m_mathjaxBlocks.resize(idx);
if (manualUpdate) {
updateInplacePreview();
}
clearObsoleteCache();
}
void VMathJaxInplacePreviewHelper::processForInplacePreview(int p_idx)
@ -220,6 +224,13 @@ void VMathJaxInplacePreviewHelper::mathjaxPreviewResultReady(int p_identitifer,
MathjaxBlockPreviewInfo &mb = m_mathjaxBlocks[p_id];
mb.setImageDataBa(p_format, p_data);
mb.updateInplacePreview(m_editor, m_doc);
// Update the cache.
QSharedPointer<MathjaxImageCacheEntry> entry(new MathjaxImageCacheEntry(p_timeStamp,
p_data,
p_format));
m_cache.insert(mb.mathjaxBlock().m_text, entry);
updateInplacePreview();
}
@ -238,3 +249,19 @@ void VMathJaxInplacePreviewHelper::textToHtmlFinished(int p_identitifer,
p_timeStamp,
p_html);
}
void VMathJaxInplacePreviewHelper::clearObsoleteCache()
{
if (m_cache.size() - m_mathjaxBlocks.size() <= MATHJAX_IMAGE_CACHE_SIZE_DIFF) {
return;
}
for (auto it = m_cache.begin(); it != m_cache.end();) {
if (m_timeStamp - it.value()->m_ts > MATHJAX_IMAGE_CACHE_TIME_DIFF) {
it.value().clear();
it = m_cache.erase(it);
} else {
++it;
}
}
}

View File

@ -85,6 +85,7 @@ private:
QSharedPointer<VImageToPreview> m_inplacePreview;
};
class VMathJaxInplacePreviewHelper : public QObject
{
Q_OBJECT
@ -113,6 +114,28 @@ private slots:
void textToHtmlFinished(int p_identitifer, int p_id, int p_timeStamp, const QString &p_html);
private:
struct MathjaxImageCacheEntry
{
MathjaxImageCacheEntry()
: m_ts(0)
{
}
MathjaxImageCacheEntry(TimeStamp p_ts,
const QByteArray &p_dataBa,
const QString &p_format)
: m_ts(p_ts),
m_imgDataBa(p_dataBa),
m_imgFormat(p_format)
{
}
TimeStamp m_ts;
QByteArray m_imgDataBa;
QString m_imgFormat;
};
void processForInplacePreview(int p_idx);
// Emit signal to update inplace preview.
@ -122,6 +145,8 @@ private:
int p_id,
int p_timeStamp);
void clearObsoleteCache();
VEditor *m_editor;
VDocument *m_document;
@ -143,6 +168,9 @@ private:
QVector<MathjaxBlockPreviewInfo> m_mathjaxBlocks;
int m_documentID;
// Indexed by content.
QHash<QString, QSharedPointer<MathjaxImageCacheEntry>> m_cache;
};
#endif // VMATHJAXINPLACEPREVIEWHELPER_H