[poppler] poppler/XRef.cc poppler/XRef.h

Albert Astals Cid aacid at kemper.freedesktop.org
Mon Jun 14 11:18:33 PDT 2010


 poppler/XRef.cc |   62 +++++++++++++++++++++++++++++++++++++++++++++++---------
 poppler/XRef.h  |    4 +--
 2 files changed, 55 insertions(+), 11 deletions(-)

New commits:
commit 3ca304f3837af27ae49541a5f441d8729264a945
Author: Albert Astals Cid <aacid at kde.org>
Date:   Mon Jun 14 19:16:41 2010 +0100

    Add more caching to ObjectStreams
    
    Makes opening of file from bug 26759 ten times faster

diff --git a/poppler/XRef.cc b/poppler/XRef.cc
index 9d0cd3b..a9cf571 100644
--- a/poppler/XRef.cc
+++ b/poppler/XRef.cc
@@ -45,6 +45,7 @@
 #include "Error.h"
 #include "ErrorCodes.h"
 #include "XRef.h"
+#include "PopplerCache.h"
 
 //------------------------------------------------------------------------
 
@@ -97,6 +98,37 @@ private:
   GBool ok;
 };
 
+class ObjectStreamKey : public PopplerCacheKey
+{
+  public:
+    ObjectStreamKey(int num) : objStrNum(num)
+    {
+    }
+
+    bool operator==(const PopplerCacheKey &key) const
+    {
+      const ObjectStreamKey *k = static_cast<const ObjectStreamKey*>(&key);
+      return objStrNum == k->objStrNum;
+    }
+
+    const int objStrNum;
+};
+
+class ObjectStreamItem : public PopplerCacheItem
+{
+  public:
+    ObjectStreamItem(ObjectStream *objStr) : objStream(objStr)
+    {
+    }
+
+    ~ObjectStreamItem()
+    {
+      delete objStream;
+    }
+
+    ObjectStream *objStream;
+};
+
 ObjectStream::ObjectStream(XRef *xref, int objStrNumA) {
   Stream *str;
   Parser *parser;
@@ -233,7 +265,7 @@ XRef::XRef() {
   size = 0;
   streamEnds = NULL;
   streamEndsLen = 0;
-  objStr = NULL;
+  objStrs = new PopplerCache(5);
 }
 
 XRef::XRef(BaseStream *strA) {
@@ -246,7 +278,7 @@ XRef::XRef(BaseStream *strA) {
   entries = NULL;
   streamEnds = NULL;
   streamEndsLen = 0;
-  objStr = NULL;
+  objStrs = new PopplerCache(5);
 
   encrypted = gFalse;
   permFlags = defPermFlags;
@@ -309,8 +341,8 @@ XRef::~XRef() {
   if (streamEnds) {
     gfree(streamEnds);
   }
-  if (objStr) {
-    delete objStr;
+  if (objStrs) {
+    delete objStrs;
   }
 }
 
@@ -1010,22 +1042,34 @@ Object *XRef::fetch(int num, int gen, Object *obj) {
     break;
 
   case xrefEntryCompressed:
+  {
     if (gen != 0) {
       goto err;
     }
-    if (!objStr || objStr->getObjStrNum() != (int)e->offset) {
-      if (objStr) {
-	delete objStr;
-      }
+
+    ObjectStream *objStr = NULL;
+    ObjectStreamKey key(e->offset);
+    PopplerCacheItem *item = objStrs->lookup(key);
+    if (item) {
+      ObjectStreamItem *it = static_cast<ObjectStreamItem *>(item);
+      objStr = it->objStream;
+    }
+
+    if (!objStr) {
       objStr = new ObjectStream(this, e->offset);
       if (!objStr->isOk()) {
 	delete objStr;
 	objStr = NULL;
 	goto err;
+      } else {
+	ObjectStreamKey *newkey = new ObjectStreamKey(e->offset);
+	ObjectStreamItem *newitem = new ObjectStreamItem(objStr);
+	objStrs->put(newkey, newitem);
       }
     }
     objStr->getObject(e->gen, num, obj);
-    break;
+  }
+  break;
 
   default:
     goto err;
diff --git a/poppler/XRef.h b/poppler/XRef.h
index 36546fc..be19e23 100644
--- a/poppler/XRef.h
+++ b/poppler/XRef.h
@@ -37,7 +37,7 @@
 class Dict;
 class Stream;
 class Parser;
-class ObjectStream;
+class PopplerCache;
 
 //------------------------------------------------------------------------
 // XRef
@@ -146,7 +146,7 @@ private:
   Guint *streamEnds;		// 'endstream' positions - only used in
 				//   damaged files
   int streamEndsLen;		// number of valid entries in streamEnds
-  ObjectStream *objStr;		// cached object stream
+  PopplerCache *objStrs;	// cached object streams
   GBool encrypted;		// true if file is encrypted
   int encRevision;		
   int encVersion;		// encryption algorithm


More information about the poppler mailing list