Hi, this patch makes opening of file in bug 26759 go down from around 15 secs 
to 1.5 secs by caching more ObjectStream objects. Obviously some more memory 
is used but i think a 10x speed is worth it.

Any objection to commit it to both master and 0.14 branches?

Albert
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;
_______________________________________________
poppler mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/poppler

Reply via email to