Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4680 | right-hear | 1 | #include "fitz.h" |
2 | #include "mupdf.h" |
||
3 | |||
4 | typedef struct pdf_item_s pdf_item; |
||
5 | |||
6 | struct pdf_item_s |
||
7 | { |
||
8 | void *drop_func; |
||
9 | fz_obj *key; |
||
10 | void *val; |
||
11 | int age; |
||
12 | pdf_item *next; |
||
13 | }; |
||
14 | |||
15 | struct refkey |
||
16 | { |
||
17 | void *drop_func; |
||
18 | int num; |
||
19 | int gen; |
||
20 | }; |
||
21 | |||
22 | struct pdf_store_s |
||
23 | { |
||
24 | fz_hash_table *hash; /* hash for num/gen keys */ |
||
25 | pdf_item *root; /* linked list for everything else */ |
||
26 | }; |
||
27 | |||
28 | pdf_store * |
||
29 | pdf_new_store(void) |
||
30 | { |
||
31 | pdf_store *store; |
||
32 | store = fz_malloc(sizeof(pdf_store)); |
||
33 | store->hash = fz_new_hash_table(4096, sizeof(struct refkey)); |
||
34 | store->root = NULL; |
||
35 | return store; |
||
36 | } |
||
37 | |||
38 | void |
||
39 | pdf_store_item(pdf_store *store, void *keepfunc, void *drop_func, fz_obj *key, void *val) |
||
40 | { |
||
41 | pdf_item *item; |
||
42 | |||
43 | if (!store) |
||
44 | return; |
||
45 | |||
46 | item = fz_malloc(sizeof(pdf_item)); |
||
47 | item->drop_func = drop_func; |
||
48 | item->key = fz_keep_obj(key); |
||
49 | item->val = ((void*(*)(void*))keepfunc)(val); |
||
50 | item->age = 0; |
||
51 | item->next = NULL; |
||
52 | |||
53 | if (fz_is_indirect(key)) |
||
54 | { |
||
55 | struct refkey refkey; |
||
56 | refkey.drop_func = drop_func; |
||
57 | refkey.num = fz_to_num(key); |
||
58 | refkey.gen = fz_to_gen(key); |
||
59 | fz_hash_insert(store->hash, &refkey, item); |
||
60 | } |
||
61 | else |
||
62 | { |
||
63 | item->next = store->root; |
||
64 | store->root = item; |
||
65 | } |
||
66 | } |
||
67 | |||
68 | void * |
||
69 | pdf_find_item(pdf_store *store, void *drop_func, fz_obj *key) |
||
70 | { |
||
71 | struct refkey refkey; |
||
72 | pdf_item *item; |
||
73 | |||
74 | if (!store) |
||
75 | return NULL; |
||
76 | |||
77 | if (key == NULL) |
||
78 | return NULL; |
||
79 | |||
80 | if (fz_is_indirect(key)) |
||
81 | { |
||
82 | refkey.drop_func = drop_func; |
||
83 | refkey.num = fz_to_num(key); |
||
84 | refkey.gen = fz_to_gen(key); |
||
85 | item = fz_hash_find(store->hash, &refkey); |
||
86 | if (item) |
||
87 | { |
||
88 | item->age = 0; |
||
89 | return item->val; |
||
90 | } |
||
91 | } |
||
92 | else |
||
93 | { |
||
94 | for (item = store->root; item; item = item->next) |
||
95 | { |
||
96 | if (item->drop_func == drop_func && !fz_objcmp(item->key, key)) |
||
97 | { |
||
98 | item->age = 0; |
||
99 | return item->val; |
||
100 | } |
||
101 | } |
||
102 | } |
||
103 | |||
104 | return NULL; |
||
105 | } |
||
106 | |||
107 | void |
||
108 | pdf_remove_item(pdf_store *store, void *drop_func, fz_obj *key) |
||
109 | { |
||
110 | struct refkey refkey; |
||
111 | pdf_item *item, *prev, *next; |
||
112 | |||
113 | if (fz_is_indirect(key)) |
||
114 | { |
||
115 | refkey.drop_func = drop_func; |
||
116 | refkey.num = fz_to_num(key); |
||
117 | refkey.gen = fz_to_gen(key); |
||
118 | item = fz_hash_find(store->hash, &refkey); |
||
119 | if (item) |
||
120 | { |
||
121 | fz_hash_remove(store->hash, &refkey); |
||
122 | ((void(*)(void*))item->drop_func)(item->val); |
||
123 | fz_drop_obj(item->key); |
||
124 | fz_free(item); |
||
125 | } |
||
126 | } |
||
127 | else |
||
128 | { |
||
129 | prev = NULL; |
||
130 | for (item = store->root; item; item = next) |
||
131 | { |
||
132 | next = item->next; |
||
133 | if (item->drop_func == drop_func && !fz_objcmp(item->key, key)) |
||
134 | { |
||
135 | if (!prev) |
||
136 | store->root = next; |
||
137 | else |
||
138 | prev->next = next; |
||
139 | ((void(*)(void*))item->drop_func)(item->val); |
||
140 | fz_drop_obj(item->key); |
||
141 | fz_free(item); |
||
142 | } |
||
143 | else |
||
144 | prev = item; |
||
145 | } |
||
146 | } |
||
147 | } |
||
148 | |||
149 | void |
||
150 | pdf_age_store(pdf_store *store, int maxage) |
||
151 | { |
||
152 | struct refkey *refkey; |
||
153 | pdf_item *item, *prev, *next; |
||
154 | int i; |
||
155 | |||
156 | for (i = 0; i < fz_hash_len(store->hash); i++) |
||
157 | { |
||
158 | refkey = fz_hash_get_key(store->hash, i); |
||
159 | item = fz_hash_get_val(store->hash, i); |
||
160 | if (item && ++item->age > maxage) |
||
161 | { |
||
162 | fz_hash_remove(store->hash, refkey); |
||
163 | ((void(*)(void*))item->drop_func)(item->val); |
||
164 | fz_drop_obj(item->key); |
||
165 | fz_free(item); |
||
166 | i--; /* items with same hash may move into place */ |
||
167 | } |
||
168 | } |
||
169 | |||
170 | prev = NULL; |
||
171 | for (item = store->root; item; item = next) |
||
172 | { |
||
173 | next = item->next; |
||
174 | if (++item->age > maxage) |
||
175 | { |
||
176 | if (!prev) |
||
177 | store->root = next; |
||
178 | else |
||
179 | prev->next = next; |
||
180 | ((void(*)(void*))item->drop_func)(item->val); |
||
181 | fz_drop_obj(item->key); |
||
182 | fz_free(item); |
||
183 | } |
||
184 | else |
||
185 | prev = item; |
||
186 | } |
||
187 | } |
||
188 | |||
189 | void |
||
190 | pdf_free_store(pdf_store *store) |
||
191 | { |
||
192 | pdf_age_store(store, 0); |
||
193 | fz_free_hash(store->hash); |
||
194 | fz_free(store); |
||
195 | } |
||
196 | |||
197 | void |
||
198 | pdf_debug_store(pdf_store *store) |
||
199 | { |
||
200 | pdf_item *item; |
||
201 | pdf_item *next; |
||
202 | struct refkey *refkey; |
||
203 | int i; |
||
204 | |||
205 | printf("-- resource store contents --\n"); |
||
206 | |||
207 | for (i = 0; i < fz_hash_len(store->hash); i++) |
||
208 | { |
||
209 | refkey = fz_hash_get_key(store->hash, i); |
||
210 | item = fz_hash_get_val(store->hash, i); |
||
211 | if (item) |
||
212 | printf("store[%d] (%d %d R) = %p\n", i, refkey->num, refkey->gen, item->val); |
||
213 | } |
||
214 | |||
215 | for (item = store->root; item; item = next) |
||
216 | { |
||
217 | next = item->next; |
||
218 | printf("store[*] "); |
||
219 | fz_debug_obj(item->key); |
||
220 | printf(" = %p\n", item->val); |
||
221 | } |
||
222 | }>> |