Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
7858 views
1
#ifndef MUPDF_FITZ_STORE_H
2
#define MUPDF_FITZ_STORE_H
3
4
#include "mupdf/fitz/system.h"
5
#include "mupdf/fitz/context.h"
6
7
/*
8
Resource store
9
10
MuPDF stores decoded "objects" into a store for potential reuse.
11
If the size of the store gets too big, objects stored within it can
12
be evicted and freed to recover space. When MuPDF comes to decode
13
such an object, it will check to see if a version of this object is
14
already in the store - if it is, it will simply reuse it. If not, it
15
will decode it and place it into the store.
16
17
All objects that can be placed into the store are derived from the
18
fz_storable type (i.e. this should be the first component of the
19
objects structure). This allows for consistent (thread safe)
20
reference counting, and includes a function that will be called to
21
free the object as soon as the reference count reaches zero.
22
23
Most objects offer fz_keep_XXXX/fz_drop_XXXX functions derived
24
from fz_keep_storable/fz_drop_storable. Creation of such objects
25
includes a call to FZ_INIT_STORABLE to set up the fz_storable header.
26
*/
27
28
typedef struct fz_storable_s fz_storable;
29
30
typedef void (fz_store_drop_fn)(fz_context *, fz_storable *);
31
32
struct fz_storable_s {
33
int refs;
34
fz_store_drop_fn *drop;
35
};
36
37
#define FZ_INIT_STORABLE(S_,RC,DROP) \
38
do { fz_storable *S = &(S_)->storable; S->refs = (RC); \
39
S->drop = (DROP); \
40
} while (0)
41
42
void *fz_keep_storable(fz_context *, fz_storable *);
43
void fz_drop_storable(fz_context *, fz_storable *);
44
45
/*
46
The store can be seen as a dictionary that maps keys to fz_storable
47
values. In order to allow keys of different types to be stored, we
48
have a structure full of functions for each key 'type'; this
49
fz_store_type pointer is stored with each key, and tells the store
50
how to perform certain operations (like taking/dropping a reference,
51
comparing two keys, outputting details for debugging etc).
52
53
The store uses a hash table internally for speed where possible. In
54
order for this to work, we need a mechanism for turning a generic
55
'key' into 'a hashable string'. For this purpose the type structure
56
contains a make_hash_key function pointer that maps from a void *
57
to an fz_store_hash structure. If make_hash_key function returns 0,
58
then the key is determined not to be hashable, and the value is
59
not stored in the hash table.
60
*/
61
typedef struct fz_store_hash_s fz_store_hash;
62
63
struct fz_store_hash_s
64
{
65
fz_store_drop_fn *drop;
66
union
67
{
68
struct
69
{
70
int i0;
71
int i1;
72
void *ptr;
73
} i;
74
struct
75
{
76
void *ptr;
77
int i;
78
} pi;
79
struct
80
{
81
int id;
82
float m[4];
83
} im;
84
} u;
85
};
86
87
typedef struct fz_store_type_s fz_store_type;
88
89
struct fz_store_type_s
90
{
91
int (*make_hash_key)(fz_context *ctx, fz_store_hash *, void *);
92
void *(*keep_key)(fz_context *,void *);
93
void (*drop_key)(fz_context *,void *);
94
int (*cmp_key)(fz_context *ctx, void *, void *);
95
#ifndef NDEBUG
96
void (*debug)(fz_context *ctx, FILE *, void *);
97
#endif
98
};
99
100
/*
101
fz_store_new_context: Create a new store inside the context
102
103
max: The maximum size (in bytes) that the store is allowed to grow
104
to. FZ_STORE_UNLIMITED means no limit.
105
*/
106
void fz_new_store_context(fz_context *ctx, unsigned int max);
107
108
/*
109
fz_drop_store_context: Drop a reference to the store.
110
*/
111
void fz_drop_store_context(fz_context *ctx);
112
113
/*
114
fz_keep_store_context: Take a reference to the store.
115
*/
116
fz_store *fz_keep_store_context(fz_context *ctx);
117
118
/*
119
fz_store_item: Add an item to the store.
120
121
Add an item into the store, returning NULL for success. If an item
122
with the same key is found in the store, then our item will not be
123
inserted, and the function will return a pointer to that value
124
instead. This function takes its own reference to val, as required
125
(i.e. the caller maintains ownership of its own reference).
126
127
key: The key to use to index the item.
128
129
val: The value to store.
130
131
itemsize: The size in bytes of the value (as counted towards the
132
store size).
133
134
type: Functions used to manipulate the key.
135
*/
136
void *fz_store_item(fz_context *ctx, void *key, void *val, unsigned int itemsize, fz_store_type *type);
137
138
/*
139
fz_find_item: Find an item within the store.
140
141
drop: The function used to free the value (to ensure we get a value
142
of the correct type).
143
144
key: The key to use to index the item.
145
146
type: Functions used to manipulate the key.
147
148
Returns NULL for not found, otherwise returns a pointer to the value
149
indexed by key to which a reference has been taken.
150
*/
151
void *fz_find_item(fz_context *ctx, fz_store_drop_fn *drop, void *key, fz_store_type *type);
152
153
/*
154
fz_remove_item: Remove an item from the store.
155
156
If an item indexed by the given key exists in the store, remove it.
157
158
drop: The function used to free the value (to ensure we get a value
159
of the correct type).
160
161
key: The key to use to find the item to remove.
162
163
type: Functions used to manipulate the key.
164
*/
165
void fz_remove_item(fz_context *ctx, fz_store_drop_fn *drop, void *key, fz_store_type *type);
166
167
/*
168
fz_empty_store: Evict everything from the store.
169
*/
170
void fz_empty_store(fz_context *ctx);
171
172
/*
173
fz_store_scavenge: Internal function used as part of the scavenging
174
allocator; when we fail to allocate memory, before returning a
175
failure to the caller, we try to scavenge space within the store by
176
evicting at least 'size' bytes. The allocator then retries.
177
178
size: The number of bytes we are trying to have free.
179
180
phase: What phase of the scavenge we are in. Updated on exit.
181
182
Returns non zero if we managed to free any memory.
183
*/
184
int fz_store_scavenge(fz_context *ctx, unsigned int size, int *phase);
185
186
/*
187
fz_shrink_store: Evict items from the store until the total size of
188
the objects in the store is reduced to a given percentage of its
189
current size.
190
191
percent: %age of current size to reduce the store to.
192
193
Returns non zero if we managed to free enough memory, zero otherwise.
194
*/
195
int fz_shrink_store(fz_context *ctx, unsigned int percent);
196
197
/*
198
fz_print_store: Dump the contents of the store for debugging.
199
*/
200
#ifndef NDEBUG
201
void fz_print_store(fz_context *ctx, FILE *out);
202
void fz_print_store_locked(fz_context *ctx, FILE *out);
203
#endif
204
205
#endif
206
207