|
|
@ -132,9 +132,29 @@ void mp_set_init(mp_set_t *set, int n) { |
|
|
|
set->table = m_new0(mp_obj_t, set->alloc); |
|
|
|
} |
|
|
|
|
|
|
|
static void mp_set_rehash(mp_set_t *set) { |
|
|
|
int old_alloc = set->alloc; |
|
|
|
mp_obj_t *old_table = set->table; |
|
|
|
set->alloc = get_doubling_prime_greater_or_equal_to(set->alloc + 1); |
|
|
|
set->used = 0; |
|
|
|
set->table = m_new0(mp_obj_t, set->alloc); |
|
|
|
for (int i = 0; i < old_alloc; i++) { |
|
|
|
if (old_table[i] != NULL) { |
|
|
|
mp_set_lookup(set, old_table[i], true); |
|
|
|
} |
|
|
|
} |
|
|
|
m_del(mp_obj_t, old_table, old_alloc); |
|
|
|
} |
|
|
|
|
|
|
|
mp_obj_t mp_set_lookup(mp_set_t *set, mp_obj_t index, bool add_if_not_found) { |
|
|
|
int hash = mp_obj_hash(index); |
|
|
|
assert(set->alloc); /* FIXME: if alloc is ever 0 when doing a lookup, this'll fail: */ |
|
|
|
if (set->alloc == 0) { |
|
|
|
if (add_if_not_found) { |
|
|
|
mp_set_rehash(set); |
|
|
|
} else { |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
int pos = hash % set->alloc; |
|
|
|
for (;;) { |
|
|
|
mp_obj_t elem = set->table[pos]; |
|
|
@ -143,17 +163,7 @@ mp_obj_t mp_set_lookup(mp_set_t *set, mp_obj_t index, bool add_if_not_found) { |
|
|
|
if (add_if_not_found) { |
|
|
|
if (set->used + 1 >= set->alloc) { |
|
|
|
// not enough room in table, rehash it
|
|
|
|
int old_alloc = set->alloc; |
|
|
|
mp_obj_t *old_table = set->table; |
|
|
|
set->alloc = get_doubling_prime_greater_or_equal_to(set->alloc + 1); |
|
|
|
set->used = 0; |
|
|
|
set->table = m_new(mp_obj_t, set->alloc); |
|
|
|
for (int i = 0; i < old_alloc; i++) { |
|
|
|
if (old_table[i] != NULL) { |
|
|
|
mp_set_lookup(set, old_table[i], true); |
|
|
|
} |
|
|
|
} |
|
|
|
m_del(mp_obj_t, old_table, old_alloc); |
|
|
|
mp_set_rehash(set); |
|
|
|
// restart the search for the new element
|
|
|
|
pos = hash % set->alloc; |
|
|
|
} else { |
|
|
@ -173,3 +183,13 @@ mp_obj_t mp_set_lookup(mp_set_t *set, mp_obj_t index, bool add_if_not_found) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void mp_set_clear(mp_set_t *set) { |
|
|
|
set->used = 0; |
|
|
|
machine_uint_t a = set->alloc; |
|
|
|
set->alloc = 0; |
|
|
|
set->table = m_renew(mp_obj_t, set->table, a, set->alloc); |
|
|
|
for (uint i=0; i<set->alloc; i++) { |
|
|
|
set->table[i] = NULL; |
|
|
|
} |
|
|
|
} |
|
|
|