Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Unified Diff: core/src/fxcodec/jbig2/JBig2_Context.cpp

Issue 761313004: Add a small LRU cache for the JBIG2 symbol dictionary. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: intial implementation Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: core/src/fxcodec/jbig2/JBig2_Context.cpp
diff --git a/core/src/fxcodec/jbig2/JBig2_Context.cpp b/core/src/fxcodec/jbig2/JBig2_Context.cpp
index 83ded6fbe18f15ac81bde0b7d0de95d9b25ad2be..865549a9fe452f99b9b0580c6f22b7f3fe835e2e 100644
--- a/core/src/fxcodec/jbig2/JBig2_Context.cpp
+++ b/core/src/fxcodec/jbig2/JBig2_Context.cpp
@@ -4,7 +4,22 @@
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+#include <map>
+#include <vector>
#include "JBig2_Context.h"
+
+// Implement a very small least recently used (LRU) cache. It is very
+// common for a JBIG2 dictionary to span multiple page in a PDF file,
+// and we do not want to decode the same dictionary over an over
+// again. We key off of the memory location of the dictionary. The
+// vector keeps track of when an entry should be deleted, to make space
+// for a new one. Even a tiny cache size like 2 makes a dramatic difference
+// for Google Books PDF files.
+const int kMaxCacheSize = 2;
+static std::map<FX_BYTE*, CJBig2_SymbolDict*> cache;
+static std::vector<FX_BYTE*> cache_keys;
+
+
void OutputBitmap(CJBig2_Image* pImage)
{
if(!pImage) {
@@ -614,6 +629,7 @@ FX_INT32 CJBig2_Context::parseSymbolDict(CJBig2_Segment *pSegment, IFX_Pause* pP
JBig2ArithCtx *gbContext = NULL, *grContext = NULL;
CJBig2_ArithDecoder *pArithDecoder;
JBIG2_ALLOC(pSymbolDictDecoder, CJBig2_SDDProc());
+ FX_BYTE *key = pSegment->m_pData;
if(m_pStream->readShortInteger(&wFlags) != 0) {
m_pModule->JBig2_Error("symbol dictionary segment : data header too short.");
nRet = JBIG2_ERROR_TOO_SHORT;
@@ -791,7 +807,17 @@ FX_INT32 CJBig2_Context::parseSymbolDict(CJBig2_Segment *pSegment, IFX_Pause* pP
}
}
pSegment->m_nResultType = JBIG2_SYMBOL_DICT_POINTER;
- if(pSymbolDictDecoder->SDHUFF == 0) {
+ if (cache.find(key) != cache.end()) {
+ pSegment->m_Result.sd = cache[key]->DeepCopy();
+ for(std::vector<FX_BYTE*>::iterator it = cache_keys.begin();
+ it != cache_keys.end(); ++it) {
+ if (*it == key) {
+ cache_keys.erase(cache_keys.begin());
Bo Xu 2014/12/06 05:59:43 Should line 815 be: "cache_keys.erase(it);" ? I gu
jab 2014/12/08 21:00:02 Done. (I made the front hold the freshest entries
+ break;
Bo Xu 2014/12/07 19:22:50 Or can we use std:list to replace the std:vector h
jab 2014/12/08 21:00:02 Done.
+ }
+ }
+ cache_keys.push_back(key);
+ } else if(pSymbolDictDecoder->SDHUFF == 0) {
JBIG2_ALLOC(pArithDecoder, CJBig2_ArithDecoder(m_pStream));
pSegment->m_Result.sd = pSymbolDictDecoder->decode_Arith(pArithDecoder, gbContext, grContext);
delete pArithDecoder;
@@ -809,6 +835,17 @@ FX_INT32 CJBig2_Context::parseSymbolDict(CJBig2_Segment *pSegment, IFX_Pause* pP
}
m_pStream->alignByte();
}
+ if (cache.find(key) == cache.end()) {
+ CJBig2_SymbolDict *value = pSegment->m_Result.sd->DeepCopy();
Bo Xu 2014/12/06 05:59:43 should |value| be deleted after use?
jab 2014/12/08 21:00:02 That you. I think I need to free the memory when w
Bo Xu 2014/12/08 23:00:17 How about making the cache member variable of the
jab 2014/12/08 23:21:04 I made an explicit call to delete. Is that okay? I
Bo Xu 2014/12/08 23:29:54 Sure, the explicit delete is ok here. I am thinki
+ if (value) {
+ while (cache_keys.size() >= kMaxCacheSize) {
+ cache.erase(cache_keys[0]);
+ cache_keys.erase(cache_keys.begin());
+ }
+ cache.insert(std::pair<FX_BYTE*, CJBig2_SymbolDict*>(key, value));
+ cache_keys.push_back(key);
+ }
+ }
if(wFlags & 0x0200) {
pSegment->m_Result.sd->m_bContextRetained = TRUE;
if(pSymbolDictDecoder->SDHUFF == 0) {
« no previous file with comments | « no previous file | core/src/fxcodec/jbig2/JBig2_SymbolDict.h » ('j') | core/src/fxcodec/jbig2/JBig2_SymbolDict.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698