mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-04 22:18:29 +02:00
[hash] Return lookup entry.
Use the return value to return the result from _cairo_hash_table_lookup() (as opposed to filling an output parameter on the stack) as this (a) results in cleaner code (no strict-alias breaking pointer casts), (b) produces a smaller binary and (c) is measurably faster.
This commit is contained in:
parent
d15fb9344b
commit
2b32c8b9e5
10 changed files with 67 additions and 88 deletions
|
|
@ -109,10 +109,9 @@ _cairo_cache_freeze (cairo_cache_t *cache);
|
|||
cairo_private void
|
||||
_cairo_cache_thaw (cairo_cache_t *cache);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
cairo_private void *
|
||||
_cairo_cache_lookup (cairo_cache_t *cache,
|
||||
cairo_cache_entry_t *key,
|
||||
cairo_cache_entry_t **entry_return);
|
||||
cairo_cache_entry_t *key);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_cache_insert (cairo_cache_t *cache,
|
||||
|
|
|
|||
|
|
@ -222,14 +222,12 @@ _cairo_cache_thaw (cairo_cache_t *cache)
|
|||
* @key, (which will now be in *entry_return). %FALSE otherwise, (in
|
||||
* which case *entry_return will be %NULL).
|
||||
**/
|
||||
cairo_bool_t
|
||||
void *
|
||||
_cairo_cache_lookup (cairo_cache_t *cache,
|
||||
cairo_cache_entry_t *key,
|
||||
cairo_cache_entry_t **entry_return)
|
||||
cairo_cache_entry_t *key)
|
||||
{
|
||||
return _cairo_hash_table_lookup (cache->hash_table,
|
||||
(cairo_hash_entry_t *) key,
|
||||
(cairo_hash_entry_t **) entry_return);
|
||||
(cairo_hash_entry_t *) key);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -529,9 +529,8 @@ cff_dict_remove (cairo_hash_table_t *dict, unsigned short operator)
|
|||
cff_dict_operator_t key, *op;
|
||||
|
||||
_cairo_dict_init_key (&key, operator);
|
||||
if (_cairo_hash_table_lookup (dict, &key.base,
|
||||
(cairo_hash_entry_t **) &op))
|
||||
{
|
||||
op = _cairo_hash_table_lookup (dict, &key.base);
|
||||
if (op != NULL) {
|
||||
free (op->operand);
|
||||
_cairo_hash_table_remove (dict, (cairo_hash_entry_t *) op);
|
||||
free (op);
|
||||
|
|
@ -546,9 +545,8 @@ cff_dict_get_operands (cairo_hash_table_t *dict,
|
|||
cff_dict_operator_t key, *op;
|
||||
|
||||
_cairo_dict_init_key (&key, operator);
|
||||
if (_cairo_hash_table_lookup (dict, &key.base,
|
||||
(cairo_hash_entry_t **) &op))
|
||||
{
|
||||
op = _cairo_hash_table_lookup (dict, &key.base);
|
||||
if (op != NULL) {
|
||||
*size = op->operand_length;
|
||||
return op->operand;
|
||||
}
|
||||
|
|
@ -566,9 +564,8 @@ cff_dict_set_operands (cairo_hash_table_t *dict,
|
|||
cairo_status_t status;
|
||||
|
||||
_cairo_dict_init_key (&key, operator);
|
||||
if (_cairo_hash_table_lookup (dict, &key.base,
|
||||
(cairo_hash_entry_t **) &op))
|
||||
{
|
||||
op = _cairo_hash_table_lookup (dict, &key.base);
|
||||
if (op != NULL) {
|
||||
free (op->operand);
|
||||
op->operand = malloc (size);
|
||||
if (op->operand == NULL)
|
||||
|
|
@ -599,9 +596,8 @@ cff_dict_get_location (cairo_hash_table_t *dict,
|
|||
cff_dict_operator_t key, *op;
|
||||
|
||||
_cairo_dict_init_key (&key, operator);
|
||||
if (_cairo_hash_table_lookup (dict, &key.base,
|
||||
(cairo_hash_entry_t **) &op))
|
||||
{
|
||||
op = _cairo_hash_table_lookup (dict, &key.base);
|
||||
if (op != NULL) {
|
||||
*size = op->operand_length;
|
||||
return op->operand_offset;
|
||||
}
|
||||
|
|
@ -660,8 +656,8 @@ cff_dict_write (cairo_hash_table_t *dict, cairo_array_t *output)
|
|||
/* The CFF specification requires that the Top Dict of CID fonts
|
||||
* begin with the ROS operator. */
|
||||
_cairo_dict_init_key (&key, ROS_OP);
|
||||
if (_cairo_hash_table_lookup (dict, &key.base,
|
||||
(cairo_hash_entry_t **) &op))
|
||||
op = _cairo_hash_table_lookup (dict, &key.base);
|
||||
if (op != NULL)
|
||||
cairo_dict_write_operator (op, &write_info);
|
||||
|
||||
_cairo_hash_table_foreach (dict, _cairo_dict_collect, &write_info);
|
||||
|
|
|
|||
|
|
@ -499,11 +499,10 @@ cairo_toy_font_face_create (const char *family,
|
|||
_cairo_toy_font_face_init_key (&key, family, slant, weight);
|
||||
|
||||
/* Return existing font_face if it exists in the hash table. */
|
||||
if (_cairo_hash_table_lookup (hash_table,
|
||||
&key.base.hash_entry,
|
||||
(cairo_hash_entry_t **) &font_face))
|
||||
{
|
||||
if (! font_face->base.status) {
|
||||
font_face = _cairo_hash_table_lookup (hash_table,
|
||||
&key.base.hash_entry);
|
||||
if (font_face != NULL) {
|
||||
if (font_face->base.status == CAIRO_STATUS_SUCCESS) {
|
||||
/* We increment the reference count here manually to avoid
|
||||
double-locking. */
|
||||
_cairo_reference_count_inc (&font_face->base.ref_count);
|
||||
|
|
|
|||
|
|
@ -422,9 +422,9 @@ _cairo_ft_unscaled_font_create_internal (cairo_bool_t from_face,
|
|||
_cairo_ft_unscaled_font_init_key (&key, from_face, filename, id, font_face);
|
||||
|
||||
/* Return existing unscaled font if it exists in the hash table. */
|
||||
if (_cairo_hash_table_lookup (font_map->hash_table, &key.base.hash_entry,
|
||||
(cairo_hash_entry_t **) &unscaled))
|
||||
{
|
||||
unscaled = _cairo_hash_table_lookup (font_map->hash_table,
|
||||
&key.base.hash_entry);
|
||||
if (unscaled != NULL) {
|
||||
_cairo_unscaled_font_reference (&unscaled->base);
|
||||
_cairo_ft_unscaled_font_map_unlock ();
|
||||
return unscaled;
|
||||
|
|
|
|||
|
|
@ -63,10 +63,9 @@ _cairo_hash_table_create (cairo_hash_keys_equal_func_t keys_equal);
|
|||
cairo_private void
|
||||
_cairo_hash_table_destroy (cairo_hash_table_t *hash_table);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
cairo_private void *
|
||||
_cairo_hash_table_lookup (cairo_hash_table_t *hash_table,
|
||||
cairo_hash_entry_t *key,
|
||||
cairo_hash_entry_t **entry_return);
|
||||
cairo_hash_entry_t *key);
|
||||
|
||||
cairo_private void *
|
||||
_cairo_hash_table_random_entry (cairo_hash_table_t *hash_table,
|
||||
|
|
@ -81,7 +80,7 @@ _cairo_hash_table_remove (cairo_hash_table_t *hash_table,
|
|||
cairo_hash_entry_t *key);
|
||||
|
||||
cairo_private void
|
||||
_cairo_hash_table_foreach (cairo_hash_table_t *hash_table,
|
||||
_cairo_hash_table_foreach (cairo_hash_table_t *hash_table,
|
||||
cairo_hash_callback_func_t hash_callback,
|
||||
void *closure);
|
||||
|
||||
|
|
|
|||
|
|
@ -52,12 +52,11 @@
|
|||
* Appears in the table as any non-%NULL, non-DEAD_ENTRY pointer.
|
||||
*/
|
||||
|
||||
static cairo_hash_entry_t dead_entry = { 0 };
|
||||
#define DEAD_ENTRY (&dead_entry)
|
||||
#define DEAD_ENTRY ((cairo_hash_entry_t *) 0x1)
|
||||
|
||||
#define ENTRY_IS_FREE(entry) ((entry) == NULL)
|
||||
#define ENTRY_IS_DEAD(entry) ((entry) == DEAD_ENTRY)
|
||||
#define ENTRY_IS_LIVE(entry) ((entry) && ! ENTRY_IS_DEAD(entry))
|
||||
#define ENTRY_IS_LIVE(entry) ((entry) > DEAD_ENTRY)
|
||||
|
||||
/* We expect keys will not be destroyed frequently, so our table does not
|
||||
* contain any explicit shrinking code nor any chain-coalescing code for
|
||||
|
|
@ -355,32 +354,25 @@ _cairo_hash_table_resize (cairo_hash_table_t *hash_table)
|
|||
* _cairo_hash_table_lookup:
|
||||
* @hash_table: a hash table
|
||||
* @key: the key of interest
|
||||
* @entry_return: pointer for return value.
|
||||
*
|
||||
* Performs a lookup in @hash_table looking for an entry which has a
|
||||
* key that matches @key, (as determined by the keys_equal() function
|
||||
* passed to _cairo_hash_table_create).
|
||||
*
|
||||
* Return value: %TRUE if there is an entry in the hash table that
|
||||
* matches the given key, (which will now be in *entry_return). %FALSE
|
||||
* otherwise, (in which case *entry_return will be %NULL).
|
||||
* Return value: the matching entry, of %NULL if no match was found.
|
||||
**/
|
||||
cairo_bool_t
|
||||
void *
|
||||
_cairo_hash_table_lookup (cairo_hash_table_t *hash_table,
|
||||
cairo_hash_entry_t *key,
|
||||
cairo_hash_entry_t **entry_return)
|
||||
cairo_hash_entry_t *key)
|
||||
{
|
||||
cairo_hash_entry_t **entry;
|
||||
|
||||
/* See if we have an entry in the table already. */
|
||||
entry = _cairo_hash_table_lookup_internal (hash_table, key, FALSE);
|
||||
if (ENTRY_IS_LIVE(*entry)) {
|
||||
*entry_return = *entry;
|
||||
return TRUE;
|
||||
}
|
||||
if (ENTRY_IS_LIVE (*entry))
|
||||
return *entry;
|
||||
|
||||
*entry_return = NULL;
|
||||
return FALSE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -717,10 +717,9 @@ _cairo_intern_string (const char **str_inout, int len)
|
|||
if (_cairo_intern_string_ht == NULL)
|
||||
_cairo_intern_string_ht = _cairo_hash_table_create (_intern_string_equal);
|
||||
|
||||
if (! _cairo_hash_table_lookup (_cairo_intern_string_ht,
|
||||
&tmpl.hash_entry,
|
||||
(cairo_hash_entry_t **) &istring))
|
||||
{
|
||||
istring = _cairo_hash_table_lookup (_cairo_intern_string_ht,
|
||||
&tmpl.hash_entry);
|
||||
if (istring == NULL) {
|
||||
istring = malloc (sizeof (cairo_intern_string_t) + len + 1);
|
||||
if (istring != NULL) {
|
||||
istring->hash_entry.hash = tmpl.hash_entry.hash;
|
||||
|
|
|
|||
|
|
@ -420,9 +420,9 @@ _cairo_sub_font_lookup_glyph (cairo_sub_font_t *sub_font,
|
|||
cairo_sub_font_glyph_t key, *sub_font_glyph;
|
||||
|
||||
_cairo_sub_font_glyph_init_key (&key, scaled_font_glyph_index);
|
||||
if (_cairo_hash_table_lookup (sub_font->sub_font_glyphs, &key.base,
|
||||
(cairo_hash_entry_t **) &sub_font_glyph))
|
||||
{
|
||||
sub_font_glyph = _cairo_hash_table_lookup (sub_font->sub_font_glyphs,
|
||||
&key.base);
|
||||
if (sub_font_glyph != NULL) {
|
||||
subset_glyph->font_id = sub_font->font_id;
|
||||
subset_glyph->subset_id = sub_font_glyph->subset_id;
|
||||
subset_glyph->subset_glyph_index = sub_font_glyph->subset_glyph_index;
|
||||
|
|
@ -450,9 +450,9 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font,
|
|||
cairo_status_t status;
|
||||
|
||||
_cairo_sub_font_glyph_init_key (&key, scaled_font_glyph_index);
|
||||
if (! _cairo_hash_table_lookup (sub_font->sub_font_glyphs, &key.base,
|
||||
(cairo_hash_entry_t **) &sub_font_glyph))
|
||||
{
|
||||
sub_font_glyph = _cairo_hash_table_lookup (sub_font->sub_font_glyphs,
|
||||
&key.base);
|
||||
if (sub_font_glyph == NULL) {
|
||||
cairo_scaled_glyph_t *scaled_glyph;
|
||||
|
||||
if (sub_font->num_glyphs_in_current_subset == sub_font->max_glyphs_per_subset)
|
||||
|
|
@ -679,9 +679,9 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets,
|
|||
if (subsets->type != CAIRO_SUBSETS_SCALED) {
|
||||
key.is_scaled = FALSE;
|
||||
_cairo_sub_font_init_key (&key, scaled_font);
|
||||
if (_cairo_hash_table_lookup (subsets->unscaled_sub_fonts, &key.base,
|
||||
(cairo_hash_entry_t **) &sub_font))
|
||||
{
|
||||
sub_font = _cairo_hash_table_lookup (subsets->unscaled_sub_fonts,
|
||||
&key.base);
|
||||
if (sub_font != NULL) {
|
||||
if (_cairo_sub_font_lookup_glyph (sub_font,
|
||||
scaled_font_glyph_index,
|
||||
utf8, utf8_len,
|
||||
|
|
@ -693,9 +693,9 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets,
|
|||
/* Lookup glyph in scaled subsets */
|
||||
key.is_scaled = TRUE;
|
||||
_cairo_sub_font_init_key (&key, scaled_font);
|
||||
if (_cairo_hash_table_lookup (subsets->scaled_sub_fonts, &key.base,
|
||||
(cairo_hash_entry_t **) &sub_font))
|
||||
{
|
||||
sub_font = _cairo_hash_table_lookup (subsets->scaled_sub_fonts,
|
||||
&key.base);
|
||||
if (sub_font != NULL) {
|
||||
if (_cairo_sub_font_lookup_glyph (sub_font,
|
||||
scaled_font_glyph_index,
|
||||
utf8, utf8_len,
|
||||
|
|
@ -732,9 +732,9 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets,
|
|||
/* Path available. Add to unscaled subset. */
|
||||
key.is_scaled = FALSE;
|
||||
_cairo_sub_font_init_key (&key, scaled_font);
|
||||
if (! _cairo_hash_table_lookup (subsets->unscaled_sub_fonts, &key.base,
|
||||
(cairo_hash_entry_t **) &sub_font))
|
||||
{
|
||||
sub_font = _cairo_hash_table_lookup (subsets->unscaled_sub_fonts,
|
||||
&key.base);
|
||||
if (sub_font == NULL) {
|
||||
font_face = cairo_scaled_font_get_font_face (scaled_font);
|
||||
cairo_matrix_init_identity (&identity);
|
||||
_cairo_font_options_init_default (&font_options);
|
||||
|
|
@ -791,9 +791,9 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets,
|
|||
/* No path available. Add to scaled subset. */
|
||||
key.is_scaled = TRUE;
|
||||
_cairo_sub_font_init_key (&key, scaled_font);
|
||||
if (! _cairo_hash_table_lookup (subsets->scaled_sub_fonts, &key.base,
|
||||
(cairo_hash_entry_t **) &sub_font))
|
||||
{
|
||||
sub_font = _cairo_hash_table_lookup (subsets->scaled_sub_fonts,
|
||||
&key.base);
|
||||
if (sub_font == NULL) {
|
||||
subset_glyph->is_scaled = TRUE;
|
||||
subset_glyph->is_composite = FALSE;
|
||||
if (subsets->type == CAIRO_SUBSETS_SCALED)
|
||||
|
|
@ -1018,14 +1018,13 @@ _cairo_scaled_font_subset_create_glyph_names (cairo_scaled_font_subset_t *subset
|
|||
}
|
||||
|
||||
if (utf16_len == 1) {
|
||||
snprintf (buf, sizeof(buf), "uni%04X", (int)(utf16[0]));
|
||||
snprintf (buf, sizeof (buf), "uni%04X", (int) utf16[0]);
|
||||
_cairo_string_init_key (&key, buf);
|
||||
if (_cairo_hash_table_lookup (names, &key.base,
|
||||
(cairo_hash_entry_t **) &entry)) {
|
||||
snprintf (buf, sizeof(buf), "g%d", i);
|
||||
}
|
||||
entry = _cairo_hash_table_lookup (names, &key.base);
|
||||
if (entry != NULL)
|
||||
snprintf (buf, sizeof (buf), "g%d", i);
|
||||
} else {
|
||||
snprintf (buf, sizeof(buf), "g%d", i);
|
||||
snprintf (buf, sizeof (buf), "g%d", i);
|
||||
}
|
||||
if (utf16)
|
||||
free (utf16);
|
||||
|
|
|
|||
|
|
@ -465,14 +465,13 @@ void
|
|||
_cairo_scaled_font_unregister_placeholder_and_lock_font_map (cairo_scaled_font_t *scaled_font)
|
||||
{
|
||||
cairo_scaled_font_t *placeholder_scaled_font;
|
||||
cairo_bool_t found;
|
||||
|
||||
CAIRO_MUTEX_LOCK (_cairo_scaled_font_map_mutex);
|
||||
|
||||
found = _cairo_hash_table_lookup (cairo_scaled_font_map->hash_table,
|
||||
&scaled_font->hash_entry,
|
||||
(cairo_hash_entry_t**) &placeholder_scaled_font);
|
||||
assert (found);
|
||||
placeholder_scaled_font =
|
||||
_cairo_hash_table_lookup (cairo_scaled_font_map->hash_table,
|
||||
&scaled_font->hash_entry);
|
||||
assert (placeholder_scaled_font != NULL);
|
||||
assert (placeholder_scaled_font->placeholder);
|
||||
assert (CAIRO_MUTEX_IS_LOCKED (placeholder_scaled_font->mutex));
|
||||
|
||||
|
|
@ -823,8 +822,8 @@ cairo_scaled_font_create (cairo_font_face_t *font_face,
|
|||
}
|
||||
else
|
||||
{
|
||||
while (_cairo_hash_table_lookup (font_map->hash_table, &key.hash_entry,
|
||||
(cairo_hash_entry_t**) &scaled_font))
|
||||
while ((scaled_font = _cairo_hash_table_lookup (font_map->hash_table,
|
||||
&key.hash_entry)))
|
||||
{
|
||||
if (! scaled_font->placeholder)
|
||||
break;
|
||||
|
|
@ -2348,9 +2347,8 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font,
|
|||
* Check cache for glyph
|
||||
*/
|
||||
info |= CAIRO_SCALED_GLYPH_INFO_METRICS;
|
||||
if (!_cairo_cache_lookup (scaled_font->glyphs, &key,
|
||||
(cairo_cache_entry_t **) &scaled_glyph))
|
||||
{
|
||||
scaled_glyph = _cairo_cache_lookup (scaled_font->glyphs, &key);
|
||||
if (scaled_glyph == NULL) {
|
||||
/*
|
||||
* On miss, create glyph and insert into cache
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue