diff options
author | Tor Andersson <tor.andersson@artifex.com> | 2011-04-04 18:18:16 +0200 |
---|---|---|
committer | Tor Andersson <tor.andersson@artifex.com> | 2011-04-04 18:18:16 +0200 |
commit | f81e5ab22ba18963e56aad43c1c7fa9826935f3d (patch) | |
tree | cf3b261e90df51014755a8d1395116f839f73c95 /pdf/pdf_store.c | |
parent | c8d226b5bfb5dab2db10ea5175966de7bac9640e (diff) | |
download | mupdf-f81e5ab22ba18963e56aad43c1c7fa9826935f3d.tar.xz |
pdf: Rename mupdf directory.
Diffstat (limited to 'pdf/pdf_store.c')
-rw-r--r-- | pdf/pdf_store.c | 224 |
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); + } +} |