summaryrefslogtreecommitdiff
path: root/pdf/pdf_store.c
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2011-04-04 18:18:16 +0200
committerTor Andersson <tor.andersson@artifex.com>2011-04-04 18:18:16 +0200
commitf81e5ab22ba18963e56aad43c1c7fa9826935f3d (patch)
treecf3b261e90df51014755a8d1395116f839f73c95 /pdf/pdf_store.c
parentc8d226b5bfb5dab2db10ea5175966de7bac9640e (diff)
downloadmupdf-f81e5ab22ba18963e56aad43c1c7fa9826935f3d.tar.xz
pdf: Rename mupdf directory.
Diffstat (limited to 'pdf/pdf_store.c')
-rw-r--r--pdf/pdf_store.c224
1 files changed, 224 insertions, 0 deletions
diff --git a/pdf/pdf_store.c b/pdf/pdf_store.c
new file mode 100644
index 00000000..d6be2088
--- /dev/null
+++ b/pdf/pdf_store.c
@@ -0,0 +1,224 @@
+#include "fitz.h"
+#include "mupdf.h"
+
+typedef struct pdf_item_s pdf_item;
+
+struct pdf_item_s
+{
+ void *dropfunc;
+ fz_obj *key;
+ void *val;
+ int age;
+ pdf_item *next;
+};
+
+struct refkey
+{
+ void *dropfunc;
+ int num;
+ int gen;
+};
+
+struct pdf_store_s
+{
+ fz_hashtable *hash; /* hash for num/gen keys */
+ pdf_item *root; /* linked list for everything else */
+};
+
+pdf_store *
+pdf_newstore(void)
+{
+ pdf_store *store;
+ store = fz_malloc(sizeof(pdf_store));
+ store->hash = fz_newhash(4096, sizeof(struct refkey));
+ store->root = nil;
+ return store;
+}
+
+void
+pdf_storeitem(pdf_store *store, void *keepfunc, void *dropfunc, fz_obj *key, void *val)
+{
+ pdf_item *item;
+
+ if (!store)
+ return;
+
+ item = fz_malloc(sizeof(pdf_item));
+ item->dropfunc = dropfunc;
+ item->key = fz_keepobj(key);
+ item->val = ((void*(*)(void*))keepfunc)(val);
+ item->age = 0;
+ item->next = nil;
+
+ if (fz_isindirect(key))
+ {
+ struct refkey refkey;
+ pdf_logrsrc("store item (%d %d R) ptr=%p\n", fz_tonum(key), fz_togen(key), val);
+ refkey.dropfunc = dropfunc;
+ refkey.num = fz_tonum(key);
+ refkey.gen = fz_togen(key);
+ fz_hashinsert(store->hash, &refkey, item);
+ }
+ else
+ {
+ pdf_logrsrc("store item (...) = %p\n", val);
+ item->next = store->root;
+ store->root = item;
+ }
+}
+
+void *
+pdf_finditem(pdf_store *store, void *dropfunc, fz_obj *key)
+{
+ struct refkey refkey;
+ pdf_item *item;
+
+ if (!store)
+ return nil;
+
+ if (key == nil)
+ return nil;
+
+ if (fz_isindirect(key))
+ {
+ refkey.dropfunc = dropfunc;
+ refkey.num = fz_tonum(key);
+ refkey.gen = fz_togen(key);
+ item = fz_hashfind(store->hash, &refkey);
+ if (item)
+ {
+ item->age = 0;
+ return item->val;
+ }
+ }
+ else
+ {
+ for (item = store->root; item; item = item->next)
+ {
+ if (item->dropfunc == dropfunc && !fz_objcmp(item->key, key))
+ {
+ item->age = 0;
+ return item->val;
+ }
+ }
+ }
+
+ return nil;
+}
+
+void
+pdf_removeitem(pdf_store *store, void *dropfunc, fz_obj *key)
+{
+ struct refkey refkey;
+ pdf_item *item, *prev, *next;
+
+ if (fz_isindirect(key))
+ {
+ refkey.dropfunc = dropfunc;
+ refkey.num = fz_tonum(key);
+ refkey.gen = fz_togen(key);
+ item = fz_hashfind(store->hash, &refkey);
+ if (item)
+ {
+ fz_hashremove(store->hash, &refkey);
+ ((void(*)(void*))item->dropfunc)(item->val);
+ fz_dropobj(item->key);
+ fz_free(item);
+ }
+ }
+ else
+ {
+ prev = nil;
+ for (item = store->root; item; item = next)
+ {
+ next = item->next;
+ if (item->dropfunc == dropfunc && !fz_objcmp(item->key, key))
+ {
+ if (!prev)
+ store->root = next;
+ else
+ prev->next = next;
+ ((void(*)(void*))item->dropfunc)(item->val);
+ fz_dropobj(item->key);
+ fz_free(item);
+ }
+ else
+ prev = item;
+ }
+ }
+}
+
+void
+pdf_agestore(pdf_store *store, int maxage)
+{
+ struct refkey *refkey;
+ pdf_item *item, *prev, *next;
+ int i;
+
+ for (i = 0; i < fz_hashlen(store->hash); i++)
+ {
+ refkey = fz_hashgetkey(store->hash, i);
+ item = fz_hashgetval(store->hash, i);
+ if (item && ++item->age > maxage)
+ {
+ fz_hashremove(store->hash, refkey);
+ ((void(*)(void*))item->dropfunc)(item->val);
+ fz_dropobj(item->key);
+ fz_free(item);
+ i--; /* items with same hash may move into place */
+ }
+ }
+
+ prev = nil;
+ for (item = store->root; item; item = next)
+ {
+ next = item->next;
+ if (++item->age > maxage)
+ {
+ if (!prev)
+ store->root = next;
+ else
+ prev->next = next;
+ ((void(*)(void*))item->dropfunc)(item->val);
+ fz_dropobj(item->key);
+ fz_free(item);
+ }
+ else
+ prev = item;
+ }
+}
+
+void
+pdf_freestore(pdf_store *store)
+{
+ pdf_agestore(store, 0);
+ fz_freehash(store->hash);
+ fz_free(store);
+}
+
+void
+pdf_debugstore(pdf_store *store)
+{
+ pdf_item *item;
+ pdf_item *next;
+ struct refkey *refkey;
+ int i;
+
+ printf("-- resource store contents --\n");
+
+ for (i = 0; i < fz_hashlen(store->hash); i++)
+ {
+ refkey = fz_hashgetkey(store->hash, i);
+ item = fz_hashgetval(store->hash, i);
+ if (item)
+ printf("store[%d] (%d %d R) = %p\n", i, refkey->num, refkey->gen, item->val);
+ }
+
+ for (item = store->root; item; item = next)
+ {
+ next = item->next;
+ printf("store[*] ");
+ fz_debugobj(item->key);
+ printf(" = %p\n", item->val);
+ }
+}