mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-01 19:38:03 +02:00
Originally 2005-09-06 Carl Worth <cworth@cworth.org>:
_cairo_cache_preserve -> _cairo_cache_freeze _cairo_cache_release -> _cairo_cache_thaw Track rename of _cairo_cache_freeze/thaw. Track rename. Add stacking behavior to _cairo_cache_freeze/thaw. Abstract out shrinking from _cairo_cache_insert so that _cairo_cache_thaw will also shrink as necessary. Make this function static since its current limitation to accept an entry rather than a key makes it not as externally useful as would be desirable. Document this limitation.
This commit is contained in:
parent
b1a38efd34
commit
999c2a8a2b
4 changed files with 112 additions and 48 deletions
24
ChangeLog
24
ChangeLog
|
|
@ -1,3 +1,27 @@
|
|||
2005-09-12 Carl Worth <cworth@cworth.org>
|
||||
|
||||
Originally 2005-09-06 Carl Worth <cworth@cworth.org>:
|
||||
|
||||
* src/cairo-cache-private.h: Rename:
|
||||
|
||||
_cairo_cache_preserve -> _cairo_cache_freeze
|
||||
_cairo_cache_release -> _cairo_cache_thaw
|
||||
|
||||
* src/cairo-scaled-font.c: (_cairo_scaled_font_show_glyphs): Track
|
||||
rename of _cairo_cache_freeze/thaw.
|
||||
|
||||
* src/cairo-cache.c: (_cairo_cache_init), (_cairo_cache_freeze),
|
||||
(_cairo_cache_thaw), (_cairo_cache_shrink_to_accomodate),
|
||||
(_cairo_cache_insert): Track rename. Add stacking behavior to
|
||||
_cairo_cache_freeze/thaw. Abstract out shrinking from
|
||||
_cairo_cache_insert so that _cairo_cache_thaw will also shrink as
|
||||
necessary.
|
||||
|
||||
* src/cairo-cache.c: (_cairo_cache_remove): Make this function
|
||||
static since its current limitation to accept an entry rather than
|
||||
a key makes it not as externally useful as would be
|
||||
desirable. Document this limitation.
|
||||
|
||||
2005-09-12 Carl Worth <cworth@cworth.org>
|
||||
|
||||
Fix for bug #4401 as reported by Tim Mooney:
|
||||
|
|
|
|||
|
|
@ -103,10 +103,10 @@ cairo_private void
|
|||
_cairo_cache_destroy (cairo_cache_t *cache);
|
||||
|
||||
cairo_private void
|
||||
_cairo_cache_preserve (cairo_cache_t *cache);
|
||||
_cairo_cache_freeze (cairo_cache_t *cache);
|
||||
|
||||
cairo_private void
|
||||
_cairo_cache_release (cairo_cache_t *cache);
|
||||
_cairo_cache_thaw (cairo_cache_t *cache);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_cache_lookup (cairo_cache_t *cache,
|
||||
|
|
@ -117,10 +117,6 @@ cairo_private cairo_status_t
|
|||
_cairo_cache_insert (cairo_cache_t *cache,
|
||||
cairo_cache_entry_t *entry);
|
||||
|
||||
cairo_private void
|
||||
_cairo_cache_remove (cairo_cache_t *cache,
|
||||
cairo_cache_entry_t *key);
|
||||
|
||||
cairo_private void
|
||||
_cairo_cache_foreach (cairo_cache_t *cache,
|
||||
cairo_cache_callback_func_t cache_callback,
|
||||
|
|
|
|||
|
|
@ -46,9 +46,18 @@ struct _cairo_cache {
|
|||
unsigned long max_size;
|
||||
unsigned long size;
|
||||
|
||||
cairo_bool_t preserve_entries;
|
||||
int freeze_count;
|
||||
};
|
||||
|
||||
static void
|
||||
_cairo_cache_remove (cairo_cache_t *cache,
|
||||
cairo_cache_entry_t *entry);
|
||||
|
||||
static void
|
||||
_cairo_cache_shrink_to_accomodate (cairo_cache_t *cache,
|
||||
unsigned long additional);
|
||||
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_cache_init (cairo_cache_t *cache,
|
||||
cairo_cache_keys_equal_func_t keys_equal,
|
||||
|
|
@ -64,7 +73,7 @@ _cairo_cache_init (cairo_cache_t *cache,
|
|||
cache->max_size = max_size;
|
||||
cache->size = 0;
|
||||
|
||||
cache->preserve_entries = FALSE;
|
||||
cache->freeze_count = 0;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
@ -103,7 +112,7 @@ _cairo_cache_fini (cairo_cache_t *cache)
|
|||
* of cairo_cache_entry_t. A cache entry must be able to hold hash
|
||||
* code, a size, and the key/value pair being stored in the
|
||||
* cache. Sometimes only the key will be necessary, (as in
|
||||
* _cairo_cache_remove()), and in these cases the value portion of the
|
||||
* _cairo_cache_lookup()), and in these cases the value portion of the
|
||||
* entry need not be initialized.
|
||||
*
|
||||
* The units for max_size can be chosen by the caller, but should be
|
||||
|
|
@ -119,7 +128,7 @@ _cairo_cache_fini (cairo_cache_t *cache)
|
|||
* continue to live even after being ejected from the cache. However,
|
||||
* in some cases the memory overhead of adding a reference count to
|
||||
* the entry would be objectionable. In such cases, the
|
||||
* _cairo_cache_preserve() and _cairo_cache_release() calls can be
|
||||
* _cairo_cache_freeze() and _cairo_cache_thaw() calls can be
|
||||
* used to establish a window during which no automatic removal of
|
||||
* entries will occur.
|
||||
*
|
||||
|
|
@ -164,37 +173,50 @@ _cairo_cache_destroy (cairo_cache_t *cache)
|
|||
}
|
||||
|
||||
/**
|
||||
* _cairo_cache_preserve:
|
||||
* _cairo_cache_freeze:
|
||||
* @cache: a cache with some precious entries in it (or about to be
|
||||
* added)
|
||||
*
|
||||
* Disable the automatic ejection of entries from the cache. Future
|
||||
* calls to _cairo_cache_insert() will add new entries to the cache
|
||||
* regardless of how large the cache grows. See
|
||||
* _cairo_cache_release().
|
||||
* Disable the automatic ejection of entries from the cache. For as
|
||||
* long as the cache is "frozen", calls to _cairo_cache_insert() will
|
||||
* add new entries to the cache regardless of how large the cache
|
||||
* grows. See _cairo_cache_thaw().
|
||||
*
|
||||
* NOTE: Multiple calls to _cairo_cache_freeze() will stack, in that
|
||||
* the cache will remain "frozen" until a corresponding number of
|
||||
* calls are made to _cairo_cache_thaw().
|
||||
**/
|
||||
void
|
||||
_cairo_cache_preserve (cairo_cache_t *cache)
|
||||
_cairo_cache_freeze (cairo_cache_t *cache)
|
||||
{
|
||||
cache->preserve_entries = TRUE;
|
||||
assert (cache->freeze_count >= 0);
|
||||
|
||||
cache->freeze_count++;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_cache_release:
|
||||
* _cairo_cache_thaw:
|
||||
* @cache: a cache, just after the entries in it have become less
|
||||
* previous
|
||||
* precious
|
||||
*
|
||||
* Cancel the effects of _cairo_cache_preserve(). That is, allow the
|
||||
* cache to resume ejecting entries when it is larger than max_size as
|
||||
* passed to cairo_cache_create(). If the cache is already larger than
|
||||
* max_size, no entries will be immediately removed, but the cache
|
||||
* will be brought down to size at the time of the next call to
|
||||
* _cairo_cache_insert().
|
||||
* Cancels the effects of _cairo_cache_freeze().
|
||||
*
|
||||
* When a number of calls to _cairo_cache_thaw() is made corresponding
|
||||
* to the number of calls to _cairo_cache_freeze() the cache will no
|
||||
* longer be "frozen". If the cache had grown larger than max_size
|
||||
* while frozen, entries will immediately be ejected (by random) from
|
||||
* the cache until the cache is smaller than max_size. Also, the
|
||||
* automatic ejection of entries on _cairo_cache_insert() will resume.
|
||||
**/
|
||||
void
|
||||
_cairo_cache_release (cairo_cache_t *cache)
|
||||
_cairo_cache_thaw (cairo_cache_t *cache)
|
||||
{
|
||||
cache->preserve_entries = FALSE;
|
||||
assert (cache->freeze_count > 0);
|
||||
|
||||
cache->freeze_count--;
|
||||
|
||||
if (cache->freeze_count == 0)
|
||||
_cairo_cache_shrink_to_accomodate (cache, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -211,7 +233,7 @@ _cairo_cache_release (cairo_cache_t *cache)
|
|||
* @key, (which will now be in *entry_return). %FALSE otherwise, (in
|
||||
* which case *entry_return will be %NULL).
|
||||
**/
|
||||
cairo_private cairo_bool_t
|
||||
cairo_bool_t
|
||||
_cairo_cache_lookup (cairo_cache_t *cache,
|
||||
cairo_cache_entry_t *key,
|
||||
cairo_cache_entry_t **entry_return)
|
||||
|
|
@ -245,6 +267,35 @@ _cairo_cache_remove_random (cairo_cache_t *cache)
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_cache_shrink_to_accomodate:
|
||||
* @cache: a cache
|
||||
* @additional: additional size requested in bytes
|
||||
*
|
||||
* If cache is not frozen, eject entries randomly until the size of
|
||||
* the cache is at least @additional bytes less than
|
||||
* cache->max_size. That is, make enough room to accomodate a new
|
||||
* entry of size @additional.
|
||||
**/
|
||||
static void
|
||||
_cairo_cache_shrink_to_accomodate (cairo_cache_t *cache,
|
||||
unsigned long additional)
|
||||
{
|
||||
cairo_int_status_t status;
|
||||
|
||||
if (cache->freeze_count)
|
||||
return;
|
||||
|
||||
while (cache->size + additional > cache->max_size) {
|
||||
status = _cairo_cache_remove_random (cache);
|
||||
if (status) {
|
||||
if (status == CAIRO_INT_STATUS_CACHE_EMPTY)
|
||||
return;
|
||||
ASSERT_NOT_REACHED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_cache_insert:
|
||||
* @cache: a cache
|
||||
|
|
@ -257,22 +308,13 @@ _cairo_cache_remove_random (cairo_cache_t *cache)
|
|||
* Return value: CAIRO_STATUS_SUCCESS if successful or
|
||||
* CAIRO_STATUS_NO_MEMORY if insufficient memory is available.
|
||||
**/
|
||||
cairo_private cairo_status_t
|
||||
cairo_status_t
|
||||
_cairo_cache_insert (cairo_cache_t *cache,
|
||||
cairo_cache_entry_t *entry)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
if (! cache->preserve_entries) {
|
||||
while (cache->size + entry->size > cache->max_size) {
|
||||
status = _cairo_cache_remove_random (cache);
|
||||
if (status) {
|
||||
if (status == CAIRO_INT_STATUS_CACHE_EMPTY)
|
||||
break;
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
_cairo_cache_shrink_to_accomodate (cache, entry->size);
|
||||
|
||||
status = _cairo_hash_table_insert (cache->hash_table,
|
||||
(cairo_hash_entry_t *) entry);
|
||||
|
|
@ -287,13 +329,16 @@ _cairo_cache_insert (cairo_cache_t *cache,
|
|||
/**
|
||||
* _cairo_cache_remove:
|
||||
* @cache: a cache
|
||||
* @entry: key of entry to be removed
|
||||
* @entry: an entry that exists in the cache
|
||||
*
|
||||
* Remove an entry from the cache which has a key that matches @key,
|
||||
* if any (as determined by the keys_equal() function passed to
|
||||
* _cairo_cache_create()).
|
||||
* Remove an existing entry from the cache.
|
||||
*
|
||||
* (NOTE: If any caller wanted access to a non-static version of this
|
||||
* function, an improved version would require only a key rather than
|
||||
* an entry. Fixing that would require fixing _cairo_hash_table_remove
|
||||
* to return (a copy of?) the entry being removed.)
|
||||
**/
|
||||
cairo_private void
|
||||
static void
|
||||
_cairo_cache_remove (cairo_cache_t *cache,
|
||||
cairo_cache_entry_t *entry)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: cairo-scaled-font.c,v 1.3 2005-09-01 13:13:46 inte Exp $
|
||||
/* $Id: cairo-scaled-font.c,v 1.4 2005-09-12 18:15:52 cworth Exp $
|
||||
*
|
||||
* Copyright © 2005 Keith Packard
|
||||
*
|
||||
|
|
@ -804,7 +804,7 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
|
|||
|
||||
status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
_cairo_cache_preserve (scaled_font->glyphs);
|
||||
_cairo_cache_freeze (scaled_font->glyphs);
|
||||
|
||||
for (i = 0; i < num_glyphs; i++) {
|
||||
int x, y;
|
||||
|
|
@ -886,8 +886,7 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
|
|||
}
|
||||
|
||||
CLEANUP_MASK:
|
||||
|
||||
_cairo_cache_release (scaled_font->glyphs);
|
||||
_cairo_cache_thaw (scaled_font->glyphs);
|
||||
|
||||
if (mask != NULL)
|
||||
cairo_surface_destroy (mask);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue