[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:
Chris Wilson 2008-11-07 20:30:33 +00:00
parent d15fb9344b
commit 2b32c8b9e5
10 changed files with 67 additions and 88 deletions

View file

@ -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,

View file

@ -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);
}
/**

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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;
}
/**

View file

@ -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;

View file

@ -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);

View file

@ -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
*/