TODO | 9 --- src/hb-common.cc | 52 +++++++++----------- src/hb-mutex-private.hh | 54 +++++++++++++++++++++ src/hb-object-private.hh | 32 +++++++----- src/hb-ot-map-private.hh | 26 +++------- src/hb-ot-map.cc | 66 +++++++++++++------------- src/hb-ot-shape.cc | 2 src/hb-private.hh | 119 ++++++++++++++++++++++++++++------------------- test/test-object.c | 4 + 9 files changed, 221 insertions(+), 143 deletions(-)
New commits: commit b8d6183ebc4697a434776cf2aec7857d63a7d881 Author: Behdad Esfahbod <[email protected]> Date: Thu May 5 15:14:04 2011 -0400 Use threadsafe set implementation for hb_language lookups Note that the static variable has to be a global static, as gcc implements local statics differently and that would require linking to libstdc++, which we don't want. diff --git a/src/hb-common.cc b/src/hb-common.cc index 67988c3..368789a 100644 --- a/src/hb-common.cc +++ b/src/hb-common.cc @@ -28,6 +28,8 @@ #include "hb-private.hh" +#include "hb-mutex-private.hh" + HB_BEGIN_DECLS @@ -155,11 +157,11 @@ struct hb_language_item_t { void finish (void) { free (lang); } }; +static hb_threadsafe_set_t<hb_language_item_t> langs; + hb_language_t hb_language_from_string (const char *str) { - static hb_set_t<hb_language_item_t> langs; - if (!str || !*str) return NULL; commit d37486d87b65c5abaaa2998fa5c9e48eedde0933 Author: Behdad Esfahbod <[email protected]> Date: Thu May 5 15:07:54 2011 -0400 Add hb_threadsafe_set_t diff --git a/src/hb-mutex-private.hh b/src/hb-mutex-private.hh index cf5beb1..65e5892 100644 --- a/src/hb-mutex-private.hh +++ b/src/hb-mutex-private.hh @@ -110,4 +110,58 @@ struct hb_static_mutex_t : hb_mutex_t HB_END_DECLS + +template <typename item_t> +struct hb_threadsafe_set_t +{ + hb_set_t <item_t> set; + hb_static_mutex_t mutex; + + template <typename T> + inline item_t *insert (T v) + { + hb_mutex_lock (&mutex); + item_t *item = set.insert (v); + hb_mutex_unlock (&mutex); + return item; + } + + template <typename T> + inline void remove (T v) + { + hb_mutex_lock (&mutex); + set.remove (v); + hb_mutex_unlock (&mutex); + } + + template <typename T> + inline item_t *find (T v) + { + hb_mutex_lock (&mutex); + item_t *item = set.find (v); + hb_mutex_unlock (&mutex); + return item; + } + + template <typename T> + inline item_t *find_or_insert (T v) { + hb_mutex_lock (&mutex); + item_t *item = set.find_or_insert (v); + hb_mutex_unlock (&mutex); + return item; + } + + void finish (void) { + hb_mutex_lock (&mutex); + set.finish (); + hb_mutex_unlock (&mutex); + } + +}; + + +HB_BEGIN_DECLS + +HB_END_DECLS + #endif /* HB_MUTEX_PRIVATE_HH */ diff --git a/src/hb-private.hh b/src/hb-private.hh index d31e014..577389d 100644 --- a/src/hb-private.hh +++ b/src/hb-private.hh @@ -324,8 +324,6 @@ struct hb_set_t { hb_array_t <item_t> items; - public: - template <typename T> inline item_t *insert (T v) { @@ -370,6 +368,7 @@ struct hb_set_t void finish (void) { for (unsigned i = 0; i < items.len; i++) items[i].finish (); + items.shrink (0); } }; commit b45f32ee4e599c515ce93e44315283d236b073bb Author: Behdad Esfahbod <[email protected]> Date: Thu May 5 15:00:43 2011 -0400 Use hb_array_t for hb_language_t mapping diff --git a/src/hb-common.cc b/src/hb-common.cc index b75146d..67988c3 100644 --- a/src/hb-common.cc +++ b/src/hb-common.cc @@ -136,40 +136,36 @@ lang_hash (const void *key) #endif +struct hb_language_item_t { + + hb_language_t lang; + + inline bool operator == (const char *s) const { + return lang_equal (lang, s); + } + + inline hb_language_item_t & operator = (const char *s) { + lang = (hb_language_t) strdup (s); + for (unsigned char *p = (unsigned char *) lang; *p; p++) + *p = canon_map[*p]; + + return *this; + } + + void finish (void) { free (lang); } +}; + hb_language_t hb_language_from_string (const char *str) { - static unsigned int num_langs; - static unsigned int num_alloced; - static hb_language_t *langs; - unsigned int i; - unsigned char *p; - - /* TODO Use a hash table or something */ + static hb_set_t<hb_language_item_t> langs; if (!str || !*str) return NULL; - for (i = 0; i < num_langs; i++) - if (lang_equal (str, langs[i]->s)) - return langs[i]; - - if (unlikely (num_langs == num_alloced)) { - unsigned int new_alloced = 2 * (8 + num_alloced); - hb_language_t *new_langs = (hb_language_t *) realloc (langs, new_alloced * sizeof (langs[0])); - if (!new_langs) - return NULL; - num_alloced = new_alloced; - langs = new_langs; - } - - langs[i] = (hb_language_t) strdup (str); - for (p = (unsigned char *) langs[i]->s; *p; p++) - *p = canon_map[*p]; - - num_langs++; + hb_language_item_t *item = langs.find_or_insert (str); - return langs[i]; + return likely (item) ? item->lang : NULL; } const char * diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh index 1add2e7..dc7dba9 100644 --- a/src/hb-object-private.hh +++ b/src/hb-object-private.hh @@ -132,11 +132,11 @@ struct hb_user_data_array_t { return true; } hb_user_data_item_t item = {key, data, destroy}; - return items.insert (item); + return !!items.insert (item); } inline void *get (hb_user_data_key_t *key) { - hb_user_data_item_t *item = items.get (key); + hb_user_data_item_t *item = items.find (key); return item ? item->data : NULL; } diff --git a/src/hb-private.hh b/src/hb-private.hh index c37518d..d31e014 100644 --- a/src/hb-private.hh +++ b/src/hb-private.hh @@ -327,16 +327,16 @@ struct hb_set_t public: template <typename T> - inline bool insert (T v) + inline item_t *insert (T v) { item_t *item = items.find (v); if (item) item->finish (); else item = items.push (); - if (unlikely (!item)) return false; + if (unlikely (!item)) return NULL; *item = v; - return true; + return item; } template <typename T> @@ -351,11 +351,22 @@ struct hb_set_t } template <typename T> - inline item_t *get (T v) + inline item_t *find (T v) { return items.find (v); } + template <typename T> + inline item_t *find_or_insert (T v) { + item_t *item = find (v); + if (!item) { + item = items.push (); + if (likely (item)) + *item = v; + } + return item; + } + void finish (void) { for (unsigned i = 0; i < items.len; i++) items[i].finish (); commit 21d2c92fdf7307c7117f8948021f0dd7d5a5d2a3 Author: Behdad Esfahbod <[email protected]> Date: Thu May 5 14:47:53 2011 -0400 Move code around diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh index ffe87b4..1add2e7 100644 --- a/src/hb-object-private.hh +++ b/src/hb-object-private.hh @@ -106,20 +106,20 @@ typedef struct { /* XXX make this thread-safe, somehow! */ -struct hb_user_data_t { - hb_user_data_key_t *key; - void *data; - hb_destroy_func_t destroy; +struct hb_user_data_array_t { - inline bool operator == (hb_user_data_key_t *other_key) const { return key == other_key; } - inline bool operator == (hb_user_data_t &other) const { return key == other.key; } + struct hb_user_data_item_t { + hb_user_data_key_t *key; + void *data; + hb_destroy_func_t destroy; - void finish (void) { if (destroy) destroy (data); } -}; + inline bool operator == (hb_user_data_key_t *other_key) const { return key == other_key; } + inline bool operator == (hb_user_data_item_t &other) const { return key == other.key; } -struct hb_user_data_array_t { + void finish (void) { if (destroy) destroy (data); } + }; - hb_set_t<hb_user_data_t> items; + hb_set_t<hb_user_data_item_t> items; inline bool set (hb_user_data_key_t *key, void * data, @@ -131,13 +131,13 @@ struct hb_user_data_array_t { items.remove (key); return true; } - hb_user_data_t user_data = {key, data, destroy}; - return items.insert (user_data); + hb_user_data_item_t item = {key, data, destroy}; + return items.insert (item); } inline void *get (hb_user_data_key_t *key) { - hb_user_data_t *user_data = items.get (key); - return user_data ? user_data->data : NULL; + hb_user_data_item_t *item = items.get (key); + return item ? item->data : NULL; } void finish (void) { items.finish (); } commit 448ea9bf63104d39f87fff66219034222fa632b8 Author: Behdad Esfahbod <[email protected]> Date: Thu May 5 14:39:24 2011 -0400 [TODO] Remove done items diff --git a/TODO b/TODO index e95dd4f..1152d5e 100644 --- a/TODO +++ b/TODO @@ -7,8 +7,6 @@ General fixes: - Fix tt kern on/off and GPOS interaction -- Remove fixed-size feature/lookup arrays in hb-ot-map - API issues to fix before 1.0: ============================ @@ -52,16 +50,9 @@ hb-view enhancements: - Add XML and JSON formats -Build fixes: -=========== - -- GNOME Bug 612402 - (hb-arm) HarfBuzz compilation fix for arm - - Optimizations: ============= - Avoid allocating blob objects internally for for_data() faces? - Add caching layer to hb-ft - commit 265ac614ea6d26041c7d64739098b76a82bbc4f4 Author: Behdad Esfahbod <[email protected]> Date: Thu May 5 14:38:16 2011 -0400 Replace fixed-size lookup_maps array with hb_array_t diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh index bd4e868..2a74138 100644 --- a/src/hb-ot-map-private.hh +++ b/src/hb-ot-map-private.hh @@ -36,8 +36,6 @@ HB_BEGIN_DECLS -#define MAX_LOOKUPS 1000 /* FIXME */ - static const hb_tag_t table_tags[2] = {HB_OT_TAG_GSUB, HB_OT_TAG_GPOS}; struct hb_ot_map_t { @@ -113,12 +111,12 @@ struct hb_ot_map_t { } inline void substitute (hb_face_t *face, hb_buffer_t *buffer) const { - for (unsigned int i = 0; i < lookup_count[0]; i++) + for (unsigned int i = 0; i < lookup_maps[0].len; i++) hb_ot_layout_substitute_lookup (face, buffer, lookup_maps[0][i].index, lookup_maps[0][i].mask); } inline void position (hb_font_t *font, hb_face_t *face, hb_buffer_t *buffer) const { - for (unsigned int i = 0; i < lookup_count[1]; i++) + for (unsigned int i = 0; i < lookup_maps[1].len; i++) hb_ot_layout_position_lookup (font, buffer, lookup_maps[1][i].index, lookup_maps[1][i].mask); } @@ -126,11 +124,10 @@ struct hb_ot_map_t { hb_mask_t global_mask; - hb_prealloced_array_t<feature_info_t,16> feature_infos; /* used before compile() only */ - hb_prealloced_array_t<feature_map_t, 16> feature_maps; + hb_prealloced_array_t<feature_info_t,8> feature_infos; /* used before compile() only */ + hb_prealloced_array_t<feature_map_t, 8> feature_maps; - lookup_map_t lookup_maps[2][MAX_LOOKUPS]; /* GSUB/GPOS */ - unsigned int lookup_count[2]; + hb_prealloced_array_t<lookup_map_t, 32> lookup_maps[2]; /* GSUB/GPOS */ }; diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc index 04f41ee..9006bf9 100644 --- a/src/hb-ot-map.cc +++ b/src/hb-ot-map.cc @@ -39,23 +39,28 @@ hb_ot_map_t::add_lookups (hb_face_t *face, unsigned int feature_index, hb_mask_t mask) { - unsigned int i = MAX_LOOKUPS - lookup_count[table_index]; - lookup_map_t *lookups = lookup_maps[table_index] + lookup_count[table_index]; - - unsigned int *lookup_indices = (unsigned int *) lookups; - - hb_ot_layout_feature_get_lookup_indexes (face, - table_tags[table_index], - feature_index, - 0, &i, - lookup_indices); - - lookup_count[table_index] += i; + unsigned int lookup_indices[32]; + unsigned int offset, len; + + offset = 0; + do { + len = ARRAY_LENGTH (lookup_indices); + hb_ot_layout_feature_get_lookup_indexes (face, + table_tags[table_index], + feature_index, + offset, &len, + lookup_indices); + + for (unsigned int i = 0; i < len; i++) { + lookup_map_t *lookup = lookup_maps[table_index].push (); + if (unlikely (!lookup)) + return; + lookup->mask = mask; + lookup->index = lookup_indices[i]; + } - while (i--) { - lookups[i].mask = mask; - lookups[i].index = lookup_indices[i]; - } + offset += len; + } while (len == ARRAY_LENGTH (lookup_indices)); } @@ -64,7 +69,6 @@ hb_ot_map_t::compile (hb_face_t *face, const hb_segment_properties_t *props) { global_mask = 1; - lookup_count[0] = lookup_count[1] = 0; if (!feature_infos.len) return; @@ -176,17 +180,16 @@ hb_ot_map_t::compile (hb_face_t *face, add_lookups (face, table_index, feature_maps[i].index[table_index], feature_maps[i].mask); /* Sort lookups and merge duplicates */ - qsort (lookup_maps[table_index], lookup_count[table_index], sizeof (lookup_maps[table_index][0]), (hb_compare_func_t) lookup_map_t::cmp); - if (lookup_count[table_index]) + lookup_maps[table_index].sort (); + if (lookup_maps[table_index].len) { unsigned int j = 0; - for (unsigned int i = 1; i < lookup_count[table_index]; i++) + for (unsigned int i = 1; i < lookup_maps[table_index].len; i++) if (lookup_maps[table_index][i].index != lookup_maps[table_index][j].index) lookup_maps[table_index][++j] = lookup_maps[table_index][i]; else lookup_maps[table_index][j].mask |= lookup_maps[table_index][i].mask; - j++; - lookup_count[table_index] = j; + lookup_maps[table_index].shrink (j + 1); } } } diff --git a/src/hb-private.hh b/src/hb-private.hh index e776daf..c37518d 100644 --- a/src/hb-private.hh +++ b/src/hb-private.hh @@ -235,10 +235,8 @@ struct hb_prealloced_array_t { Type *array; Type static_array[StaticSize]; - inline Type& operator [] (unsigned int i) - { - return array[i]; - } + inline Type& operator [] (unsigned int i) { return array[i]; } + inline const Type& operator [] (unsigned int i) const { return array[i]; } inline Type *push (void) { commit 6843569d2c70c1771ce964e3d1a4cf91e14e7687 Author: Behdad Esfahbod <[email protected]> Date: Thu May 5 14:12:37 2011 -0400 Replace fixed-size feature_maps array with hb_array_t diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh index 3b0cc19..bd4e868 100644 --- a/src/hb-ot-map-private.hh +++ b/src/hb-ot-map-private.hh @@ -82,8 +82,6 @@ struct hb_ot_map_t { public: - hb_ot_map_t (void) : feature_count (0) {} - void add_feature (hb_tag_t tag, unsigned int value, bool global) { feature_info_t *info = feature_infos.push(); @@ -104,13 +102,13 @@ struct hb_ot_map_t { inline hb_mask_t get_global_mask (void) const { return global_mask; } inline hb_mask_t get_mask (hb_tag_t tag, unsigned int *shift = NULL) const { - const feature_map_t *map = (const feature_map_t *) bsearch (&tag, feature_maps, feature_count, sizeof (feature_maps[0]), (hb_compare_func_t) feature_map_t::cmp); + const feature_map_t *map = feature_maps.bsearch (&tag); if (shift) *shift = map ? map->shift : 0; return map ? map->mask : 0; } inline hb_mask_t get_1_mask (hb_tag_t tag) const { - const feature_map_t *map = (const feature_map_t *) bsearch (&tag, feature_maps, feature_count, sizeof (feature_maps[0]), (hb_compare_func_t) feature_map_t::cmp); + const feature_map_t *map = feature_maps.bsearch (&tag); return map ? map->_1_mask : 0; } @@ -128,10 +126,8 @@ struct hb_ot_map_t { hb_mask_t global_mask; - unsigned int feature_count; hb_prealloced_array_t<feature_info_t,16> feature_infos; /* used before compile() only */ -#define MAX_FEATURES 100 - feature_map_t feature_maps[MAX_FEATURES]; + hb_prealloced_array_t<feature_map_t, 16> feature_maps; lookup_map_t lookup_maps[2][MAX_LOOKUPS]; /* GSUB/GPOS */ unsigned int lookup_count[2]; diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc index d313da7..04f41ee 100644 --- a/src/hb-ot-map.cc +++ b/src/hb-ot-map.cc @@ -106,10 +106,8 @@ hb_ot_map_t::compile (hb_face_t *face, /* Allocate bits now */ - feature_count = feature_infos.len; unsigned int next_bit = 1; - j = 0; - for (unsigned int i = 0; i < feature_count; i++) { + for (unsigned int i = 0; i < feature_infos.len; i++) { const feature_info_t *info = &feature_infos[i]; unsigned int bits_needed; @@ -137,7 +135,9 @@ hb_ot_map_t::compile (hb_face_t *face, continue; - feature_map_t *map = &feature_maps[j++]; + feature_map_t *map = feature_maps.push (); + if (unlikely (!map)) + break; map->tag = info->tag; map->index[0] = feature_index[0]; @@ -156,7 +156,7 @@ hb_ot_map_t::compile (hb_face_t *face, map->_1_mask = (1 << map->shift) & map->mask; } - feature_count = j; + feature_infos.shrink (0); /* Done with these */ for (unsigned int table_index = 0; table_index < 2; table_index++) { @@ -172,7 +172,7 @@ hb_ot_map_t::compile (hb_face_t *face, &required_feature_index)) add_lookups (face, table_index, required_feature_index, 1); - for (unsigned i = 0; i < feature_count; i++) + for (unsigned i = 0; i < feature_maps.len; i++) add_lookups (face, table_index, feature_maps[i].index[table_index], feature_maps[i].mask); /* Sort lookups and merge duplicates */ diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index e01f372..306bb41 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -370,7 +370,7 @@ hb_ot_shape (hb_font_t *font, const hb_feature_t *features, unsigned int num_features) { - hb_ot_shape_plan_t plan; + hb_ot_shape_plan_t plan = hb_ot_shape_plan_t (); hb_ot_shape_plan_internal (&plan, font->face, &buffer->props, features, num_features); hb_ot_shape_execute (&plan, font, buffer, features, num_features); diff --git a/src/hb-private.hh b/src/hb-private.hh index d3edad3..e776daf 100644 --- a/src/hb-private.hh +++ b/src/hb-private.hh @@ -285,10 +285,36 @@ struct hb_prealloced_array_t { /* TODO: shrink array if needed */ } + template <typename T> + inline Type *find (T v) { + for (unsigned int i = 0; i < len; i++) + if (array[i] == v) + return &array[i]; + return NULL; + } + template <typename T> + inline const Type *find (T v) const { + for (unsigned int i = 0; i < len; i++) + if (array[i] == v) + return &array[i]; + return NULL; + } + inline void sort (void) { qsort (array, len, sizeof (Type), (hb_compare_func_t) Type::cmp); } + + template <typename T> + inline Type *bsearch (T *key) + { + return (Type *) ::bsearch (key, array, len, sizeof (Type), (hb_compare_func_t) Type::cmp); + } + template <typename T> + inline const Type *bsearch (T *key) const + { + return (const Type *) ::bsearch (key, array, len, sizeof (Type), (hb_compare_func_t) Type::cmp); + } }; template <typename Type> @@ -300,22 +326,12 @@ struct hb_set_t { hb_array_t <item_t> items; - private: - - template <typename T> - inline item_t *find (T v) { - for (unsigned int i = 0; i < items.len; i++) - if (items[i] == v) - return &items[i]; - return NULL; - } - public: template <typename T> inline bool insert (T v) { - item_t *item = find (v); + item_t *item = items.find (v); if (item) item->finish (); else @@ -328,7 +344,7 @@ struct hb_set_t template <typename T> inline void remove (T v) { - item_t *item = find (v); + item_t *item = items.find (v); if (!item) return; item->finish (); @@ -339,7 +355,7 @@ struct hb_set_t template <typename T> inline item_t *get (T v) { - return find (v); + return items.find (v); } void finish (void) { commit 44b0a4d2fc62689fc56ef57f412b4bb1e439a614 Author: Behdad Esfahbod <[email protected]> Date: Thu May 5 13:42:19 2011 -0400 Replace fixed-size feature_infos array with hb_array_t diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh index e0fe51b..3b0cc19 100644 --- a/src/hb-ot-map-private.hh +++ b/src/hb-ot-map-private.hh @@ -36,7 +36,6 @@ HB_BEGIN_DECLS -#define MAX_FEATURES 100 /* FIXME */ #define MAX_LOOKUPS 1000 /* FIXME */ static const hb_tag_t table_tags[2] = {HB_OT_TAG_GSUB, HB_OT_TAG_GPOS}; @@ -87,9 +86,10 @@ struct hb_ot_map_t { void add_feature (hb_tag_t tag, unsigned int value, bool global) { - feature_info_t *info = &feature_infos[feature_count++]; + feature_info_t *info = feature_infos.push(); + if (unlikely (!info)) return; info->tag = tag; - info->seq = feature_count; + info->seq = feature_infos.len; info->max_value = value; info->global = global; info->default_value = global ? value : 0; @@ -129,7 +129,8 @@ struct hb_ot_map_t { hb_mask_t global_mask; unsigned int feature_count; - feature_info_t feature_infos[MAX_FEATURES]; /* used before compile() only */ + hb_prealloced_array_t<feature_info_t,16> feature_infos; /* used before compile() only */ +#define MAX_FEATURES 100 feature_map_t feature_maps[MAX_FEATURES]; lookup_map_t lookup_maps[2][MAX_LOOKUPS]; /* GSUB/GPOS */ diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc index 9b15305..d313da7 100644 --- a/src/hb-ot-map.cc +++ b/src/hb-ot-map.cc @@ -66,7 +66,7 @@ hb_ot_map_t::compile (hb_face_t *face, global_mask = 1; lookup_count[0] = lookup_count[1] = 0; - if (!feature_count) + if (!feature_infos.len) return; @@ -88,9 +88,9 @@ hb_ot_map_t::compile (hb_face_t *face, /* Sort features and merge duplicates */ - qsort (feature_infos, feature_count, sizeof (feature_infos[0]), (hb_compare_func_t) feature_info_t::cmp); + feature_infos.sort (); unsigned int j = 0; - for (unsigned int i = 1; i < feature_count; i++) + for (unsigned int i = 1; i < feature_infos.len; i++) if (feature_infos[i].tag != feature_infos[j].tag) feature_infos[++j] = feature_infos[i]; else { @@ -102,10 +102,11 @@ hb_ot_map_t::compile (hb_face_t *face, /* Inherit default_value from j */ } } - feature_count = j + 1; + feature_infos.shrink (j + 1); /* Allocate bits now */ + feature_count = feature_infos.len; unsigned int next_bit = 1; j = 0; for (unsigned int i = 0; i < feature_count; i++) { diff --git a/src/hb-private.hh b/src/hb-private.hh index 26e0a69..d3edad3 100644 --- a/src/hb-private.hh +++ b/src/hb-private.hh @@ -277,6 +277,18 @@ struct hb_prealloced_array_t { len--; /* TODO: shrink array if needed */ } + + inline void shrink (unsigned int l) + { + if (l < len) + len = l; + /* TODO: shrink array if needed */ + } + + inline void sort (void) + { + qsort (array, len, sizeof (Type), (hb_compare_func_t) Type::cmp); + } }; template <typename Type> commit b214ec3ac0ce6568e9226fd09661d52de11dca96 Author: Behdad Esfahbod <[email protected]> Date: Thu May 5 13:24:07 2011 -0400 Minor diff --git a/src/hb-private.hh b/src/hb-private.hh index 28c33b7..26e0a69 100644 --- a/src/hb-private.hh +++ b/src/hb-private.hh @@ -228,7 +228,7 @@ HB_END_DECLS template <typename Type, unsigned int StaticSize> -struct hb_static_array_t { +struct hb_prealloced_array_t { unsigned int len; unsigned int allocated; @@ -280,7 +280,7 @@ struct hb_static_array_t { }; template <typename Type> -struct hb_array_t : hb_static_array_t<Type, 2> {}; +struct hb_array_t : hb_prealloced_array_t<Type, 2> {}; template <typename item_t> commit 811482bd650fb5652a9835471ae8ecf0fb185611 Author: Behdad Esfahbod <[email protected]> Date: Thu May 5 13:21:04 2011 -0400 Replace hb_map_t with hb_set_t which is more intuitive and flexible diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh index 77e0089..ffe87b4 100644 --- a/src/hb-object-private.hh +++ b/src/hb-object-private.hh @@ -106,37 +106,41 @@ typedef struct { /* XXX make this thread-safe, somehow! */ -typedef struct { +struct hb_user_data_t { + hb_user_data_key_t *key; void *data; hb_destroy_func_t destroy; + inline bool operator == (hb_user_data_key_t *other_key) const { return key == other_key; } + inline bool operator == (hb_user_data_t &other) const { return key == other.key; } + void finish (void) { if (destroy) destroy (data); } -} hb_user_data_t; +}; struct hb_user_data_array_t { - hb_map_t<hb_user_data_key_t *, hb_user_data_t> map; + hb_set_t<hb_user_data_t> items; inline bool set (hb_user_data_key_t *key, void * data, hb_destroy_func_t destroy) { + if (!key) + return false; if (!data && !destroy) { - map.unset (key); + items.remove (key); return true; } - if (!key) - return false; - hb_user_data_t user_data = {data, destroy}; - return map.set (key, user_data); + hb_user_data_t user_data = {key, data, destroy}; + return items.insert (user_data); } inline void *get (hb_user_data_key_t *key) { - hb_user_data_t *user_data = map.get (key); + hb_user_data_t *user_data = items.get (key); return user_data ? user_data->data : NULL; } - void finish (void) { map.finish (); } + void finish (void) { items.finish (); } }; diff --git a/src/hb-private.hh b/src/hb-private.hh index 9a23cd3..28c33b7 100644 --- a/src/hb-private.hh +++ b/src/hb-private.hh @@ -235,8 +235,6 @@ struct hb_static_array_t { Type *array; Type static_array[StaticSize]; - void finish (void) { for (unsigned i = 0; i < len; i++) array[i].finish (); } - inline Type& operator [] (unsigned int i) { return array[i]; @@ -285,25 +283,17 @@ template <typename Type> struct hb_array_t : hb_static_array_t<Type, 2> {}; -template <typename Key, typename Value> -struct hb_map_t +template <typename item_t> +struct hb_set_t { - struct item_t { - Key key; - /* unsigned int hash; */ - Value value; - - void finish (void) { value.finish (); } - }; - hb_array_t <item_t> items; private: template <typename T> - inline item_t *find (T key) { + inline item_t *find (T v) { for (unsigned int i = 0; i < items.len; i++) - if (items[i].key == key) + if (items[i] == v) return &items[i]; return NULL; } @@ -311,25 +301,22 @@ struct hb_map_t public: template <typename T> - inline bool set (T key, - Value &value) + inline bool insert (T v) { - item_t *item; - item = find (key); + item_t *item = find (v); if (item) item->finish (); else item = items.push (); if (unlikely (!item)) return false; - item->key = key; - item->value = value; + *item = v; return true; } - inline void unset (Key &key) + template <typename T> + inline void remove (T v) { - item_t *item; - item = find (key); + item_t *item = find (v); if (!item) return; item->finish (); @@ -338,13 +325,16 @@ struct hb_map_t } template <typename T> - inline Value *get (T key) + inline item_t *get (T v) { - item_t *item = find (key); - return item ? &item->value : NULL; + return find (v); + } + + void finish (void) { + for (unsigned i = 0; i < items.len; i++) + items[i].finish (); } - void finish (void) { items.finish (); } }; diff --git a/test/test-object.c b/test/test-object.c index 297aa29..3662d30 100644 --- a/test/test-object.c +++ b/test/test-object.c @@ -269,6 +269,10 @@ test_object (void) g_assert (o->get_user_data (obj, &key[i]) == &data[i]); for (i = 100; i < 1000; i++) g_assert (o->set_user_data (obj, &key[i], NULL, NULL)); + for (i = 2; i < 100; i++) + g_assert (o->get_user_data (obj, &key[i]) == &data[i]); + for (i = 100; i < 1000; i++) + g_assert (!o->get_user_data (obj, &key[i])); g_assert_cmpuint (global_data, ==, 900); commit 478a42536ff7ab777a7774fbfdb9c5e51334a14e Author: Behdad Esfahbod <[email protected]> Date: Thu May 5 12:39:51 2011 -0400 Make array/map implementation more generic diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh index 1f49885..77e0089 100644 --- a/src/hb-object-private.hh +++ b/src/hb-object-private.hh @@ -125,6 +125,8 @@ struct hb_user_data_array_t { map.unset (key); return true; } + if (!key) + return false; hb_user_data_t user_data = {data, destroy}; return map.set (key, user_data); } diff --git a/src/hb-private.hh b/src/hb-private.hh index 1d40d66..9a23cd3 100644 --- a/src/hb-private.hh +++ b/src/hb-private.hh @@ -300,20 +300,20 @@ struct hb_map_t private: - inline item_t *find (Key key) { - if (unlikely (!key)) return NULL; + template <typename T> + inline item_t *find (T key) { for (unsigned int i = 0; i < items.len; i++) - if (key == items[i].key) + if (items[i].key == key) return &items[i]; return NULL; } public: - inline bool set (Key key, + template <typename T> + inline bool set (T key, Value &value) { - if (unlikely (!key)) return NULL; item_t *item; item = find (key); if (item) @@ -337,7 +337,8 @@ struct hb_map_t items.pop (); } - inline Value *get (Key key) + template <typename T> + inline Value *get (T key) { item_t *item = find (key); return item ? &item->value : NULL; _______________________________________________ HarfBuzz mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/harfbuzz
