[map] Track population and occupancy separately
This commit is contained in:
parent
8a978790cb
commit
686476a8ae
|
@ -57,6 +57,7 @@ struct hb_map_t
|
||||||
hb_object_header_t header;
|
hb_object_header_t header;
|
||||||
ASSERT_POD ();
|
ASSERT_POD ();
|
||||||
bool in_error;
|
bool in_error;
|
||||||
|
unsigned int population; /* Not including tombstones. */
|
||||||
unsigned int occupancy; /* Including tombstones. */
|
unsigned int occupancy; /* Including tombstones. */
|
||||||
unsigned int mask;
|
unsigned int mask;
|
||||||
unsigned int prime;
|
unsigned int prime;
|
||||||
|
@ -65,6 +66,7 @@ struct hb_map_t
|
||||||
inline void init_shallow (void)
|
inline void init_shallow (void)
|
||||||
{
|
{
|
||||||
in_error = false;
|
in_error = false;
|
||||||
|
population = 0;
|
||||||
occupancy = 0;
|
occupancy = 0;
|
||||||
mask = 0;
|
mask = 0;
|
||||||
prime = 0;
|
prime = 0;
|
||||||
|
@ -89,7 +91,7 @@ struct hb_map_t
|
||||||
{
|
{
|
||||||
if (unlikely (in_error)) return false;
|
if (unlikely (in_error)) return false;
|
||||||
|
|
||||||
unsigned int power = _hb_bit_storage (occupancy * 2 + 8) - 1;
|
unsigned int power = _hb_bit_storage (population * 2 + 8) - 1;
|
||||||
unsigned int new_size = 1u << power;
|
unsigned int new_size = 1u << power;
|
||||||
item_t *new_items = (item_t *) malloc ((size_t) new_size * sizeof (item_t));
|
item_t *new_items = (item_t *) malloc ((size_t) new_size * sizeof (item_t));
|
||||||
if (unlikely (!new_items))
|
if (unlikely (!new_items))
|
||||||
|
@ -103,6 +105,7 @@ struct hb_map_t
|
||||||
item_t *old_items = items;
|
item_t *old_items = items;
|
||||||
|
|
||||||
/* Switch to new, empty, array. */
|
/* Switch to new, empty, array. */
|
||||||
|
population = 0;
|
||||||
occupancy = 0;
|
occupancy = 0;
|
||||||
mask = new_size - 1;
|
mask = new_size - 1;
|
||||||
prime = prime_for (power);
|
prime = prime_for (power);
|
||||||
|
@ -121,14 +124,26 @@ struct hb_map_t
|
||||||
inline void set (hb_codepoint_t key, hb_codepoint_t value)
|
inline void set (hb_codepoint_t key, hb_codepoint_t value)
|
||||||
{
|
{
|
||||||
if (unlikely (in_error)) return;
|
if (unlikely (in_error)) return;
|
||||||
|
if (unlikely (key == INVALID)) return;
|
||||||
if ((occupancy + occupancy / 2) > mask && !resize ()) return;
|
if ((occupancy + occupancy / 2) > mask && !resize ()) return;
|
||||||
unsigned int i = bucket_for (key);
|
unsigned int i = bucket_for (key);
|
||||||
if (items[i].key != key)
|
|
||||||
|
if (value == INVALID && items[i].key != key)
|
||||||
|
return; /* Trying to delete non-existent key. */
|
||||||
|
|
||||||
|
/* Accounting. */
|
||||||
|
if (items[i].is_tombstone ())
|
||||||
|
occupancy--;
|
||||||
|
else if (!items[i].is_unused ())
|
||||||
{
|
{
|
||||||
if (items[i].key == INVALID && key != INVALID)
|
population--;
|
||||||
occupancy++;
|
occupancy--;
|
||||||
items[i].key = key;
|
|
||||||
}
|
}
|
||||||
|
occupancy++;
|
||||||
|
if (value != INVALID)
|
||||||
|
population++;
|
||||||
|
|
||||||
|
items[i].key = key;
|
||||||
items[i].value = value;
|
items[i].value = value;
|
||||||
}
|
}
|
||||||
inline hb_codepoint_t get (hb_codepoint_t key) const
|
inline hb_codepoint_t get (hb_codepoint_t key) const
|
||||||
|
@ -141,10 +156,7 @@ struct hb_map_t
|
||||||
|
|
||||||
inline void del (hb_codepoint_t key)
|
inline void del (hb_codepoint_t key)
|
||||||
{
|
{
|
||||||
if (unlikely (in_error)) return;
|
set (key, INVALID);
|
||||||
if (unlikely (!items)) return;
|
|
||||||
unsigned int i = bucket_for (key);
|
|
||||||
items[i].value = INVALID;
|
|
||||||
}
|
}
|
||||||
inline bool has (hb_codepoint_t key) const
|
inline bool has (hb_codepoint_t key) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -53,6 +53,7 @@ hb_map_create (void)
|
||||||
static const hb_map_t _hb_map_nil = {
|
static const hb_map_t _hb_map_nil = {
|
||||||
HB_OBJECT_HEADER_STATIC,
|
HB_OBJECT_HEADER_STATIC,
|
||||||
true, /* in_error */
|
true, /* in_error */
|
||||||
|
0, /* population */
|
||||||
0, /* occupancy */
|
0, /* occupancy */
|
||||||
0, /* mask */
|
0, /* mask */
|
||||||
0, /* prime */
|
0, /* prime */
|
||||||
|
|
Loading…
Reference in New Issue