• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

jneem / imbl / 9651244952

24 Jun 2024 07:26PM UTC coverage: 84.143% (-0.1%) from 84.245%
9651244952

Pull #81

github

web-flow
Merge 79f1aceca into 38699a7b7
Pull Request #81: Update proptest-derive requirement from 0.4 to 0.5

5784 of 6874 relevant lines covered (84.14%)

6592875.25 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.73
/src/vector/focus.rs
1
// This Source Code Form is subject to the terms of the Mozilla Public
2
// License, v. 2.0. If a copy of the MPL was not distributed with this
3
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4

5
use std::mem::{replace, swap};
6
use std::ops::{Range, RangeBounds};
7
use std::ptr::null;
8
use std::sync::atomic::{AtomicPtr, Ordering};
9

10
use crate::nodes::chunk::Chunk;
11
use crate::sync::Lock;
12
use crate::util::{to_range, PoolRef, Ref};
13
use crate::vector::{
14
    Iter, IterMut, RRBPool, Vector,
15
    VectorInner::{Full, Inline, Single},
16
    RRB,
17
};
18

19
/// Focused indexing over a [`Vector`][Vector].
20
///
21
/// By remembering the last tree node accessed through an index lookup and the
22
/// path we took to get there, we can speed up lookups for adjacent indices
23
/// tremendously. Lookups on indices in the same node are instantaneous, and
24
/// lookups on sibling nodes are also very fast.
25
///
26
/// A `Focus` can also be used as a restricted view into a vector, using the
27
/// [`narrow`][narrow] and [`split_at`][split_at] methods.
28
///
29
/// # When should I use a `Focus` for better performance?
30
///
31
/// `Focus` is useful when you need to perform a large number of index lookups
32
/// that are more likely than not to be close to each other. It's usually worth
33
/// using a `Focus` in any situation where you're batching a lot of index
34
/// lookups together, even if they're not obviously adjacent - there's likely
35
/// to be some performance gain for even completely random access.
36
///
37
/// If you're just iterating forwards or backwards over the [`Vector`][Vector]
38
/// in order, you're better off with a regular iterator, which, in fact, is
39
/// implemented using a `Focus`, but provides a simpler interface.
40
///
41
/// If you're just doing a very small number of index lookups, the setup cost
42
/// for the `Focus` is probably not worth it.
43
///
44
/// A `Focus` is never faster than an index lookup on a small [`Vector`][Vector]
45
/// with a length below the internal RRB tree's branching factor of 64.
46
///
47
/// # Examples
48
///
49
/// This example is contrived, as the better way to iterate forwards or
50
/// backwards over a vector is with an actual iterator. Even so, the version
51
/// using a `Focus` should run nearly an order of magnitude faster than the
52
/// version using index lookups at a length of 1000. It should also be noted
53
/// that [`vector::Iter`][Iter] is actually implemented using a `Focus` behind
54
/// the scenes, so the performance of the two should be identical.
55
///
56
/// ```rust
57
/// # #[macro_use] extern crate imbl;
58
/// # use imbl::vector::Vector;
59
/// # use std::iter::FromIterator;
60
/// let mut vec: Vector<i64> = Vector::from_iter(0..1000);
61
///
62
/// // Summing a vector, the slow way:
63
/// let mut sum = 0;
64
/// for i in 0..1000 {
65
///     sum += *vec.get(i).unwrap();
66
/// }
67
/// assert_eq!(499500, sum);
68
///
69
/// // Summing a vector faster using a Focus:
70
/// let mut sum = 0;
71
/// let mut focus = vec.focus();
72
/// for i in 0..1000 {
73
///     sum += *focus.get(i).unwrap();
74
/// }
75
/// assert_eq!(499500, sum);
76
///
77
/// // And the easy way, for completeness:
78
/// let sum: i64 = vec.iter().sum();
79
/// assert_eq!(499500, sum);
80
/// ```
81
///
82
/// [Vector]: enum.Vector.html
83
/// [Iter]: struct.Iter.html
84
/// [narrow]: #method.narrow
85
/// [split_at]: #method.split_at
86
pub enum Focus<'a, A> {
87
    #[doc(hidden)]
88
    /// The Single variant is a focus of a simple Vector that can be represented as a single slice.
89
    Single(&'a [A]),
90
    #[doc(hidden)]
91
    /// The Full variant is a focus of a more complex Vector that cannot be represented as a single slice.
92
    Full(TreeFocus<A>),
93
}
94

95
impl<'a, A> Focus<'a, A>
96
where
97
    A: 'a,
98
{
99
    /// Construct a `Focus` for a [`Vector`][Vector].
100
    ///
101
    /// [Vector]: enum.Vector.html
102
    pub fn new(vector: &'a Vector<A>) -> Self {
75,599✔
103
        match &vector.vector {
75,599✔
104
            Inline(_, chunk) => Focus::Single(chunk),
13,081✔
105
            Single(_, chunk) => Focus::Single(chunk),
6,268✔
106
            Full(_, tree) => Focus::Full(TreeFocus::new(tree)),
56,250✔
107
        }
108
    }
75,599✔
109

110
    /// Get the length of the focused [`Vector`][Vector].
111
    ///
112
    /// [Vector]: enum.Vector.html
113
    pub fn len(&self) -> usize {
744,786✔
114
        match self {
744,786✔
115
            Focus::Single(chunk) => chunk.len(),
12✔
116
            Focus::Full(tree) => tree.len(),
744,774✔
117
        }
118
    }
744,786✔
119

120
    /// Test if the focused [`Vector`][Vector] is empty.
121
    ///
122
    /// [Vector]: enum.Vector.html
123
    pub fn is_empty(&self) -> bool {
124
        self.len() == 0
125
    }
126

127
    /// Get a reference to the value at a given index.
128
    pub fn get(&mut self, index: usize) -> Option<&A> {
58,805,593✔
129
        match self {
58,805,593✔
130
            Focus::Single(chunk) => chunk.get(index),
276,561✔
131
            Focus::Full(tree) => tree.get(index),
58,529,032✔
132
        }
133
    }
58,805,593✔
134

135
    /// Get a reference to the value at a given index.
136
    ///
137
    /// Panics if the index is out of bounds.
138
    pub fn index(&mut self, index: usize) -> &A {
200,000✔
139
        self.get(index).expect("index out of bounds")
200,000✔
140
    }
200,000✔
141

142
    /// Get the chunk for the given index.
143
    ///
144
    /// This gives you a reference to the leaf node that contains the index,
145
    /// along with its start and end indices.
146
    pub fn chunk_at(&mut self, index: usize) -> (Range<usize>, &[A]) {
648,064✔
147
        let len = self.len();
648,064✔
148
        if index >= len {
648,064✔
149
            panic!("vector::Focus::chunk_at: index out of bounds");
×
150
        }
151
        match self {
648,064✔
152
            Focus::Single(chunk) => (0..len, chunk),
12✔
153
            Focus::Full(tree) => tree.get_chunk(index),
648,052✔
154
        }
155
    }
648,064✔
156

157
    /// Narrow the focus onto a subslice of the vector.
158
    ///
159
    /// `Focus::narrow(range)` has the same effect as `&slice[range]`, without
160
    /// actually modifying the underlying vector.
161
    ///
162
    /// Panics if the range isn't fully inside the current focus.
163
    ///
164
    /// ## Examples
165
    ///
166
    /// ```rust
167
    /// # #[macro_use] extern crate imbl;
168
    /// # use imbl::vector::Vector;
169
    /// # use std::iter::FromIterator;
170
    /// let vec = Vector::from_iter(0..1000);
171
    /// let narrowed = vec.focus().narrow(100..200);
172
    /// let narrowed_vec = narrowed.into_iter().cloned().collect();
173
    /// assert_eq!(Vector::from_iter(100..200), narrowed_vec);
174
    /// ```
175
    ///
176
    /// [slice::split_at]: https://doc.rust-lang.org/std/primitive.slice.html#method.split_at
177
    /// [Vector::split_at]: enum.Vector.html#method.split_at
178
    #[must_use]
179
    pub fn narrow<R>(self, range: R) -> Self
180
    where
181
        R: RangeBounds<usize>,
182
    {
183
        let r = to_range(&range, self.len());
184
        if r.start >= r.end || r.start >= self.len() {
185
            panic!("vector::Focus::narrow: range out of bounds");
186
        }
187
        match self {
188
            Focus::Single(chunk) => Focus::Single(&chunk[r]),
189
            Focus::Full(tree) => Focus::Full(tree.narrow(r)),
190
        }
191
    }
192

193
    /// Split the focus into two.
194
    ///
195
    /// Given an index `index`, consume the focus and produce two new foci, the
196
    /// left onto indices `0..index`, and the right onto indices `index..N`
197
    /// where `N` is the length of the current focus.
198
    ///
199
    /// Panics if the index is out of bounds.
200
    ///
201
    /// This is the moral equivalent of [`slice::split_at`][slice::split_at], in
202
    /// that it leaves the underlying data structure unchanged, unlike
203
    /// [`Vector::split_at`][Vector::split_at].
204
    ///
205
    /// ## Examples
206
    ///
207
    /// ```rust
208
    /// # #[macro_use] extern crate imbl;
209
    /// # use imbl::vector::Vector;
210
    /// # use std::iter::FromIterator;
211
    /// let vec = Vector::from_iter(0..1000);
212
    /// let (left, right) = vec.focus().split_at(500);
213
    /// let left_vec = left.into_iter().cloned().collect();
214
    /// let right_vec = right.into_iter().cloned().collect();
215
    /// assert_eq!(Vector::from_iter(0..500), left_vec);
216
    /// assert_eq!(Vector::from_iter(500..1000), right_vec);
217
    /// ```
218
    ///
219
    /// [slice::split_at]: https://doc.rust-lang.org/std/primitive.slice.html#method.split_at
220
    /// [Vector::split_at]: enum.Vector.html#method.split_at
221
    pub fn split_at(self, index: usize) -> (Self, Self) {
47,917✔
222
        if index >= self.len() {
47,917✔
223
            panic!("vector::Focus::split_at: index out of bounds");
×
224
        }
225
        match self {
47,917✔
226
            Focus::Single(chunk) => {
×
227
                let (left, right) = chunk.split_at(index);
×
228
                (Focus::Single(left), Focus::Single(right))
×
229
            }
×
230
            Focus::Full(tree) => {
47,917✔
231
                let (left, right) = tree.split_at(index);
47,917✔
232
                (Focus::Full(left), Focus::Full(right))
47,917✔
233
            }
47,917✔
234
        }
235
    }
47,917✔
236
}
237

238
impl<'a, A> IntoIterator for Focus<'a, A>
239
where
240
    A: Clone + 'a,
241
{
242
    type Item = &'a A;
243
    type IntoIter = Iter<'a, A>;
244

245
    fn into_iter(self) -> Self::IntoIter {
48,526✔
246
        Iter::from_focus(self)
48,526✔
247
    }
48,526✔
248
}
249

250
impl<'a, A> Clone for Focus<'a, A>
251
where
252
    A: Clone + 'a,
253
{
254
    fn clone(&self) -> Self {
255
        match self {
256
            Focus::Single(chunk) => Focus::Single(chunk),
257
            Focus::Full(tree) => Focus::Full(tree.clone()),
258
        }
259
    }
260
}
261

262
pub struct TreeFocus<A> {
263
    /// A clone of the Vector's internal tree that this focus points to. A clone ensures that we don't require a
264
    /// reference to the original tree.
265
    tree: RRB<A>,
266
    /// The view represents the range of the tree that this TreeFocus can see. The view can be narrowed by calling
267
    /// either the narrow or split_at methods.
268
    view: Range<usize>,
269
    /// The tree version of the Vector is represented as the concatenation of 2 chunks, followed by the tree root,
270
    /// followed by 2 chunks. The middle_range refers to the range of the Vector that the tree covers.
271
    middle_range: Range<usize>,
272
    /// This implementation of a focus stores only a single chunk for the Vector. This chunk can refer to one of the 4
273
    /// chunks front/back chunks or one of the leaves of the tree. The target_ptr is the pointer to the actual chunk
274
    /// in question. The target_range is the range that the chunk represents.
275
    target_range: Range<usize>,
276
    target_ptr: *const Chunk<A>,
277
}
278

279
impl<A> Clone for TreeFocus<A> {
280
    fn clone(&self) -> Self {
47,787✔
281
        let tree = self.tree.clone();
47,787✔
282
        TreeFocus {
47,787✔
283
            view: self.view.clone(),
47,787✔
284
            middle_range: self.middle_range.clone(),
47,787✔
285
            target_range: 0..0,
286
            target_ptr: null(),
47,787✔
287
            tree,
288
        }
289
    }
47,787✔
290
}
291

292
unsafe impl<A: Send> Send for TreeFocus<A> {}
293
unsafe impl<A: Sync> Sync for TreeFocus<A> {}
294

295
#[inline]
296
fn contains<A: Ord>(range: &Range<A>, index: &A) -> bool {
215,315,525✔
297
    *index >= range.start && *index < range.end
215,315,525✔
298
}
215,315,525✔
299

300
impl<A> TreeFocus<A> {
301
    /// Creates a new TreeFocus for a Vector's RRB tree.
302
    fn new(tree: &RRB<A>) -> Self {
56,250✔
303
        let middle_start = tree.outer_f.len() + tree.inner_f.len();
56,250✔
304
        let middle_end = middle_start + tree.middle.len();
56,250✔
305
        TreeFocus {
56,250✔
306
            tree: tree.clone(),
56,250✔
307
            view: 0..tree.length,
56,250✔
308
            middle_range: middle_start..middle_end,
309
            target_range: 0..0,
310
            target_ptr: null(),
56,250✔
311
        }
312
    }
56,250✔
313

314
    /// Returns the number of elements that the TreeFocus is valid for.
315
    fn len(&self) -> usize {
59,369,166✔
316
        self.view.end - self.view.start
59,369,166✔
317
    }
59,369,166✔
318

319
    /// Restricts the TreeFocus to a subrange of itself.
320
    fn narrow(self, mut view: Range<usize>) -> Self {
95,995✔
321
        view.start += self.view.start;
95,995✔
322
        view.end += self.view.start;
95,995✔
323
        TreeFocus {
95,995✔
324
            view,
95,995✔
325
            middle_range: self.middle_range.clone(),
95,995✔
326
            target_range: 0..0,
327
            target_ptr: null(),
95,995✔
328
            tree: self.tree,
95,995✔
329
        }
330
    }
95,995✔
331

332
    /// Splits the TreeFocus into two disjoint foci. The first TreeFocus is valid for ..index while the
333
    /// second is valid for index.. .
334
    fn split_at(self, index: usize) -> (Self, Self) {
47,821✔
335
        let len = self.len();
47,821✔
336
        let left = self.clone().narrow(0..index);
47,821✔
337
        let right = self.narrow(index..len);
47,821✔
338
        (left, right)
47,821✔
339
    }
47,821✔
340

341
    /// Computes an absolute index in the RRBTree for the given index relative to the start of this TreeFocus.
342
    fn physical_index(&self, index: usize) -> usize {
59,193,023✔
343
        debug_assert!(index < self.view.end);
59,193,023✔
344
        self.view.start + index
59,193,023✔
345
    }
59,193,023✔
346

347
    /// Computes a range relative to the TreeFocus given one that is absolute in the RRBTree.
348
    fn logical_range(&self, range: &Range<usize>) -> Range<usize> {
648,052✔
349
        (range.start - self.view.start)..(range.end - self.view.start)
648,052✔
350
    }
648,052✔
351

352
    /// Sets the internal chunk to the one that contains the given absolute index.
353
    fn set_focus(&mut self, index: usize) {
8,583,100✔
354
        if index < self.middle_range.start {
8,583,100✔
355
            let outer_len = self.tree.outer_f.len();
57,143✔
356
            if index < outer_len {
57,143✔
357
                self.target_range = 0..outer_len;
15,340✔
358
                self.target_ptr = &*self.tree.outer_f;
15,340✔
359
            } else {
360
                self.target_range = outer_len..self.middle_range.start;
41,803✔
361
                self.target_ptr = &*self.tree.inner_f;
41,803✔
362
            }
363
        } else if index >= self.middle_range.end {
8,525,957✔
364
            let outer_start = self.middle_range.end + self.tree.inner_b.len();
98,443✔
365
            if index < outer_start {
98,443✔
366
                self.target_range = self.middle_range.end..outer_start;
42,469✔
367
                self.target_ptr = &*self.tree.inner_b;
42,469✔
368
            } else {
369
                self.target_range = outer_start..self.tree.length;
55,974✔
370
                self.target_ptr = &*self.tree.outer_b;
55,974✔
371
            }
372
        } else {
373
            let tree_index = index - self.middle_range.start;
8,427,514✔
374
            let (range, ptr) = self
16,855,028✔
375
                .tree
376
                .middle
377
                .lookup_chunk(self.tree.middle_level, 0, tree_index);
8,427,514✔
378
            self.target_range =
8,427,514✔
379
                (range.start + self.middle_range.start)..(range.end + self.middle_range.start);
8,427,514✔
380
            self.target_ptr = ptr;
8,427,514✔
381
        }
382
    }
8,583,100✔
383

384
    /// Gets the chunk that this TreeFocus is focused on.
385
    fn get_focus(&self) -> &Chunk<A> {
59,169,020✔
386
        unsafe { &*self.target_ptr }
59,169,020✔
387
    }
59,169,020✔
388

389
    /// Gets the value at the given index relative to the TreeFocus.
390
    pub fn get(&mut self, index: usize) -> Option<&A> {
58,533,355✔
391
        if index >= self.len() {
58,533,355✔
392
            return None;
×
393
        }
394
        let phys_index = self.physical_index(index);
58,533,355✔
395
        if !contains(&self.target_range, &phys_index) {
58,533,355✔
396
            self.set_focus(phys_index);
7,935,068✔
397
        }
398
        let target_phys_index = phys_index - self.target_range.start;
58,533,355✔
399
        Some(&self.get_focus()[target_phys_index])
58,533,355✔
400
    }
58,533,355✔
401

402
    /// Gets the chunk for an index as a slice and its corresponding range within the TreeFocus.
403
    pub fn get_chunk(&mut self, index: usize) -> (Range<usize>, &[A]) {
648,052✔
404
        let phys_index = self.physical_index(index);
648,052✔
405
        if !contains(&self.target_range, &phys_index) {
648,052✔
406
            self.set_focus(phys_index);
648,052✔
407
        }
408
        let mut slice: &[A] = self.get_focus();
648,052✔
409
        let mut left = 0;
648,052✔
410
        let mut right = 0;
648,052✔
411
        if self.target_range.start < self.view.start {
648,052✔
412
            left = self.view.start - self.target_range.start;
×
413
        }
414
        if self.target_range.end > self.view.end {
648,052✔
415
            right = self.target_range.end - self.view.end;
×
416
        }
417
        slice = &slice[left..(slice.len() - right)];
648,052✔
418
        let phys_range = (self.target_range.start + left)..(self.target_range.end - right);
648,052✔
419
        (self.logical_range(&phys_range), slice)
648,052✔
420
    }
648,052✔
421
}
422

423
/// A mutable version of [`Focus`][Focus].
424
///
425
/// See [`Focus`][Focus] for more details.
426
///
427
/// You can only build one `FocusMut` at a time for a vector, effectively
428
/// keeping a lock on the vector until you're done with the focus, which relies
429
/// on the structure of the vector not changing while it exists.
430
///
431
/// ```rust,compile_fail
432
/// # #[macro_use] extern crate imbl;
433
/// # use imbl::vector::Vector;
434
/// # use std::iter::FromIterator;
435
/// let mut vec = Vector::from_iter(0..1000);
436
/// let focus1 = vec.focus_mut();
437
/// // Fails here in 2015 edition because you're creating
438
/// // two mutable references to the same thing.
439
/// let focus2 = vec.focus_mut();
440
/// // Fails here in 2018 edition because creating focus2
441
/// // made focus1's lifetime go out of scope.
442
/// assert_eq!(Some(&0), focus1.get(0));
443
/// ```
444
///
445
/// On the other hand, you can split that one focus into multiple sub-focuses,
446
/// which is safe because they can't overlap:
447
///
448
/// ```rust
449
/// # #[macro_use] extern crate imbl;
450
/// # use imbl::vector::Vector;
451
/// # use std::iter::FromIterator;
452
/// let mut vec = Vector::from_iter(0..1000);
453
/// let focus = vec.focus_mut();
454
/// let (mut left, mut right) = focus.split_at(500);
455
/// assert_eq!(Some(&0), left.get(0));
456
/// assert_eq!(Some(&500), right.get(0));
457
/// ```
458
///
459
/// These sub-foci also work as a lock on the vector, even if the focus they
460
/// were created from goes out of scope.
461
///
462
/// ```rust,compile_fail
463
/// # #[macro_use] extern crate imbl;
464
/// # use imbl::vector::Vector;
465
/// # use std::iter::FromIterator;
466
/// let mut vec = Vector::from_iter(0..1000);
467
/// let (left, right) = {
468
///     let focus = vec.focus_mut();
469
///     focus.split_at(500)
470
/// };
471
/// // `left` and `right` are still in scope even if `focus` isn't, so we can't
472
/// // create another focus:
473
/// let focus2 = vec.focus_mut();
474
/// assert_eq!(Some(&0), left.get(0));
475
/// ```
476
///
477
/// [Focus]: enum.Focus.html
478
pub enum FocusMut<'a, A> {
479
    #[doc(hidden)]
480
    /// The Single variant is a focusmut of a simple Vector that can be represented as a single slice.
481
    Single(RRBPool<A>, &'a mut [A]),
482
    #[doc(hidden)]
483
    /// The Full variant is a focus of a more complex Vector that cannot be represented as a single slice.
484
    Full(RRBPool<A>, TreeFocusMut<'a, A>),
485
}
486

487
impl<'a, A> FocusMut<'a, A>
488
where
489
    A: 'a,
490
{
491
    /// Get the length of the focused `Vector`.
492
    pub fn len(&self) -> usize {
66,428,707✔
493
        match self {
66,428,707✔
494
            FocusMut::Single(_, chunk) => chunk.len(),
256✔
495
            FocusMut::Full(_, tree) => tree.len(),
66,428,451✔
496
        }
497
    }
66,428,707✔
498

499
    /// Test if the focused `Vector` is empty.
500
    pub fn is_empty(&self) -> bool {
934,829✔
501
        self.len() == 0
934,829✔
502
    }
934,829✔
503

504
    /// Narrow the focus onto a subslice of the vector.
505
    ///
506
    /// `FocusMut::narrow(range)` has the same effect as `&slice[range]`, without
507
    /// actually modifying the underlying vector.
508
    ///
509
    /// Panics if the range isn't fully inside the current focus.
510
    ///
511
    /// ## Examples
512
    ///
513
    /// ```rust
514
    /// # #[macro_use] extern crate imbl;
515
    /// # use imbl::vector::Vector;
516
    /// # use std::iter::FromIterator;
517
    /// let mut vec = Vector::from_iter(0..1000);
518
    /// let narrowed = vec.focus_mut().narrow(100..200);
519
    /// let narrowed_vec = narrowed.unmut().into_iter().cloned().collect();
520
    /// assert_eq!(Vector::from_iter(100..200), narrowed_vec);
521
    /// ```
522
    ///
523
    /// [slice::split_at]: https://doc.rust-lang.org/std/primitive.slice.html#method.split_at
524
    /// [Vector::split_at]: enum.Vector.html#method.split_at
525
    #[must_use]
526
    pub fn narrow<R>(self, range: R) -> Self
527
    where
528
        R: RangeBounds<usize>,
529
    {
530
        let r = to_range(&range, self.len());
531
        if r.start > r.end || r.start > self.len() {
532
            panic!("vector::FocusMut::narrow: range out of bounds");
533
        }
534
        match self {
535
            FocusMut::Single(pool, chunk) => FocusMut::Single(pool, &mut chunk[r]),
536
            FocusMut::Full(pool, tree) => FocusMut::Full(pool, tree.narrow(r)),
537
        }
538
    }
539

540
    /// Split the focus into two.
541
    ///
542
    /// Given an index `index`, consume the focus and produce two new foci, the
543
    /// left onto indices `0..index`, and the right onto indices `index..N`
544
    /// where `N` is the length of the current focus.
545
    ///
546
    /// Panics if the index is out of bounds.
547
    ///
548
    /// This is the moral equivalent of [`slice::split_at`][slice::split_at], in
549
    /// that it leaves the underlying data structure unchanged, unlike
550
    /// [`Vector::split_at`][Vector::split_at].
551
    ///
552
    /// ## Examples
553
    ///
554
    /// ```rust
555
    /// # #[macro_use] extern crate imbl;
556
    /// # use imbl::vector::Vector;
557
    /// # use std::iter::FromIterator;
558
    /// let mut vec = Vector::from_iter(0..1000);
559
    /// {
560
    ///     let (left, right) = vec.focus_mut().split_at(500);
561
    ///     for ptr in left {
562
    ///         *ptr += 100;
563
    ///     }
564
    ///     for ptr in right {
565
    ///         *ptr -= 100;
566
    ///     }
567
    /// }
568
    /// let expected = Vector::from_iter(100..600)
569
    ///              + Vector::from_iter(400..900);
570
    /// assert_eq!(expected, vec);
571
    /// ```
572
    ///
573
    /// [slice::split_at]: https://doc.rust-lang.org/std/primitive.slice.html#method.split_at
574
    /// [Vector::split_at]: enum.Vector.html#method.split_at
575
    #[allow(clippy::redundant_clone)]
576
    pub fn split_at(self, index: usize) -> (Self, Self) {
3,649,719✔
577
        if index > self.len() {
3,649,719✔
578
            panic!("vector::FocusMut::split_at: index out of bounds");
×
579
        }
580
        match self {
3,649,719✔
581
            FocusMut::Single(pool, chunk) => {
75✔
582
                let (left, right) = chunk.split_at_mut(index);
75✔
583
                (
75✔
584
                    FocusMut::Single(pool.clone(), left),
75✔
585
                    FocusMut::Single(pool, right),
75✔
586
                )
587
            }
75✔
588
            FocusMut::Full(pool, tree) => {
7,299,363✔
589
                let (left, right) = tree.split_at(index);
3,649,644✔
590
                (
3,649,644✔
591
                    FocusMut::Full(pool.clone(), left),
3,649,644✔
592
                    FocusMut::Full(pool, right),
3,649,644✔
593
                )
594
            }
3,649,644✔
595
        }
596
    }
3,649,719✔
597

598
    /// Convert a `FocusMut` into a `Focus`.
599
    pub fn unmut(self) -> Focus<'a, A> {
600
        match self {
601
            FocusMut::Single(_, chunk) => Focus::Single(chunk),
602
            FocusMut::Full(_, mut tree) => Focus::Full(TreeFocus {
603
                tree: {
604
                    let t = tree.tree.lock().unwrap();
605
                    (*t).clone()
606
                },
607
                view: tree.view.clone(),
608
                middle_range: tree.middle_range.clone(),
609
                target_range: 0..0,
610
                target_ptr: null(),
611
            }),
612
        }
613
    }
614
}
615

616
impl<'a, A> FocusMut<'a, A>
617
where
618
    A: Clone + 'a,
619
{
620
    /// Construct a `FocusMut` for a `Vector`.
621
    pub fn new(vector: &'a mut Vector<A>) -> Self {
3,688✔
622
        match &mut vector.vector {
3,688✔
623
            Inline(pool, chunk) => FocusMut::Single(pool.clone(), chunk),
3✔
624
            Single(pool, chunk) => FocusMut::Single(
52✔
625
                pool.clone(),
26✔
626
                PoolRef::make_mut(&pool.value_pool, chunk).as_mut_slice(),
26✔
627
            ),
26✔
628
            Full(pool, tree) => FocusMut::Full(pool.clone(), TreeFocusMut::new(tree)),
3,659✔
629
        }
630
    }
3,688✔
631

632
    /// Get a reference to the value at a given index.
633
    pub fn get(&mut self, index: usize) -> Option<&A> {
634
        self.get_mut(index).map(|r| &*r)
635
    }
636

637
    /// Get a mutable reference to the value at a given index.
638
    pub fn get_mut(&mut self, index: usize) -> Option<&mut A> {
155,414,435✔
639
        match self {
155,414,435✔
640
            FocusMut::Single(_, chunk) => chunk.get_mut(index),
610✔
641
            FocusMut::Full(pool, tree) => tree.get(pool, index),
155,413,825✔
642
        }
643
    }
155,414,435✔
644

645
    /// Get a reference to the value at a given index.
646
    ///
647
    /// Panics if the index is out of bounds.
648
    pub fn index(&mut self, index: usize) -> &A {
97,007,704✔
649
        &*self.index_mut(index)
97,007,704✔
650
    }
97,007,704✔
651

652
    /// Get a mutable reference to the value at a given index.
653
    ///
654
    /// Panics if the index is out of bounds.
655
    #[allow(clippy::should_implement_trait)] // would if I could
656
    pub fn index_mut(&mut self, index: usize) -> &mut A {
147,463,497✔
657
        self.get_mut(index).expect("index out of bounds")
147,463,497✔
658
    }
147,463,497✔
659

660
    /// Update the value at a given index.
661
    ///
662
    /// Returns `None` if the index is out of bounds, or the replaced value
663
    /// otherwise.
664
    pub fn set(&mut self, index: usize, value: A) -> Option<A> {
665
        self.get_mut(index).map(|pos| replace(pos, value))
666
    }
667

668
    /// Swap the values at two given indices.
669
    ///
670
    /// Panics if either index is out of bounds.
671
    ///
672
    /// If the indices are equal, this function returns without doing anything.
673
    pub fn swap(&mut self, a: usize, b: usize) {
674
        if a == b {
675
            return;
676
        }
677
        self.pair(a, b, |left, right| swap(left, right));
678
    }
679

680
    /// Lookup two indices simultaneously and run a function over them.
681
    ///
682
    /// Useful because the borrow checker won't let you have more than one
683
    /// mutable reference into the same data structure at any given time.
684
    ///
685
    /// Panics if either index is out of bounds, or if they are the same index.
686
    ///
687
    /// # Examples
688
    ///
689
    /// ```rust
690
    /// # #[macro_use] extern crate imbl;
691
    /// # use imbl::vector::Vector;
692
    /// # use std::iter::FromIterator;
693
    /// let mut vec = vector![1, 2, 3, 4, 5];
694
    /// vec.focus_mut().pair(1, 3, |a, b| *a += *b);
695
    /// assert_eq!(vector![1, 6, 3, 4, 5], vec);
696
    /// ```
697
    pub fn pair<F, B>(&mut self, a: usize, b: usize, mut f: F) -> B
698
    where
699
        F: FnMut(&mut A, &mut A) -> B,
700
    {
701
        if a == b {
702
            panic!("vector::FocusMut::pair: indices cannot be equal!");
703
        }
704
        let pa: *mut A = self.index_mut(a);
705
        let pb: *mut A = self.index_mut(b);
706
        unsafe { f(&mut *pa, &mut *pb) }
707
    }
708

709
    /// Lookup three indices simultaneously and run a function over them.
710
    ///
711
    /// Useful because the borrow checker won't let you have more than one
712
    /// mutable reference into the same data structure at any given time.
713
    ///
714
    /// Panics if any index is out of bounds, or if any indices are equal.
715
    ///
716
    /// # Examples
717
    ///
718
    /// ```rust
719
    /// # #[macro_use] extern crate imbl;
720
    /// # use imbl::vector::Vector;
721
    /// # use std::iter::FromIterator;
722
    /// let mut vec = vector![1, 2, 3, 4, 5];
723
    /// vec.focus_mut().triplet(0, 2, 4, |a, b, c| *a += *b + *c);
724
    /// assert_eq!(vector![9, 2, 3, 4, 5], vec);
725
    /// ```
726
    pub fn triplet<F, B>(&mut self, a: usize, b: usize, c: usize, mut f: F) -> B
727
    where
728
        F: FnMut(&mut A, &mut A, &mut A) -> B,
729
    {
730
        if a == b || b == c || a == c {
731
            panic!("vector::FocusMut::triplet: indices cannot be equal!");
732
        }
733
        let pa: *mut A = self.index_mut(a);
734
        let pb: *mut A = self.index_mut(b);
735
        let pc: *mut A = self.index_mut(c);
736
        unsafe { f(&mut *pa, &mut *pb, &mut *pc) }
737
    }
738

739
    /// Get the chunk for the given index.
740
    ///
741
    /// This gives you a reference to the leaf node that contains the index,
742
    /// along with its start and end indices.
743
    pub fn chunk_at(&mut self, index: usize) -> (Range<usize>, &mut [A]) {
748,650✔
744
        let len = self.len();
748,650✔
745
        if index >= len {
748,650✔
746
            panic!("vector::FocusMut::chunk_at: index out of bounds");
×
747
        }
748
        match self {
748,650✔
749
            FocusMut::Single(_, chunk) => (0..len, chunk),
10✔
750
            FocusMut::Full(pool, tree) => {
748,640✔
751
                let (range, chunk) = tree.get_chunk(pool, index);
748,640✔
752
                (range, chunk)
748,640✔
753
            }
748,640✔
754
        }
755
    }
748,650✔
756
}
757

758
impl<'a, A> IntoIterator for FocusMut<'a, A>
759
where
760
    A: Clone + 'a,
761
{
762
    type Item = &'a mut A;
763
    type IntoIter = IterMut<'a, A>;
764

765
    fn into_iter(self) -> Self::IntoIter {
582,980✔
766
        IterMut::from_focus(self)
582,980✔
767
    }
582,980✔
768
}
769

770
impl<'a, A> From<FocusMut<'a, A>> for Focus<'a, A>
771
where
772
    A: Clone + 'a,
773
{
774
    fn from(f: FocusMut<'a, A>) -> Focus<'a, A> {
775
        f.unmut()
776
    }
777
}
778

779
// NOTE: The documentation the mutable version is similar to the non-mutable version. I will comment for the places
780
// where there are differences, otherwise the documentation is copied directly.
781
pub struct TreeFocusMut<'a, A> {
782
    /// The tree that this TreeFocusMut refers to. Unlike the non-mutable version, TreeFocusMut needs to store a
783
    /// mutable reference. Additionally, there may be multiple TreeFocusMuts that refer to the same tree so we need a
784
    /// Lock to synchronise the changes.
785
    tree: Lock<&'a mut RRB<A>>,
786
    /// The view represents the range of the tree that this TreeFocusMut can see. The view can be narrowed by calling
787
    /// either the narrow or split_at methods.
788
    view: Range<usize>,
789
    /// The tree version of the Vector is represented as the concatenation of 2 chunks, followed by the tree root,
790
    /// followed by 2 chunks. The middle_range refers to the range of the Vector that the tree covers.
791
    middle_range: Range<usize>,
792
    /// This implementation of a focusmut stores only a single chunk for the Vector. This chunk can refer to one of the
793
    /// 4 chunks front/back chunks or one of the leaves of the tree. The target_ptr is the pointer to the actual chunk
794
    /// in question. The target_range is the range that the chunk represents.
795
    target_range: Range<usize>,
796
    /// Not actually sure why this needs to be an atomic, it seems like it is unneccessary. This is just a pointer to
797
    /// the chunk referred to above.
798
    target_ptr: AtomicPtr<Chunk<A>>,
799
}
800

801
impl<'a, A> TreeFocusMut<'a, A>
802
where
803
    A: 'a,
804
{
805
    /// Creates a new TreeFocusMut for a Vector's RRB tree.
806
    fn new(tree: &'a mut RRB<A>) -> Self {
3,659✔
807
        let middle_start = tree.outer_f.len() + tree.inner_f.len();
3,659✔
808
        let middle_end = middle_start + tree.middle.len();
3,659✔
809
        TreeFocusMut {
3,659✔
810
            view: 0..tree.length,
3,659✔
811
            tree: Lock::new(tree),
3,659✔
812
            middle_range: middle_start..middle_end,
813
            target_range: 0..0,
814
            target_ptr: AtomicPtr::default(),
3,659✔
815
        }
816
    }
3,659✔
817

818
    /// Returns the number of elements that the TreeFocusMut is valid for.
819
    fn len(&self) -> usize {
225,486,864✔
820
        self.view.end - self.view.start
225,486,864✔
821
    }
225,486,864✔
822

823
    /// Restricts the TreeFocusMut to a subrange of itself.
824
    fn narrow(self, mut view: Range<usize>) -> Self {
825
        view.start += self.view.start;
826
        view.end += self.view.start;
827
        TreeFocusMut {
828
            view,
829
            middle_range: self.middle_range.clone(),
830
            target_range: 0..0,
831
            target_ptr: AtomicPtr::default(),
832
            tree: self.tree,
833
        }
834
    }
835

836
    /// Splits the TreeFocusMut into two disjoint foci. The first TreeFocusMut is valid for ..index while the
837
    /// second is valid for index.. .
838
    fn split_at(self, index: usize) -> (Self, Self) {
3,649,633✔
839
        let len = self.len();
3,649,633✔
840
        debug_assert!(index <= len);
3,649,633✔
841
        let left = TreeFocusMut {
3,649,633✔
842
            view: self.view.start..(self.view.start + index),
3,649,633✔
843
            middle_range: self.middle_range.clone(),
3,649,633✔
844
            target_range: 0..0,
845
            target_ptr: AtomicPtr::default(),
3,649,633✔
846
            tree: self.tree.clone(),
3,649,633✔
847
        };
848
        let right = TreeFocusMut {
3,649,633✔
849
            view: (self.view.start + index)..(self.view.start + len),
3,649,633✔
850
            middle_range: self.middle_range.clone(),
3,649,633✔
851
            target_range: 0..0,
852
            target_ptr: AtomicPtr::default(),
3,649,633✔
853
            tree: self.tree,
3,649,633✔
854
        };
855
        (left, right)
3,649,633✔
856
    }
3,649,633✔
857

858
    /// Computes an absolute index in the RRBTree for the given index relative to the start of this TreeFocusMut.
859
    fn physical_index(&self, index: usize) -> usize {
156,161,431✔
860
        debug_assert!(index < self.view.end);
156,161,431✔
861
        self.view.start + index
156,161,431✔
862
    }
156,161,431✔
863

864
    /// Computes a range relative to the TreeFocusMut given one that is absolute in the RRBTree.
865
    fn logical_range(&self, range: &Range<usize>) -> Range<usize> {
748,640✔
866
        (range.start - self.view.start)..(range.end - self.view.start)
748,640✔
867
    }
748,640✔
868

869
    /// Gets the chunk for an index and its corresponding range within the TreeFocusMut.
870
    fn get_focus(&mut self) -> &mut Chunk<A> {
156,904,728✔
871
        unsafe { &mut *self.target_ptr.load(Ordering::Relaxed) }
156,904,728✔
872
    }
156,904,728✔
873
}
874

875
impl<'a, A> TreeFocusMut<'a, A>
876
where
877
    A: Clone + 'a,
878
{
879
    /// Sets the internal chunk to the one that contains the given absolute index.
880
    fn set_focus(&mut self, pool: &RRBPool<A>, index: usize) {
21,012,637✔
881
        let mut tree = self
21,012,637✔
882
            .tree
883
            .lock()
884
            .expect("imbl::vector::Focus::set_focus: unable to acquire exclusive lock on Vector");
885
        if index < self.middle_range.start {
21,012,637✔
886
            let outer_len = tree.outer_f.len();
43,626✔
887
            if index < outer_len {
43,626✔
888
                self.target_range = 0..outer_len;
×
889
                self.target_ptr.store(
×
890
                    PoolRef::make_mut(&pool.value_pool, &mut tree.outer_f),
×
891
                    Ordering::Relaxed,
×
892
                );
893
            } else {
894
                self.target_range = outer_len..self.middle_range.start;
43,626✔
895
                self.target_ptr.store(
87,252✔
896
                    PoolRef::make_mut(&pool.value_pool, &mut tree.inner_f),
43,626✔
897
                    Ordering::Relaxed,
43,626✔
898
                );
899
            }
900
        } else if index >= self.middle_range.end {
20,969,011✔
901
            let outer_start = self.middle_range.end + tree.inner_b.len();
88,569✔
902
            if index < outer_start {
88,569✔
903
                self.target_range = self.middle_range.end..outer_start;
54,668✔
904
                self.target_ptr.store(
109,336✔
905
                    PoolRef::make_mut(&pool.value_pool, &mut tree.inner_b),
54,668✔
906
                    Ordering::Relaxed,
54,668✔
907
                );
908
            } else {
909
                self.target_range = outer_start..tree.length;
33,901✔
910
                self.target_ptr.store(
67,802✔
911
                    PoolRef::make_mut(&pool.value_pool, &mut tree.outer_b),
33,901✔
912
                    Ordering::Relaxed,
33,901✔
913
                );
914
            }
915
        } else {
916
            let tree_index = index - self.middle_range.start;
20,880,442✔
917
            let level = tree.middle_level;
20,880,442✔
918
            let middle = Ref::make_mut(&mut tree.middle);
20,880,442✔
919
            let (range, ptr) = middle.lookup_chunk_mut(pool, level, 0, tree_index);
20,880,442✔
920
            self.target_range =
20,880,442✔
921
                (range.start + self.middle_range.start)..(range.end + self.middle_range.start);
20,880,442✔
922
            self.target_ptr.store(ptr, Ordering::Relaxed);
20,880,442✔
923
        }
924
    }
21,012,637✔
925

926
    /// Gets the value at the given index relative to the TreeFocusMut.
927
    pub fn get(&mut self, pool: &RRBPool<A>, index: usize) -> Option<&mut A> {
155,417,116✔
928
        if index >= self.len() {
155,417,116✔
929
            return None;
×
930
        }
931
        let phys_index = self.physical_index(index);
155,417,116✔
932
        if !contains(&self.target_range, &phys_index) {
155,417,116✔
933
            self.set_focus(pool, phys_index);
20,263,861✔
934
        }
935
        let target_phys_index = phys_index - self.target_range.start;
155,417,116✔
936
        Some(&mut self.get_focus()[target_phys_index])
155,417,116✔
937
    }
155,417,116✔
938

939
    /// Gets the chunk for an index as a slice and its corresponding range within the TreeFocusMut.
940
    pub fn get_chunk(&mut self, pool: &RRBPool<A>, index: usize) -> (Range<usize>, &mut [A]) {
748,640✔
941
        let phys_index = self.physical_index(index);
748,640✔
942
        if !contains(&self.target_range, &phys_index) {
748,640✔
943
            self.set_focus(pool, phys_index);
748,640✔
944
        }
945
        let mut left = 0;
748,640✔
946
        let mut right = 0;
748,640✔
947
        if self.target_range.start < self.view.start {
748,640✔
948
            left = self.view.start - self.target_range.start;
×
949
        }
950
        if self.target_range.end > self.view.end {
748,640✔
951
            right = self.target_range.end - self.view.end;
×
952
        }
953
        let phys_range = (self.target_range.start + left)..(self.target_range.end - right);
748,640✔
954
        let log_range = self.logical_range(&phys_range);
748,640✔
955
        let slice_len = self.get_focus().len();
748,640✔
956
        let slice = &mut (self.get_focus().as_mut_slice())[left..(slice_len - right)];
748,640✔
957
        (log_range, slice)
748,640✔
958
    }
748,640✔
959
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc