Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/cranelift/bforest/src/set.rs
1692 views
1
//! Forest of sets.
2
3
use super::{Comparator, Forest, INNER_SIZE, Node, NodeData, NodePool, Path, SetValue};
4
use crate::packed_option::PackedOption;
5
#[cfg(test)]
6
use alloc::string::String;
7
#[cfg(test)]
8
use core::fmt;
9
use core::marker::PhantomData;
10
11
/// Tag type defining forest types for a set.
12
struct SetTypes<K>(PhantomData<K>);
13
14
impl<K> Forest for SetTypes<K>
15
where
16
K: Copy,
17
{
18
type Key = K;
19
type Value = SetValue;
20
type LeafKeys = [K; 2 * INNER_SIZE - 1];
21
type LeafValues = [SetValue; 2 * INNER_SIZE - 1];
22
23
fn splat_key(key: Self::Key) -> Self::LeafKeys {
24
[key; 2 * INNER_SIZE - 1]
25
}
26
27
fn splat_value(value: Self::Value) -> Self::LeafValues {
28
[value; 2 * INNER_SIZE - 1]
29
}
30
}
31
32
/// Memory pool for a forest of `Set` instances.
33
pub struct SetForest<K>
34
where
35
K: Copy,
36
{
37
nodes: NodePool<SetTypes<K>>,
38
}
39
40
impl<K> SetForest<K>
41
where
42
K: Copy,
43
{
44
/// Create a new empty forest.
45
pub fn new() -> Self {
46
Self {
47
nodes: NodePool::new(),
48
}
49
}
50
51
/// Clear all sets in the forest.
52
///
53
/// All `Set` instances belong to this forest are invalidated and should no longer be used.
54
pub fn clear(&mut self) {
55
self.nodes.clear();
56
}
57
}
58
59
/// B-tree representing an ordered set of `K`s using `C` for comparing elements.
60
///
61
/// This is not a general-purpose replacement for `BTreeSet`. See the [module
62
/// documentation](index.html) for more information about design tradeoffs.
63
///
64
/// Sets can be cloned, but that operation should only be used as part of cloning the whole forest
65
/// they belong to. *Cloning a set does not allocate new memory for the clone*. It creates an alias
66
/// of the same memory.
67
#[derive(Clone)]
68
pub struct Set<K>
69
where
70
K: Copy,
71
{
72
root: PackedOption<Node>,
73
unused: PhantomData<K>,
74
}
75
76
impl<K> Set<K>
77
where
78
K: Copy,
79
{
80
/// Make an empty set.
81
pub fn new() -> Self {
82
Self {
83
root: None.into(),
84
unused: PhantomData,
85
}
86
}
87
88
/// Is this an empty set?
89
pub fn is_empty(&self) -> bool {
90
self.root.is_none()
91
}
92
93
/// Does the set contain `key`?.
94
pub fn contains<C: Comparator<K>>(&self, key: K, forest: &SetForest<K>, comp: &C) -> bool {
95
self.root
96
.expand()
97
.and_then(|root| Path::default().find(key, root, &forest.nodes, comp))
98
.is_some()
99
}
100
101
/// Try to insert `key` into the set.
102
///
103
/// If the set did not contain `key`, insert it and return true.
104
///
105
/// If `key` is already present, don't change the set and return false.
106
pub fn insert<C: Comparator<K>>(
107
&mut self,
108
key: K,
109
forest: &mut SetForest<K>,
110
comp: &C,
111
) -> bool {
112
self.cursor(forest, comp).insert(key)
113
}
114
115
/// Remove `key` from the set and return true.
116
///
117
/// If `key` was not present in the set, return false.
118
pub fn remove<C: Comparator<K>>(
119
&mut self,
120
key: K,
121
forest: &mut SetForest<K>,
122
comp: &C,
123
) -> bool {
124
let mut c = self.cursor(forest, comp);
125
if c.goto(key) {
126
c.remove();
127
true
128
} else {
129
false
130
}
131
}
132
133
/// Remove all entries.
134
pub fn clear(&mut self, forest: &mut SetForest<K>) {
135
if let Some(root) = self.root.take() {
136
forest.nodes.free_tree(root);
137
}
138
}
139
140
/// Retains only the elements specified by the predicate.
141
///
142
/// Remove all elements where the predicate returns false.
143
pub fn retain<F>(&mut self, forest: &mut SetForest<K>, mut predicate: F)
144
where
145
F: FnMut(K) -> bool,
146
{
147
let mut path = Path::default();
148
if let Some(root) = self.root.expand() {
149
path.first(root, &forest.nodes);
150
}
151
while let Some((node, entry)) = path.leaf_pos() {
152
if predicate(forest.nodes[node].unwrap_leaf().0[entry]) {
153
path.next(&forest.nodes);
154
} else {
155
self.root = path.remove(&mut forest.nodes).into();
156
}
157
}
158
}
159
160
/// Create a cursor for navigating this set. The cursor is initially positioned off the end of
161
/// the set.
162
pub fn cursor<'a, C: Comparator<K>>(
163
&'a mut self,
164
forest: &'a mut SetForest<K>,
165
comp: &'a C,
166
) -> SetCursor<'a, K, C> {
167
SetCursor::new(self, forest, comp)
168
}
169
170
/// Create an iterator traversing this set. The iterator type is `K`.
171
pub fn iter<'a>(&'a self, forest: &'a SetForest<K>) -> SetIter<'a, K> {
172
SetIter {
173
root: self.root,
174
pool: &forest.nodes,
175
path: Path::default(),
176
}
177
}
178
}
179
180
impl<K> Default for Set<K>
181
where
182
K: Copy,
183
{
184
fn default() -> Self {
185
Self::new()
186
}
187
}
188
189
/// A position in a `Set` used to navigate and modify the ordered set.
190
///
191
/// A cursor always points at an element in the set, or "off the end" which is a position after the
192
/// last element in the set.
193
pub struct SetCursor<'a, K, C>
194
where
195
K: 'a + Copy,
196
C: 'a + Comparator<K>,
197
{
198
root: &'a mut PackedOption<Node>,
199
pool: &'a mut NodePool<SetTypes<K>>,
200
comp: &'a C,
201
path: Path<SetTypes<K>>,
202
}
203
204
impl<'a, K, C> SetCursor<'a, K, C>
205
where
206
K: Copy,
207
C: Comparator<K>,
208
{
209
/// Create a cursor with a default (invalid) location.
210
fn new(container: &'a mut Set<K>, forest: &'a mut SetForest<K>, comp: &'a C) -> Self {
211
Self {
212
root: &mut container.root,
213
pool: &mut forest.nodes,
214
comp,
215
path: Path::default(),
216
}
217
}
218
219
/// Is this cursor pointing to an empty set?
220
pub fn is_empty(&self) -> bool {
221
self.root.is_none()
222
}
223
224
/// Move cursor to the next element and return it.
225
///
226
/// If the cursor reaches the end, return `None` and leave the cursor at the off-the-end
227
/// position.
228
pub fn next(&mut self) -> Option<K> {
229
self.path.next(self.pool).map(|(k, _)| k)
230
}
231
232
/// Move cursor to the previous element and return it.
233
///
234
/// If the cursor is already pointing at the first element, leave it there and return `None`.
235
pub fn prev(&mut self) -> Option<K> {
236
self.root
237
.expand()
238
.and_then(|root| self.path.prev(root, self.pool).map(|(k, _)| k))
239
}
240
241
/// Get the current element, or `None` if the cursor is at the end.
242
pub fn elem(&self) -> Option<K> {
243
self.path
244
.leaf_pos()
245
.and_then(|(node, entry)| self.pool[node].unwrap_leaf().0.get(entry).cloned())
246
}
247
248
/// Move this cursor to `elem`.
249
///
250
/// If `elem` is in the set, place the cursor at `elem` and return true.
251
///
252
/// If `elem` is not in the set, place the cursor at the next larger element (or the end) and
253
/// return false.
254
pub fn goto(&mut self, elem: K) -> bool {
255
match self.root.expand() {
256
None => false,
257
Some(root) => {
258
if self.path.find(elem, root, self.pool, self.comp).is_some() {
259
true
260
} else {
261
self.path.normalize(self.pool);
262
false
263
}
264
}
265
}
266
}
267
268
/// Move this cursor to the first element.
269
pub fn goto_first(&mut self) -> Option<K> {
270
self.root.map(|root| self.path.first(root, self.pool).0)
271
}
272
273
/// Try to insert `elem` into the set and leave the cursor at the inserted element.
274
///
275
/// If the set did not contain `elem`, insert it and return true.
276
///
277
/// If `elem` is already present, don't change the set, place the cursor at `goto(elem)`, and
278
/// return false.
279
pub fn insert(&mut self, elem: K) -> bool {
280
match self.root.expand() {
281
None => {
282
let root = self.pool.alloc_node(NodeData::leaf(elem, SetValue()));
283
*self.root = root.into();
284
self.path.set_root_node(root);
285
true
286
}
287
Some(root) => {
288
// TODO: Optimize the case where `self.path` is already at the correct insert pos.
289
if self.path.find(elem, root, self.pool, self.comp).is_none() {
290
*self.root = self.path.insert(elem, SetValue(), self.pool).into();
291
true
292
} else {
293
false
294
}
295
}
296
}
297
}
298
299
/// Remove the current element (if any) and return it.
300
/// This advances the cursor to the next element after the removed one.
301
pub fn remove(&mut self) -> Option<K> {
302
let elem = self.elem();
303
if elem.is_some() {
304
*self.root = self.path.remove(self.pool).into();
305
}
306
elem
307
}
308
}
309
310
#[cfg(test)]
311
impl<'a, K, C> SetCursor<'a, K, C>
312
where
313
K: Copy + fmt::Display,
314
C: Comparator<K>,
315
{
316
fn verify(&self) {
317
self.path.verify(self.pool);
318
self.root.map(|root| self.pool.verify_tree(root, self.comp));
319
}
320
321
/// Get a text version of the path to the current position.
322
fn tpath(&self) -> String {
323
use alloc::string::ToString;
324
self.path.to_string()
325
}
326
}
327
328
/// An iterator visiting the elements of a `Set`.
329
pub struct SetIter<'a, K>
330
where
331
K: 'a + Copy,
332
{
333
root: PackedOption<Node>,
334
pool: &'a NodePool<SetTypes<K>>,
335
path: Path<SetTypes<K>>,
336
}
337
338
impl<'a, K> Iterator for SetIter<'a, K>
339
where
340
K: 'a + Copy,
341
{
342
type Item = K;
343
344
fn next(&mut self) -> Option<Self::Item> {
345
// We use `self.root` to indicate if we need to go to the first element. Reset to `None`
346
// once we've returned the first element. This also works for an empty tree since the
347
// `path.next()` call returns `None` when the path is empty. This also fuses the iterator.
348
match self.root.take() {
349
Some(root) => Some(self.path.first(root, self.pool).0),
350
None => self.path.next(self.pool).map(|(k, _)| k),
351
}
352
}
353
}
354
355
#[cfg(test)]
356
mod tests {
357
use super::*;
358
use alloc::vec::Vec;
359
use core::mem;
360
361
#[test]
362
fn node_size() {
363
// check that nodes are cache line sized when keys are 32 bits.
364
type F = SetTypes<u32>;
365
assert_eq!(mem::size_of::<NodeData<F>>(), 64);
366
}
367
368
#[test]
369
fn empty() {
370
let mut f = SetForest::<u32>::new();
371
f.clear();
372
373
let mut s = Set::<u32>::new();
374
assert!(s.is_empty());
375
s.clear(&mut f);
376
assert!(!s.contains(7, &f, &()));
377
378
// Iterator for an empty set.
379
assert_eq!(s.iter(&f).next(), None);
380
381
s.retain(&mut f, |_| unreachable!());
382
383
let mut c = SetCursor::new(&mut s, &mut f, &());
384
c.verify();
385
assert_eq!(c.elem(), None);
386
387
assert_eq!(c.goto_first(), None);
388
assert_eq!(c.tpath(), "<empty path>");
389
}
390
391
#[test]
392
fn simple_cursor() {
393
let mut f = SetForest::<u32>::new();
394
let mut s = Set::<u32>::new();
395
let mut c = SetCursor::new(&mut s, &mut f, &());
396
397
assert!(c.insert(50));
398
c.verify();
399
assert_eq!(c.elem(), Some(50));
400
401
assert!(c.insert(100));
402
c.verify();
403
assert_eq!(c.elem(), Some(100));
404
405
assert!(c.insert(10));
406
c.verify();
407
assert_eq!(c.elem(), Some(10));
408
409
// Basic movement.
410
assert_eq!(c.next(), Some(50));
411
assert_eq!(c.next(), Some(100));
412
assert_eq!(c.next(), None);
413
assert_eq!(c.next(), None);
414
assert_eq!(c.prev(), Some(100));
415
assert_eq!(c.prev(), Some(50));
416
assert_eq!(c.prev(), Some(10));
417
assert_eq!(c.prev(), None);
418
assert_eq!(c.prev(), None);
419
420
assert!(c.goto(50));
421
assert_eq!(c.elem(), Some(50));
422
assert_eq!(c.remove(), Some(50));
423
c.verify();
424
425
assert_eq!(c.elem(), Some(100));
426
assert_eq!(c.remove(), Some(100));
427
c.verify();
428
assert_eq!(c.elem(), None);
429
assert_eq!(c.remove(), None);
430
c.verify();
431
}
432
433
#[test]
434
fn two_level_sparse_tree() {
435
let mut f = SetForest::<u32>::new();
436
let mut s = Set::<u32>::new();
437
let mut c = SetCursor::new(&mut s, &mut f, &());
438
439
// Insert enough elements that we get a two-level tree.
440
// Each leaf node holds 8 elements
441
assert!(c.is_empty());
442
for i in 0..50 {
443
assert!(c.insert(i));
444
assert_eq!(c.elem(), Some(i));
445
}
446
assert!(!c.is_empty());
447
448
assert_eq!(c.goto_first(), Some(0));
449
assert_eq!(c.tpath(), "node2[0]--node0[0]");
450
451
assert_eq!(c.prev(), None);
452
for i in 1..50 {
453
assert_eq!(c.next(), Some(i));
454
}
455
assert_eq!(c.next(), None);
456
for i in (0..50).rev() {
457
assert_eq!(c.prev(), Some(i));
458
}
459
assert_eq!(c.prev(), None);
460
461
assert!(c.goto(25));
462
for i in 25..50 {
463
assert_eq!(c.remove(), Some(i));
464
assert!(!c.is_empty());
465
c.verify();
466
}
467
468
for i in (0..25).rev() {
469
assert!(!c.is_empty());
470
assert_eq!(c.elem(), None);
471
assert_eq!(c.prev(), Some(i));
472
assert_eq!(c.remove(), Some(i));
473
c.verify();
474
}
475
assert_eq!(c.elem(), None);
476
assert!(c.is_empty());
477
}
478
479
#[test]
480
fn three_level_sparse_tree() {
481
let mut f = SetForest::<u32>::new();
482
let mut s = Set::<u32>::new();
483
let mut c = SetCursor::new(&mut s, &mut f, &());
484
485
// Insert enough elements that we get a 3-level tree.
486
// Each leaf node holds 8 elements when filled up sequentially.
487
// Inner nodes hold 8 node pointers.
488
assert!(c.is_empty());
489
for i in 0..150 {
490
assert!(c.insert(i));
491
assert_eq!(c.elem(), Some(i));
492
}
493
assert!(!c.is_empty());
494
495
assert!(c.goto(0));
496
assert_eq!(c.tpath(), "node11[0]--node2[0]--node0[0]");
497
498
assert_eq!(c.prev(), None);
499
for i in 1..150 {
500
assert_eq!(c.next(), Some(i));
501
}
502
assert_eq!(c.next(), None);
503
for i in (0..150).rev() {
504
assert_eq!(c.prev(), Some(i));
505
}
506
assert_eq!(c.prev(), None);
507
508
assert!(c.goto(125));
509
for i in 125..150 {
510
assert_eq!(c.remove(), Some(i));
511
assert!(!c.is_empty());
512
c.verify();
513
}
514
515
for i in (0..125).rev() {
516
assert!(!c.is_empty());
517
assert_eq!(c.elem(), None);
518
assert_eq!(c.prev(), Some(i));
519
assert_eq!(c.remove(), Some(i));
520
c.verify();
521
}
522
assert_eq!(c.elem(), None);
523
assert!(c.is_empty());
524
}
525
526
// Generate a densely populated 4-level tree.
527
//
528
// Level 1: 1 root
529
// Level 2: 8 inner
530
// Level 3: 64 inner
531
// Level 4: 512 leafs, up to 7680 elements
532
//
533
// A 3-level tree can hold at most 960 elements.
534
fn dense4l(f: &mut SetForest<i32>) -> Set<i32> {
535
f.clear();
536
let mut s = Set::new();
537
538
// Insert 400 elements in 7 passes over the range to avoid the half-full leaf node pattern
539
// that comes from sequential insertion. This will generate a normal leaf layer.
540
for n in 0..4000 {
541
assert!(s.insert((n * 7) % 4000, f, &()));
542
}
543
s
544
}
545
546
#[test]
547
fn four_level() {
548
let mut f = SetForest::<i32>::new();
549
let mut s = dense4l(&mut f);
550
551
assert_eq!(
552
s.iter(&f).collect::<Vec<_>>()[0..10],
553
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
554
);
555
556
let mut c = s.cursor(&mut f, &());
557
558
c.verify();
559
560
// Peel off a whole sub-tree of the root by deleting from the front.
561
// The 900 element is near the front of the second sub-tree.
562
assert!(c.goto(900));
563
assert_eq!(c.tpath(), "node48[1]--node47[0]--node26[0]--node20[4]");
564
assert!(c.goto(0));
565
for i in 0..900 {
566
assert!(!c.is_empty());
567
assert_eq!(c.remove(), Some(i));
568
}
569
c.verify();
570
assert_eq!(c.elem(), Some(900));
571
572
// Delete backwards from somewhere in the middle.
573
assert!(c.goto(3000));
574
for i in (2000..3000).rev() {
575
assert_eq!(c.prev(), Some(i));
576
assert_eq!(c.remove(), Some(i));
577
assert_eq!(c.elem(), Some(3000));
578
}
579
c.verify();
580
581
// Remove everything in a scattered manner, triggering many collapsing patterns.
582
for i in 0..4000 {
583
if c.goto((i * 7) % 4000) {
584
c.remove();
585
}
586
}
587
assert!(c.is_empty());
588
}
589
590
#[test]
591
fn four_level_clear() {
592
let mut f = SetForest::<i32>::new();
593
let mut s = dense4l(&mut f);
594
s.clear(&mut f);
595
}
596
}
597
598