Across all benchmarks (on various sizes) this actually drops
performance by 3%. However, density increasing by 15% is probably a
worthwhile tradeoff.
```
-Initial insert: 227-237(230+/-3.7) ns
+Initial insert: 266-281(273.4+/-6.5) ns
-Initial lookup (match): 65-66(65.4+/-0.49) ns
+Initial lookup (match): 67-78(70.6+/-3.8) ns
-Initial lookup (miss): 79-80(79.4+/-0.49) ns
+Initial lookup (miss): 82-93(84.8+/-4.2) ns
-Initial lookup (random): 111-115(112.6+/-1.6) ns
+Initial lookup (random): 118-138(123.4+/-7.4) ns
-Initial delete all: 66-68(66.6+/-0.8) ns
+Initial delete all: 79-90(82+/-4.1) ns
-Initial re-inserting: 87-90(88+/-1.3) ns
+Initial re-inserting: 104-116(107.2+/-4.4) ns
-Deleting first half: 32-33(32.4+/-0.49) ns
+Deleting first half: 37-43(39+/-2.1) ns
-Lookup after half-change (match): 67-69(68+/-0.89) ns
+Lookup after half-change (match): 72-81(74.2+/-3.4) ns
-Churning second time: 272-276(274.2+/-1.5) ns
+Churning second time: 304-332(310.2+/-11) ns
-Churning third time: 290-296(293+/-2) ns
+Churning third time: 233-259(239+/-10) ns
-Churning fourth time: 289-295(292+/-2.2) ns
+Churning fourth time: 309-337(315.6+/-11) ns
-Churning fifth time: 289-294(291.8+/-1.9) ns
+Churning fifth time: 307-337(315+/-11) ns
-Details: worst run 146 (24 deleted)
+Details: worst run 115 (2 deleted)
-Lookup after churn & spread (miss): 110-111(110.6+/-0.49) ns
+Lookup after churn & spread (miss): 93-104(95.4+/-4.3) ns
-Deleting half after churn & spread: 36-37(36.4+/-0.49) ns
+Deleting half after churn & spread: 39-45(40.4+/-2.3) ns
-Adding (a different) half after churn & spread: 81-82(81.6+/-0.49) ns
+Adding (a different) half after churn & spread: 38-43(39.6+/-1.7) ns
```
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ht->table = &ht->common_bits;
}
ht->table = &ht->common_bits;
}
static inline size_t ht_max(const struct htable *ht)
{
static inline size_t ht_max(const struct htable *ht)
{
- return ((size_t)3 << ht->bits) / 4;
+ return ((size_t)7 << ht->bits) / 8;
-static inline size_t ht_max_with_deleted(const struct htable *ht)
+/* Clean deleted if we're full, and more than 12.5% deleted */
+static inline size_t ht_max_deleted(const struct htable *ht)
- return ((size_t)9 << ht->bits) / 10;
+ return ((size_t)1 << ht->bits) / 8;
}
bool htable_init_sized(struct htable *ht,
}
bool htable_init_sized(struct htable *ht,
htable_init(ht, rehash, priv);
/* Don't go insane with sizing. */
htable_init(ht, rehash, priv);
/* Don't go insane with sizing. */
- for (ht->bits = 1; ((size_t)3 << ht->bits) / 4 < expect; ht->bits++) {
+ for (ht->bits = 1; ht_max(ht) < expect; ht->bits++) {
if (ht->bits == 30)
break;
}
if (ht->bits == 30)
break;
}
assert(p);
assert(entry_is_valid((uintptr_t)p));
assert(p);
assert(entry_is_valid((uintptr_t)p));
- if (ht->elems+1 > ht_max(ht) && !double_table(ht))
- return false;
- if (ht->elems+1 + ht->deleted > ht_max_with_deleted(ht))
- rehash_table(ht);
+ /* Getting too full? */
+ if (ht->elems+1 + ht->deleted > ht_max(ht)) {
+ /* If we're more than 1/8 deleted, clean those,
+ * otherwise double table size. */
+ if (ht->deleted > ht_max_deleted(ht))
+ rehash_table(ht);
+ else if (!double_table(ht))
+ return false;
+ }
if (((uintptr_t)p & ht->common_mask) != ht->common_bits)
update_common(ht, p);
if (((uintptr_t)p & ht->common_mask) != ht->common_bits)
update_common(ht, p);