beta-0.89.2
[luatex.git] / source / libs / cairo / cairo-src / src / cairo-cache.c
blob5c4e4caa3d005142d3dac8756e0abb14db5c7bb4
1 /* cairo - a vector graphics library with display and print output
3 * Copyright © 2004 Red Hat, Inc.
4 * Copyright © 2005 Red Hat, Inc.
6 * This library is free software; you can redistribute it and/or
7 * modify it either under the terms of the GNU Lesser General Public
8 * License version 2.1 as published by the Free Software Foundation
9 * (the "LGPL") or, at your option, under the terms of the Mozilla
10 * Public License Version 1.1 (the "MPL"). If you do not alter this
11 * notice, a recipient may use your version of this file under either
12 * the MPL or the LGPL.
14 * You should have received a copy of the LGPL along with this library
15 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
17 * You should have received a copy of the MPL along with this library
18 * in the file COPYING-MPL-1.1
20 * The contents of this file are subject to the Mozilla Public License
21 * Version 1.1 (the "License"); you may not use this file except in
22 * compliance with the License. You may obtain a copy of the License at
23 * http://www.mozilla.org/MPL/
25 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
26 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
27 * the specific language governing rights and limitations.
29 * The Original Code is the cairo graphics library.
31 * The Initial Developer of the Original Code is Red Hat, Inc.
33 * Contributor(s):
34 * Keith Packard <keithp@keithp.com>
35 * Graydon Hoare <graydon@redhat.com>
36 * Carl Worth <cworth@cworth.org>
39 #include "cairoint.h"
40 #include "cairo-error-private.h"
42 static void
43 _cairo_cache_shrink_to_accommodate (cairo_cache_t *cache,
44 unsigned long additional);
46 static cairo_bool_t
47 _cairo_cache_entry_is_non_zero (const void *entry)
49 return ((const cairo_cache_entry_t *) entry)->size;
53 /**
54 * _cairo_cache_init:
55 * @cache: the #cairo_cache_t to initialise
56 * @keys_equal: a function to return %TRUE if two keys are equal
57 * @entry_destroy: destroy notifier for cache entries
58 * @max_size: the maximum size for this cache
59 * Returns: the newly created #cairo_cache_t
61 * Creates a new cache using the keys_equal() function to determine
62 * the equality of entries.
64 * Data is provided to the cache in the form of user-derived version
65 * of #cairo_cache_entry_t. A cache entry must be able to hold hash
66 * code, a size, and the key/value pair being stored in the
67 * cache. Sometimes only the key will be necessary, (as in
68 * _cairo_cache_lookup()), and in these cases the value portion of the
69 * entry need not be initialized.
71 * The units for max_size can be chosen by the caller, but should be
72 * consistent with the units of the size field of cache entries. When
73 * adding an entry with _cairo_cache_insert() if the total size of
74 * entries in the cache would exceed max_size then entries will be
75 * removed at random until the new entry would fit or the cache is
76 * empty. Then the new entry is inserted.
78 * There are cases in which the automatic removal of entries is
79 * undesired. If the cache entries have reference counts, then it is a
80 * simple matter to use the reference counts to ensure that entries
81 * continue to live even after being ejected from the cache. However,
82 * in some cases the memory overhead of adding a reference count to
83 * the entry would be objectionable. In such cases, the
84 * _cairo_cache_freeze() and _cairo_cache_thaw() calls can be
85 * used to establish a window during which no automatic removal of
86 * entries will occur.
87 **/
88 cairo_status_t
89 _cairo_cache_init (cairo_cache_t *cache,
90 cairo_cache_keys_equal_func_t keys_equal,
91 cairo_cache_predicate_func_t predicate,
92 cairo_destroy_func_t entry_destroy,
93 unsigned long max_size)
95 cache->hash_table = _cairo_hash_table_create (keys_equal);
96 if (unlikely (cache->hash_table == NULL))
97 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
99 if (predicate == NULL)
100 predicate = _cairo_cache_entry_is_non_zero;
101 cache->predicate = predicate;
102 cache->entry_destroy = entry_destroy;
104 cache->max_size = max_size;
105 cache->size = 0;
107 cache->freeze_count = 0;
109 return CAIRO_STATUS_SUCCESS;
112 static void
113 _cairo_cache_pluck (void *entry, void *closure)
115 _cairo_cache_remove (closure, entry);
119 * _cairo_cache_fini:
120 * @cache: a cache to destroy
122 * Immediately destroys the given cache, freeing all resources
123 * associated with it. As part of this process, the entry_destroy()
124 * function, (as passed to _cairo_cache_init()), will be called for
125 * each entry in the cache.
127 void
128 _cairo_cache_fini (cairo_cache_t *cache)
130 _cairo_hash_table_foreach (cache->hash_table,
131 _cairo_cache_pluck,
132 cache);
133 assert (cache->size == 0);
134 _cairo_hash_table_destroy (cache->hash_table);
138 * _cairo_cache_freeze:
139 * @cache: a cache with some precious entries in it (or about to be
140 * added)
142 * Disable the automatic ejection of entries from the cache. For as
143 * long as the cache is "frozen", calls to _cairo_cache_insert() will
144 * add new entries to the cache regardless of how large the cache
145 * grows. See _cairo_cache_thaw().
147 * Note: Multiple calls to _cairo_cache_freeze() will stack, in that
148 * the cache will remain "frozen" until a corresponding number of
149 * calls are made to _cairo_cache_thaw().
151 void
152 _cairo_cache_freeze (cairo_cache_t *cache)
154 assert (cache->freeze_count >= 0);
156 cache->freeze_count++;
160 * _cairo_cache_thaw:
161 * @cache: a cache, just after the entries in it have become less
162 * precious
164 * Cancels the effects of _cairo_cache_freeze().
166 * When a number of calls to _cairo_cache_thaw() is made corresponding
167 * to the number of calls to _cairo_cache_freeze() the cache will no
168 * longer be "frozen". If the cache had grown larger than max_size
169 * while frozen, entries will immediately be ejected (by random) from
170 * the cache until the cache is smaller than max_size. Also, the
171 * automatic ejection of entries on _cairo_cache_insert() will resume.
173 void
174 _cairo_cache_thaw (cairo_cache_t *cache)
176 assert (cache->freeze_count > 0);
178 if (--cache->freeze_count == 0)
179 _cairo_cache_shrink_to_accommodate (cache, 0);
183 * _cairo_cache_lookup:
184 * @cache: a cache
185 * @key: the key of interest
186 * @entry_return: pointer for return value
188 * Performs a lookup in @cache looking for an entry which has a key
189 * that matches @key, (as determined by the keys_equal() function
190 * passed to _cairo_cache_init()).
192 * Return value: %TRUE if there is an entry in the cache that matches
193 * @key, (which will now be in *entry_return). %FALSE otherwise, (in
194 * which case *entry_return will be %NULL).
196 void *
197 _cairo_cache_lookup (cairo_cache_t *cache,
198 cairo_cache_entry_t *key)
200 return _cairo_hash_table_lookup (cache->hash_table,
201 (cairo_hash_entry_t *) key);
205 * _cairo_cache_remove_random:
206 * @cache: a cache
208 * Remove a random entry from the cache.
210 * Return value: %TRUE if an entry was successfully removed.
211 * %FALSE if there are no entries that can be removed.
213 static cairo_bool_t
214 _cairo_cache_remove_random (cairo_cache_t *cache)
216 cairo_cache_entry_t *entry;
218 entry = _cairo_hash_table_random_entry (cache->hash_table,
219 cache->predicate);
220 if (unlikely (entry == NULL))
221 return FALSE;
223 _cairo_cache_remove (cache, entry);
225 return TRUE;
229 * _cairo_cache_shrink_to_accommodate:
230 * @cache: a cache
231 * @additional: additional size requested in bytes
233 * If cache is not frozen, eject entries randomly until the size of
234 * the cache is at least @additional bytes less than
235 * cache->max_size. That is, make enough room to accommodate a new
236 * entry of size @additional.
238 static void
239 _cairo_cache_shrink_to_accommodate (cairo_cache_t *cache,
240 unsigned long additional)
242 while (cache->size + additional > cache->max_size) {
243 if (! _cairo_cache_remove_random (cache))
244 return;
249 * _cairo_cache_insert:
250 * @cache: a cache
251 * @entry: an entry to be inserted
253 * Insert @entry into the cache. If an entry exists in the cache with
254 * a matching key, then the old entry will be removed first, (and the
255 * entry_destroy() callback will be called on it).
257 * Return value: %CAIRO_STATUS_SUCCESS if successful or
258 * %CAIRO_STATUS_NO_MEMORY if insufficient memory is available.
260 cairo_status_t
261 _cairo_cache_insert (cairo_cache_t *cache,
262 cairo_cache_entry_t *entry)
264 cairo_status_t status;
266 if (entry->size && ! cache->freeze_count)
267 _cairo_cache_shrink_to_accommodate (cache, entry->size);
269 status = _cairo_hash_table_insert (cache->hash_table,
270 (cairo_hash_entry_t *) entry);
271 if (unlikely (status))
272 return status;
274 cache->size += entry->size;
276 return CAIRO_STATUS_SUCCESS;
280 * _cairo_cache_remove:
281 * @cache: a cache
282 * @entry: an entry that exists in the cache
284 * Remove an existing entry from the cache.
286 void
287 _cairo_cache_remove (cairo_cache_t *cache,
288 cairo_cache_entry_t *entry)
290 cache->size -= entry->size;
292 _cairo_hash_table_remove (cache->hash_table,
293 (cairo_hash_entry_t *) entry);
295 if (cache->entry_destroy)
296 cache->entry_destroy (entry);
300 * _cairo_cache_foreach:
301 * @cache: a cache
302 * @cache_callback: function to be called for each entry
303 * @closure: additional argument to be passed to @cache_callback
305 * Call @cache_callback for each entry in the cache, in a
306 * non-specified order.
308 void
309 _cairo_cache_foreach (cairo_cache_t *cache,
310 cairo_cache_callback_func_t cache_callback,
311 void *closure)
313 _cairo_hash_table_foreach (cache->hash_table,
314 cache_callback,
315 closure);
318 unsigned long
319 _cairo_hash_string (const char *c)
321 /* This is the djb2 hash. */
322 unsigned long hash = _CAIRO_HASH_INIT_VALUE;
323 while (c && *c)
324 hash = ((hash << 5) + hash) + *c++;
325 return hash;
328 unsigned long
329 _cairo_hash_bytes (unsigned long hash,
330 const void *ptr,
331 unsigned int length)
333 const uint8_t *bytes = ptr;
334 /* This is the djb2 hash. */
335 while (length--)
336 hash = ((hash << 5) + hash) + *bytes++;
337 return hash;