Browse Source

preview: add cache for mathjax in-place preview

Le Tan 7 years ago
parent
commit
f2afe4b4e2
2 changed files with 74 additions and 19 deletions
  1. 46 19
      src/vmathjaxinplacepreviewhelper.cpp
  2. 28 0
      src/vmathjaxinplacepreviewhelper.h

+ 46 - 19
src/vmathjaxinplacepreviewhelper.cpp

@@ -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));
+
+        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;
+        }
+    }
+}

+ 28 - 0
src/vmathjaxinplacepreviewhelper.h

@@ -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