h->rehash_threshold = rehash_threshold;
h->rehash_size = rehash_size;
h->count = 0;
- h->key_and_value = make_nil_vector (2 * size);
+ h->key_and_value = make_vector (2 * size, Qunbound);
h->hash = make_nil_vector (size);
h->next = make_vector (size, make_fixnum (-1));
h->index = make_vector (hash_index_size (h, size), make_fixnum (-1));
gc_aset (next, i, make_fixnum (i + 1));
gc_aset (next, next_size - 1, make_fixnum (-1));
ptrdiff_t index_size = hash_index_size (h, next_size);
+
+ /* Build the new&larger key_and_value vector, making sure the new
+ fields are initialized to `unbound`. */
Lisp_Object key_and_value
- = larger_vector (h->key_and_value, 2 * (next_size - old_size),
- 2 * next_size);
+ = larger_vecalloc (h->key_and_value, 2 * (next_size - old_size),
+ 2 * next_size);
+ for (ptrdiff_t i = ASIZE (h->key_and_value);
+ i < ASIZE (key_and_value); i++)
+ ASET (key_and_value, i, Qunbound);
+
Lisp_Object hash = larger_vector (h->hash, next_size - old_size,
next_size);
h->index = make_vector (index_size, make_fixnum (-1));
(bug#36447). */
h->next = Fcopy_sequence (h->next);
h->index = Fcopy_sequence (h->index);
- h->hash = Fcopy_sequence (h->hash);
+ h->hash = make_nil_vector (size);
/* Recompute the actual hash codes for each entry in the table.
Order is still invalid. */
for (ptrdiff_t i = 0; i < size; ++i)
- if (!NILP (HASH_HASH (h, i)))
- {
- Lisp_Object key = HASH_KEY (h, i);
- Lisp_Object hash_code = h->test.hashfn (key, h);
- set_hash_hash_slot (h, i, hash_code);
- }
+ {
+ Lisp_Object key = HASH_KEY (h, i);
+ if (!EQ (key, Qunbound))
+ set_hash_hash_slot (h, i, h->test.hashfn (key, h));
+ }
/* Reset the index so that any slot we don't fill below is marked
invalid. */
/* Finally, mark the hash table as having a valid hash order.
Do this last so that if we're interrupted, we retry on next
access. */
- eassert (h->count < 0);
+ eassert (hash_rehash_needed_p (h));
h->count = -h->count;
eassert (!hash_rehash_needed_p (h));
}
/* Store key/value in the key_and_value vector. */
i = h->next_free;
+ eassert (NILP (HASH_HASH (h, i)));
+ eassert (EQ (Qunbound, (HASH_KEY (h, i))));
h->next_free = HASH_NEXT (h, i);
set_hash_key_slot (h, i, key);
set_hash_value_slot (h, i, value);
/* Clear slots in key_and_value and add the slots to
the free list. */
- set_hash_key_slot (h, i, Qnil);
+ set_hash_key_slot (h, i, Qunbound);
set_hash_value_slot (h, i, Qnil);
set_hash_hash_slot (h, i, Qnil);
set_hash_next_slot (h, i, h->next_free);
for (i = 0; i < size; ++i)
{
set_hash_next_slot (h, i, i < size - 1 ? i + 1 : -1);
- set_hash_key_slot (h, i, Qnil);
+ set_hash_key_slot (h, i, Qunbound);
set_hash_value_slot (h, i, Qnil);
set_hash_hash_slot (h, i, Qnil);
}
if (remove_entries_p)
{
+ eassert (!remove_p
+ == (key_known_to_survive_p && value_known_to_survive_p));
if (remove_p)
{
/* Take out of collision chain. */
h->next_free = i;
/* Clear key, value, and hash. */
- set_hash_key_slot (h, i, Qnil);
+ set_hash_key_slot (h, i, Qunbound);
set_hash_value_slot (h, i, Qnil);
set_hash_hash_slot (h, i, Qnil);
struct Lisp_Hash_Table *h = check_hash_table (table);
for (ptrdiff_t i = 0; i < HASH_TABLE_SIZE (h); ++i)
- if (!NILP (HASH_HASH (h, i)))
- call2 (function, HASH_KEY (h, i), HASH_VALUE (h, i));
+ {
+ Lisp_Object k = HASH_KEY (h, i);
+ if (!EQ (k, Qunbound))
+ call2 (function, k, HASH_VALUE (h, i));
+ }
return Qnil;
}