diff --git a/src/hb-bit-set.hh b/src/hb-bit-set.hh index d4a227352..8197ebca4 100644 --- a/src/hb-bit-set.hh +++ b/src/hb-bit-set.hh @@ -47,6 +47,7 @@ struct hb_bit_set_t if (likely (!a.successful || !b.successful)) return; hb_swap (a.population, b.population); + hb_swap (a.hash_, b.hash_); hb_swap (a.last_page_lookup, b.last_page_lookup); hb_swap (a.page_map, b.page_map); hb_swap (a.pages, b.pages); @@ -56,6 +57,7 @@ struct hb_bit_set_t { successful = true; population = 0; + hash_ = 0; last_page_lookup = 0; page_map.init (); pages.init (); @@ -78,6 +80,7 @@ struct hb_bit_set_t bool successful = true; /* Allocations successful */ mutable unsigned int population = 0; + mutable unsigned int hash_ = 0; mutable unsigned int last_page_lookup = 0; hb_sorted_vector_t page_map; hb_vector_t pages; @@ -114,7 +117,10 @@ struct hb_bit_set_t { resize (0); if (likely (successful)) + { population = 0; + hash_ = 0; + } } bool is_empty () const { @@ -126,16 +132,26 @@ struct hb_bit_set_t } explicit operator bool () const { return !is_empty (); } + bool has_hash () const { return hash_ != UINT_MAX; } unsigned hash () const { + if (has_hash ()) return hash_; + unsigned h = 0; for (auto &map : page_map) h = h * 31 + hb_hash (map.major) + hb_hash (pages[map.index]); + + hash_ = h; + return h; } private: - void dirty () { population = UINT_MAX; } + void dirty () + { + population = UINT_MAX; + hash_ = UINT_MAX; + } public: void add (hb_codepoint_t g) @@ -355,6 +371,7 @@ struct hb_bit_set_t if (unlikely (!resize (count))) return; population = other.population; + hash_ = other.hash_; /* TODO switch to vector operator =. */ hb_memcpy ((void *) pages, (const void *) other.pages, count * pages.item_size); @@ -364,7 +381,10 @@ struct hb_bit_set_t bool is_equal (const hb_bit_set_t &other) const { if (has_population () && other.has_population () && - get_population () != other.get_population ()) + population != other.population) + return false; + if (has_hash () && other.has_hash () && + hash_ != other.hash_) return false; unsigned int na = pages.length; @@ -392,7 +412,7 @@ struct hb_bit_set_t bool is_subset (const hb_bit_set_t &larger_set) const { if (has_population () && larger_set.has_population () && - get_population () != larger_set.get_population ()) + population != larger_set.population) return false; uint32_t spi = 0;