im_rc/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
5use std::mem::{replace, swap};
6use std::ops::{Range, RangeBounds};
7use std::ptr::null;
8use std::sync::atomic::{AtomicPtr, Ordering};
9
10use crate::nodes::chunk::Chunk;
11use crate::sync::Lock;
12use crate::util::{to_range, PoolRef, Ref};
13use crate::vector::{
14    Iter, IterMut, RRBPool, Rrb, Vector,
15    VectorInner::{Full, Inline, Single},
16};
17
18/// Focused indexing over a [`Vector`][Vector].
19///
20/// By remembering the last tree node accessed through an index lookup and the
21/// path we took to get there, we can speed up lookups for adjacent indices
22/// tremendously. Lookups on indices in the same node are instantaneous, and
23/// lookups on sibling nodes are also very fast.
24///
25/// A `Focus` can also be used as a restricted view into a vector, using the
26/// [`narrow`][narrow] and [`split_at`][split_at] methods.
27///
28/// # When should I use a `Focus` for better performance?
29///
30/// `Focus` is useful when you need to perform a large number of index lookups
31/// that are more likely than not to be close to each other. It's usually worth
32/// using a `Focus` in any situation where you're batching a lot of index
33/// lookups together, even if they're not obviously adjacent - there's likely
34/// to be some performance gain for even completely random access.
35///
36/// If you're just iterating forwards or backwards over the [`Vector`][Vector]
37/// in order, you're better off with a regular iterator, which, in fact, is
38/// implemented using a `Focus`, but provides a simpler interface.
39///
40/// If you're just doing a very small number of index lookups, the setup cost
41/// for the `Focus` is probably not worth it.
42///
43/// A `Focus` is never faster than an index lookup on a small [`Vector`][Vector]
44/// with a length below the internal RRB tree's branching factor of 64.
45///
46/// # Examples
47///
48/// This example is contrived, as the better way to iterate forwards or
49/// backwards over a vector is with an actual iterator. Even so, the version
50/// using a `Focus` should run nearly an order of magnitude faster than the
51/// version using index lookups at a length of 1000. It should also be noted
52/// that [`vector::Iter`][Iter] is actually implemented using a `Focus` behind
53/// the scenes, so the performance of the two should be identical.
54///
55/// ```rust
56/// # #[macro_use] extern crate im_rc as im;
57/// # use im::vector::Vector;
58/// # use std::iter::FromIterator;
59/// let mut vec: Vector<i64> = Vector::from_iter(0..1000);
60///
61/// // Summing a vector, the slow way:
62/// let mut sum = 0;
63/// for i in 0..1000 {
64///     sum += *vec.get(i).unwrap();
65/// }
66/// assert_eq!(499500, sum);
67///
68/// // Summing a vector faster using a Focus:
69/// let mut sum = 0;
70/// let mut focus = vec.focus();
71/// for i in 0..1000 {
72///     sum += *focus.get(i).unwrap();
73/// }
74/// assert_eq!(499500, sum);
75///
76/// // And the easy way, for completeness:
77/// let sum: i64 = vec.iter().sum();
78/// assert_eq!(499500, sum);
79/// ```
80///
81/// [Vector]: enum.Vector.html
82/// [Iter]: struct.Iter.html
83/// [narrow]: #method.narrow
84/// [split_at]: #method.split_at
85pub enum Focus<'a, A> {
86    #[doc(hidden)]
87    Single(&'a [A]),
88    #[doc(hidden)]
89    Full(TreeFocus<A>),
90}
91
92impl<'a, A> Focus<'a, A>
93where
94    A: Clone + 'a,
95{
96    /// Construct a `Focus` for a [`Vector`][Vector].
97    ///
98    /// [Vector]: enum.Vector.html
99    pub fn new(vector: &'a Vector<A>) -> Self {
100        match &vector.vector {
101            Inline(_, chunk) => Focus::Single(chunk),
102            Single(_, chunk) => Focus::Single(chunk),
103            Full(_, tree) => Focus::Full(TreeFocus::new(tree)),
104        }
105    }
106
107    /// Get the length of the focused [`Vector`][Vector].
108    ///
109    /// [Vector]: enum.Vector.html
110    pub fn len(&self) -> usize {
111        match self {
112            Focus::Single(chunk) => chunk.len(),
113            Focus::Full(tree) => tree.len(),
114        }
115    }
116
117    /// Test if the focused [`Vector`][Vector] is empty.
118    ///
119    /// [Vector]: enum.Vector.html
120    pub fn is_empty(&self) -> bool {
121        self.len() == 0
122    }
123
124    /// Get a reference to the value at a given index.
125    pub fn get(&mut self, index: usize) -> Option<&A> {
126        match self {
127            Focus::Single(chunk) => chunk.get(index),
128            Focus::Full(tree) => tree.get(index),
129        }
130    }
131
132    /// Get a reference to the value at a given index.
133    ///
134    /// Panics if the index is out of bounds.
135    pub fn index(&mut self, index: usize) -> &A {
136        self.get(index).expect("index out of bounds")
137    }
138
139    /// Get the chunk for the given index.
140    ///
141    /// This gives you a reference to the leaf node that contains the index,
142    /// along with its start and end indices.
143    pub fn chunk_at(&mut self, index: usize) -> (Range<usize>, &[A]) {
144        let len = self.len();
145        if index >= len {
146            panic!("vector::Focus::chunk_at: index out of bounds");
147        }
148        match self {
149            Focus::Single(chunk) => (0..len, chunk),
150            Focus::Full(tree) => tree.get_chunk(index),
151        }
152    }
153
154    /// Narrow the focus onto a subslice of the vector.
155    ///
156    /// `Focus::narrow(range)` has the same effect as `&slice[range]`, without
157    /// actually modifying the underlying vector.
158    ///
159    /// Panics if the range isn't fully inside the current focus.
160    ///
161    /// ## Examples
162    ///
163    /// ```rust
164    /// # #[macro_use] extern crate im_rc as im;
165    /// # use im::vector::Vector;
166    /// # use std::iter::FromIterator;
167    /// let vec = Vector::from_iter(0..1000);
168    /// let narrowed = vec.focus().narrow(100..200);
169    /// let narrowed_vec = narrowed.into_iter().cloned().collect();
170    /// assert_eq!(Vector::from_iter(100..200), narrowed_vec);
171    /// ```
172    ///
173    /// [slice::split_at]: https://doc.rust-lang.org/std/primitive.slice.html#method.split_at
174    /// [Vector::split_at]: enum.Vector.html#method.split_at
175    pub fn narrow<R>(self, range: R) -> Self
176    where
177        R: RangeBounds<usize>,
178    {
179        let r = to_range(&range, self.len());
180        if r.start >= r.end || r.start >= self.len() {
181            panic!("vector::Focus::narrow: range out of bounds");
182        }
183        match self {
184            Focus::Single(chunk) => Focus::Single(&chunk[r]),
185            Focus::Full(tree) => Focus::Full(tree.narrow(r)),
186        }
187    }
188
189    /// Split the focus into two.
190    ///
191    /// Given an index `index`, consume the focus and produce two new foci, the
192    /// left onto indices `0..index`, and the right onto indices `index..N`
193    /// where `N` is the length of the current focus.
194    ///
195    /// Panics if the index is out of bounds.
196    ///
197    /// This is the moral equivalent of [`slice::split_at`][slice::split_at], in
198    /// that it leaves the underlying data structure unchanged, unlike
199    /// [`Vector::split_at`][Vector::split_at].
200    ///
201    /// ## Examples
202    ///
203    /// ```rust
204    /// # #[macro_use] extern crate im_rc as im;
205    /// # use im::vector::Vector;
206    /// # use std::iter::FromIterator;
207    /// let vec = Vector::from_iter(0..1000);
208    /// let (left, right) = vec.focus().split_at(500);
209    /// let left_vec = left.into_iter().cloned().collect();
210    /// let right_vec = right.into_iter().cloned().collect();
211    /// assert_eq!(Vector::from_iter(0..500), left_vec);
212    /// assert_eq!(Vector::from_iter(500..1000), right_vec);
213    /// ```
214    ///
215    /// [slice::split_at]: https://doc.rust-lang.org/std/primitive.slice.html#method.split_at
216    /// [Vector::split_at]: enum.Vector.html#method.split_at
217    pub fn split_at(self, index: usize) -> (Self, Self) {
218        if index >= self.len() {
219            panic!("vector::Focus::split_at: index out of bounds");
220        }
221        match self {
222            Focus::Single(chunk) => {
223                let (left, right) = chunk.split_at(index);
224                (Focus::Single(left), Focus::Single(right))
225            }
226            Focus::Full(tree) => {
227                let (left, right) = tree.split_at(index);
228                (Focus::Full(left), Focus::Full(right))
229            }
230        }
231    }
232}
233
234impl<'a, A> IntoIterator for Focus<'a, A>
235where
236    A: Clone + 'a,
237{
238    type Item = &'a A;
239    type IntoIter = Iter<'a, A>;
240
241    fn into_iter(self) -> Self::IntoIter {
242        Iter::from_focus(self)
243    }
244}
245
246impl<'a, A> Clone for Focus<'a, A>
247where
248    A: Clone + 'a,
249{
250    fn clone(&self) -> Self {
251        match self {
252            Focus::Single(chunk) => Focus::Single(chunk),
253            Focus::Full(tree) => Focus::Full(tree.clone()),
254        }
255    }
256}
257
258pub struct TreeFocus<A> {
259    tree: Rrb<A>,
260    view: Range<usize>,
261    middle_range: Range<usize>,
262    target_range: Range<usize>,
263    target_ptr: *const Chunk<A>,
264}
265
266impl<A> Clone for TreeFocus<A> {
267    fn clone(&self) -> Self {
268        let tree = self.tree.clone();
269        TreeFocus {
270            view: self.view.clone(),
271            middle_range: self.middle_range.clone(),
272            target_range: 0..0,
273            target_ptr: null(),
274            tree,
275        }
276    }
277}
278
279#[allow(unsafe_code)]
280#[cfg(threadsafe)]
281unsafe impl<A: Send> Send for TreeFocus<A> {}
282#[allow(unsafe_code)]
283#[cfg(threadsafe)]
284unsafe impl<A: Sync> Sync for TreeFocus<A> {}
285
286#[inline]
287fn contains<A: Ord>(range: &Range<A>, index: &A) -> bool {
288    *index >= range.start && *index < range.end
289}
290
291impl<A> TreeFocus<A>
292where
293    A: Clone,
294{
295    fn new(tree: &Rrb<A>) -> Self {
296        let middle_start = tree.outer_f.len() + tree.inner_f.len();
297        let middle_end = middle_start + tree.middle.len();
298        TreeFocus {
299            tree: tree.clone(),
300            view: 0..tree.length,
301            middle_range: middle_start..middle_end,
302            target_range: 0..0,
303            target_ptr: null(),
304        }
305    }
306
307    fn len(&self) -> usize {
308        self.view.end - self.view.start
309    }
310
311    fn narrow(self, mut view: Range<usize>) -> Self {
312        view.start += self.view.start;
313        view.end += self.view.start;
314        TreeFocus {
315            view,
316            middle_range: self.middle_range.clone(),
317            target_range: 0..0,
318            target_ptr: null(),
319            tree: self.tree,
320        }
321    }
322
323    fn split_at(self, index: usize) -> (Self, Self) {
324        let len = self.len();
325        let left = self.clone().narrow(0..index);
326        let right = self.narrow(index..len);
327        (left, right)
328    }
329
330    fn physical_index(&self, index: usize) -> usize {
331        debug_assert!(index < self.view.end);
332        self.view.start + index
333    }
334
335    fn logical_range(&self, range: &Range<usize>) -> Range<usize> {
336        (range.start - self.view.start)..(range.end - self.view.start)
337    }
338
339    fn set_focus(&mut self, index: usize) {
340        if index < self.middle_range.start {
341            let outer_len = self.tree.outer_f.len();
342            if index < outer_len {
343                self.target_range = 0..outer_len;
344                self.target_ptr = &*self.tree.outer_f;
345            } else {
346                self.target_range = outer_len..self.middle_range.start;
347                self.target_ptr = &*self.tree.inner_f;
348            }
349        } else if index >= self.middle_range.end {
350            let outer_start = self.middle_range.end + self.tree.inner_b.len();
351            if index < outer_start {
352                self.target_range = self.middle_range.end..outer_start;
353                self.target_ptr = &*self.tree.inner_b;
354            } else {
355                self.target_range = outer_start..self.tree.length;
356                self.target_ptr = &*self.tree.outer_b;
357            }
358        } else {
359            let tree_index = index - self.middle_range.start;
360            let (range, ptr) = self
361                .tree
362                .middle
363                .lookup_chunk(self.tree.middle_level, 0, tree_index);
364            self.target_range =
365                (range.start + self.middle_range.start)..(range.end + self.middle_range.start);
366            self.target_ptr = ptr;
367        }
368    }
369
370    #[allow(unsafe_code)]
371    fn get_focus(&self) -> &Chunk<A> {
372        unsafe { &*self.target_ptr }
373    }
374
375    pub fn get(&mut self, index: usize) -> Option<&A> {
376        if index >= self.len() {
377            return None;
378        }
379        let phys_index = self.physical_index(index);
380        if !contains(&self.target_range, &phys_index) {
381            self.set_focus(phys_index);
382        }
383        let target_phys_index = phys_index - self.target_range.start;
384        Some(&self.get_focus()[target_phys_index])
385    }
386
387    pub fn get_chunk(&mut self, index: usize) -> (Range<usize>, &[A]) {
388        let phys_index = self.physical_index(index);
389        if !contains(&self.target_range, &phys_index) {
390            self.set_focus(phys_index);
391        }
392        let mut slice: &[A] = self.get_focus().as_slice();
393        let mut left = 0;
394        let mut right = 0;
395        if self.target_range.start < self.view.start {
396            left = self.view.start - self.target_range.start;
397        }
398        if self.target_range.end > self.view.end {
399            right = self.target_range.end - self.view.end;
400        }
401        slice = &slice[left..(slice.len() - right)];
402        let phys_range = (self.target_range.start + left)..(self.target_range.end - right);
403        (self.logical_range(&phys_range), slice)
404    }
405}
406
407/// A mutable version of [`Focus`][Focus].
408///
409/// See [`Focus`][Focus] for more details.
410///
411/// You can only build one `FocusMut` at a time for a vector, effectively
412/// keeping a lock on the vector until you're done with the focus, which relies
413/// on the structure of the vector not changing while it exists.
414///
415/// ```rust,compile_fail
416/// # #[macro_use] extern crate im_rc as im;
417/// # use im::vector::Vector;
418/// # use std::iter::FromIterator;
419/// let mut vec = Vector::from_iter(0..1000);
420/// let focus1 = vec.focus_mut();
421/// // Fails here in 2015 edition because you're creating
422/// // two mutable references to the same thing.
423/// let focus2 = vec.focus_mut();
424/// // Fails here in 2018 edition because creating focus2
425/// // made focus1's lifetime go out of scope.
426/// assert_eq!(Some(&0), focus1.get(0));
427/// ```
428///
429/// On the other hand, you can split that one focus into multiple sub-focuses,
430/// which is safe because they can't overlap:
431///
432/// ```rust
433/// # #[macro_use] extern crate im_rc as im;
434/// # use im::vector::Vector;
435/// # use std::iter::FromIterator;
436/// let mut vec = Vector::from_iter(0..1000);
437/// let focus = vec.focus_mut();
438/// let (mut left, mut right) = focus.split_at(500);
439/// assert_eq!(Some(&0), left.get(0));
440/// assert_eq!(Some(&500), right.get(0));
441/// ```
442///
443/// These sub-foci also work as a lock on the vector, even if the focus they
444/// were created from goes out of scope.
445///
446/// ```rust,compile_fail
447/// # #[macro_use] extern crate im_rc as im;
448/// # use im::vector::Vector;
449/// # use std::iter::FromIterator;
450/// let mut vec = Vector::from_iter(0..1000);
451/// let (left, right) = {
452///     let focus = vec.focus_mut();
453///     focus.split_at(500)
454/// };
455/// // `left` and `right` are still in scope even if `focus` isn't, so we can't
456/// // create another focus:
457/// let focus2 = vec.focus_mut();
458/// assert_eq!(Some(&0), left.get(0));
459/// ```
460///
461/// [Focus]: enum.Focus.html
462pub enum FocusMut<'a, A> {
463    #[doc(hidden)]
464    Single(RRBPool<A>, &'a mut [A]),
465    #[doc(hidden)]
466    Full(RRBPool<A>, TreeFocusMut<'a, A>),
467}
468
469impl<'a, A> FocusMut<'a, A>
470where
471    A: Clone + 'a,
472{
473    /// Construct a `FocusMut` for a `Vector`.
474    pub fn new(vector: &'a mut Vector<A>) -> Self {
475        match &mut vector.vector {
476            Inline(pool, chunk) => FocusMut::Single(pool.clone(), chunk),
477            Single(pool, chunk) => FocusMut::Single(
478                pool.clone(),
479                PoolRef::make_mut(&pool.value_pool, chunk).as_mut_slice(),
480            ),
481            Full(pool, tree) => FocusMut::Full(pool.clone(), TreeFocusMut::new(tree)),
482        }
483    }
484
485    /// Get the length of the focused `Vector`.
486    pub fn len(&self) -> usize {
487        match self {
488            FocusMut::Single(_, chunk) => chunk.len(),
489            FocusMut::Full(_, tree) => tree.len(),
490        }
491    }
492
493    /// Test if the focused `Vector` is empty.
494    pub fn is_empty(&self) -> bool {
495        self.len() == 0
496    }
497
498    /// Get a reference to the value at a given index.
499    pub fn get(&mut self, index: usize) -> Option<&A> {
500        self.get_mut(index).map(|r| &*r)
501    }
502
503    /// Get a mutable reference to the value at a given index.
504    pub fn get_mut(&mut self, index: usize) -> Option<&mut A> {
505        match self {
506            FocusMut::Single(_, chunk) => chunk.get_mut(index),
507            FocusMut::Full(pool, tree) => tree.get(pool, index),
508        }
509    }
510
511    /// Get a reference to the value at a given index.
512    ///
513    /// Panics if the index is out of bounds.
514    pub fn index(&mut self, index: usize) -> &A {
515        &*self.index_mut(index)
516    }
517
518    /// Get a mutable reference to the value at a given index.
519    ///
520    /// Panics if the index is out of bounds.
521    #[allow(clippy::should_implement_trait)] // would if I could
522    pub fn index_mut(&mut self, index: usize) -> &mut A {
523        self.get_mut(index).expect("index out of bounds")
524    }
525
526    /// Update the value at a given index.
527    ///
528    /// Returns `None` if the index is out of bounds, or the replaced value
529    /// otherwise.
530    pub fn set(&mut self, index: usize, value: A) -> Option<A> {
531        self.get_mut(index).map(|pos| replace(pos, value))
532    }
533
534    /// Swap the values at two given indices.
535    ///
536    /// Panics if either index is out of bounds.
537    ///
538    /// If the indices are equal, this function returns without doing anything.
539    pub fn swap(&mut self, a: usize, b: usize) {
540        if a == b {
541            return;
542        }
543        self.pair(a, b, |left, right| swap(left, right));
544    }
545
546    /// Lookup two indices simultaneously and run a function over them.
547    ///
548    /// Useful because the borrow checker won't let you have more than one
549    /// mutable reference into the same data structure at any given time.
550    ///
551    /// Panics if either index is out of bounds, or if they are the same index.
552    ///
553    /// # Examples
554    ///
555    /// ```rust
556    /// # #[macro_use] extern crate im_rc as im;
557    /// # use im::vector::Vector;
558    /// # use std::iter::FromIterator;
559    /// let mut vec = vector![1, 2, 3, 4, 5];
560    /// vec.focus_mut().pair(1, 3, |a, b| *a += *b);
561    /// assert_eq!(vector![1, 6, 3, 4, 5], vec);
562    /// ```
563    #[allow(unsafe_code)]
564    pub fn pair<F, B>(&mut self, a: usize, b: usize, mut f: F) -> B
565    where
566        F: FnMut(&mut A, &mut A) -> B,
567    {
568        if a == b {
569            panic!("vector::FocusMut::pair: indices cannot be equal!");
570        }
571        let pa: *mut A = self.index_mut(a);
572        let pb: *mut A = self.index_mut(b);
573        unsafe { f(&mut *pa, &mut *pb) }
574    }
575
576    /// Lookup three indices simultaneously and run a function over them.
577    ///
578    /// Useful because the borrow checker won't let you have more than one
579    /// mutable reference into the same data structure at any given time.
580    ///
581    /// Panics if any index is out of bounds, or if any indices are equal.
582    ///
583    /// # Examples
584    ///
585    /// ```rust
586    /// # #[macro_use] extern crate im_rc as im;
587    /// # use im::vector::Vector;
588    /// # use std::iter::FromIterator;
589    /// let mut vec = vector![1, 2, 3, 4, 5];
590    /// vec.focus_mut().triplet(0, 2, 4, |a, b, c| *a += *b + *c);
591    /// assert_eq!(vector![9, 2, 3, 4, 5], vec);
592    /// ```
593    #[allow(unsafe_code)]
594    pub fn triplet<F, B>(&mut self, a: usize, b: usize, c: usize, mut f: F) -> B
595    where
596        F: FnMut(&mut A, &mut A, &mut A) -> B,
597    {
598        if a == b || b == c || a == c {
599            panic!("vector::FocusMut::triplet: indices cannot be equal!");
600        }
601        let pa: *mut A = self.index_mut(a);
602        let pb: *mut A = self.index_mut(b);
603        let pc: *mut A = self.index_mut(c);
604        unsafe { f(&mut *pa, &mut *pb, &mut *pc) }
605    }
606
607    /// Get the chunk for the given index.
608    ///
609    /// This gives you a reference to the leaf node that contains the index,
610    /// along with its start and end indices.
611    pub fn chunk_at(&mut self, index: usize) -> (Range<usize>, &mut [A]) {
612        let len = self.len();
613        if index >= len {
614            panic!("vector::FocusMut::chunk_at: index out of bounds");
615        }
616        match self {
617            FocusMut::Single(_, chunk) => (0..len, chunk),
618            FocusMut::Full(pool, tree) => {
619                let (range, chunk) = tree.get_chunk(pool, index);
620                (range, chunk)
621            }
622        }
623    }
624
625    /// Narrow the focus onto a subslice of the vector.
626    ///
627    /// `FocusMut::narrow(range)` has the same effect as `&slice[range]`, without
628    /// actually modifying the underlying vector.
629    ///
630    /// Panics if the range isn't fully inside the current focus.
631    ///
632    /// ## Examples
633    ///
634    /// ```rust
635    /// # #[macro_use] extern crate im_rc as im;
636    /// # use im::vector::Vector;
637    /// # use std::iter::FromIterator;
638    /// let mut vec = Vector::from_iter(0..1000);
639    /// let narrowed = vec.focus_mut().narrow(100..200);
640    /// let narrowed_vec = narrowed.unmut().into_iter().cloned().collect();
641    /// assert_eq!(Vector::from_iter(100..200), narrowed_vec);
642    /// ```
643    ///
644    /// [slice::split_at]: https://doc.rust-lang.org/std/primitive.slice.html#method.split_at
645    /// [Vector::split_at]: enum.Vector.html#method.split_at
646    pub fn narrow<R>(self, range: R) -> Self
647    where
648        R: RangeBounds<usize>,
649    {
650        let r = to_range(&range, self.len());
651        if r.start > r.end || r.start > self.len() {
652            panic!("vector::FocusMut::narrow: range out of bounds");
653        }
654        match self {
655            FocusMut::Single(pool, chunk) => FocusMut::Single(pool, &mut chunk[r]),
656            FocusMut::Full(pool, tree) => FocusMut::Full(pool, tree.narrow(r)),
657        }
658    }
659
660    /// Split the focus into two.
661    ///
662    /// Given an index `index`, consume the focus and produce two new foci, the
663    /// left onto indices `0..index`, and the right onto indices `index..N`
664    /// where `N` is the length of the current focus.
665    ///
666    /// Panics if the index is out of bounds.
667    ///
668    /// This is the moral equivalent of [`slice::split_at`][slice::split_at], in
669    /// that it leaves the underlying data structure unchanged, unlike
670    /// [`Vector::split_at`][Vector::split_at].
671    ///
672    /// ## Examples
673    ///
674    /// ```rust
675    /// # #[macro_use] extern crate im_rc as im;
676    /// # use im::vector::Vector;
677    /// # use std::iter::FromIterator;
678    /// let mut vec = Vector::from_iter(0..1000);
679    /// {
680    ///     let (left, right) = vec.focus_mut().split_at(500);
681    ///     for ptr in left {
682    ///         *ptr += 100;
683    ///     }
684    ///     for ptr in right {
685    ///         *ptr -= 100;
686    ///     }
687    /// }
688    /// let expected = Vector::from_iter(100..600)
689    ///              + Vector::from_iter(400..900);
690    /// assert_eq!(expected, vec);
691    /// ```
692    ///
693    /// [slice::split_at]: https://doc.rust-lang.org/std/primitive.slice.html#method.split_at
694    /// [Vector::split_at]: enum.Vector.html#method.split_at
695    #[allow(clippy::redundant_clone)]
696    pub fn split_at(self, index: usize) -> (Self, Self) {
697        if index > self.len() {
698            panic!("vector::FocusMut::split_at: index out of bounds");
699        }
700        match self {
701            FocusMut::Single(pool, chunk) => {
702                let (left, right) = chunk.split_at_mut(index);
703                (
704                    FocusMut::Single(pool.clone(), left),
705                    FocusMut::Single(pool, right),
706                )
707            }
708            FocusMut::Full(pool, tree) => {
709                let (left, right) = tree.split_at(index);
710                (
711                    FocusMut::Full(pool.clone(), left),
712                    FocusMut::Full(pool, right),
713                )
714            }
715        }
716    }
717
718    /// Convert a `FocusMut` into a `Focus`.
719    pub fn unmut(self) -> Focus<'a, A> {
720        match self {
721            FocusMut::Single(_, chunk) => Focus::Single(chunk),
722            FocusMut::Full(_, mut tree) => Focus::Full(TreeFocus {
723                tree: {
724                    let t = tree.tree.lock().unwrap();
725                    (*t).clone()
726                },
727                view: tree.view.clone(),
728                middle_range: tree.middle_range.clone(),
729                target_range: 0..0,
730                target_ptr: null(),
731            }),
732        }
733    }
734}
735
736impl<'a, A> IntoIterator for FocusMut<'a, A>
737where
738    A: Clone + 'a,
739{
740    type Item = &'a mut A;
741    type IntoIter = IterMut<'a, A>;
742
743    fn into_iter(self) -> Self::IntoIter {
744        IterMut::from_focus(self)
745    }
746}
747
748impl<'a, A> From<FocusMut<'a, A>> for Focus<'a, A>
749where
750    A: Clone + 'a,
751{
752    fn from(f: FocusMut<'a, A>) -> Self {
753        f.unmut()
754    }
755}
756
757pub struct TreeFocusMut<'a, A> {
758    tree: Lock<&'a mut Rrb<A>>,
759    view: Range<usize>,
760    middle_range: Range<usize>,
761    target_range: Range<usize>,
762    target_ptr: AtomicPtr<Chunk<A>>,
763}
764
765impl<'a, A> TreeFocusMut<'a, A>
766where
767    A: Clone + 'a,
768{
769    fn new(tree: &'a mut Rrb<A>) -> Self {
770        let middle_start = tree.outer_f.len() + tree.inner_f.len();
771        let middle_end = middle_start + tree.middle.len();
772        TreeFocusMut {
773            view: 0..tree.length,
774            tree: Lock::new(tree),
775            middle_range: middle_start..middle_end,
776            target_range: 0..0,
777            target_ptr: AtomicPtr::default(),
778        }
779    }
780
781    fn len(&self) -> usize {
782        self.view.end - self.view.start
783    }
784
785    fn narrow(self, mut view: Range<usize>) -> Self {
786        view.start += self.view.start;
787        view.end += self.view.start;
788        TreeFocusMut {
789            view,
790            middle_range: self.middle_range.clone(),
791            target_range: 0..0,
792            target_ptr: AtomicPtr::default(),
793            tree: self.tree,
794        }
795    }
796
797    fn split_at(self, index: usize) -> (Self, Self) {
798        let len = self.len();
799        debug_assert!(index <= len);
800        #[allow(unsafe_code)]
801        let left = TreeFocusMut {
802            view: self.view.start..(self.view.start + index),
803            middle_range: self.middle_range.clone(),
804            target_range: 0..0,
805            target_ptr: AtomicPtr::default(),
806            tree: self.tree.clone(),
807        };
808        let right = TreeFocusMut {
809            view: (self.view.start + index)..(self.view.start + len),
810            middle_range: self.middle_range.clone(),
811            target_range: 0..0,
812            target_ptr: AtomicPtr::default(),
813            tree: self.tree,
814        };
815        (left, right)
816    }
817
818    fn physical_index(&self, index: usize) -> usize {
819        debug_assert!(index < self.view.end);
820        self.view.start + index
821    }
822
823    fn logical_range(&self, range: &Range<usize>) -> Range<usize> {
824        (range.start - self.view.start)..(range.end - self.view.start)
825    }
826
827    fn set_focus(&mut self, pool: &RRBPool<A>, index: usize) {
828        let mut tree = self
829            .tree
830            .lock()
831            .expect("im::vector::Focus::set_focus: unable to acquire exclusive lock on Vector");
832        if index < self.middle_range.start {
833            let outer_len = tree.outer_f.len();
834            if index < outer_len {
835                self.target_range = 0..outer_len;
836                self.target_ptr.store(
837                    PoolRef::make_mut(&pool.value_pool, &mut tree.outer_f),
838                    Ordering::Relaxed,
839                );
840            } else {
841                self.target_range = outer_len..self.middle_range.start;
842                self.target_ptr.store(
843                    PoolRef::make_mut(&pool.value_pool, &mut tree.inner_f),
844                    Ordering::Relaxed,
845                );
846            }
847        } else if index >= self.middle_range.end {
848            let outer_start = self.middle_range.end + tree.inner_b.len();
849            if index < outer_start {
850                self.target_range = self.middle_range.end..outer_start;
851                self.target_ptr.store(
852                    PoolRef::make_mut(&pool.value_pool, &mut tree.inner_b),
853                    Ordering::Relaxed,
854                );
855            } else {
856                self.target_range = outer_start..tree.length;
857                self.target_ptr.store(
858                    PoolRef::make_mut(&pool.value_pool, &mut tree.outer_b),
859                    Ordering::Relaxed,
860                );
861            }
862        } else {
863            let tree_index = index - self.middle_range.start;
864            let level = tree.middle_level;
865            let middle = Ref::make_mut(&mut tree.middle);
866            let (range, ptr) = middle.lookup_chunk_mut(pool, level, 0, tree_index);
867            self.target_range =
868                (range.start + self.middle_range.start)..(range.end + self.middle_range.start);
869            self.target_ptr.store(ptr, Ordering::Relaxed);
870        }
871    }
872
873    #[allow(unsafe_code)]
874    fn get_focus(&mut self) -> &mut Chunk<A> {
875        unsafe { &mut *self.target_ptr.load(Ordering::Relaxed) }
876    }
877
878    pub fn get(&mut self, pool: &RRBPool<A>, index: usize) -> Option<&mut A> {
879        if index >= self.len() {
880            return None;
881        }
882        let phys_index = self.physical_index(index);
883        if !contains(&self.target_range, &phys_index) {
884            self.set_focus(pool, phys_index);
885        }
886        let target_phys_index = phys_index - self.target_range.start;
887        Some(&mut self.get_focus()[target_phys_index])
888    }
889
890    pub fn get_chunk(&mut self, pool: &RRBPool<A>, index: usize) -> (Range<usize>, &mut [A]) {
891        let phys_index = self.physical_index(index);
892        if !contains(&self.target_range, &phys_index) {
893            self.set_focus(pool, phys_index);
894        }
895        let mut left = 0;
896        let mut right = 0;
897        if self.target_range.start < self.view.start {
898            left = self.view.start - self.target_range.start;
899        }
900        if self.target_range.end > self.view.end {
901            right = self.target_range.end - self.view.end;
902        }
903        let phys_range = (self.target_range.start + left)..(self.target_range.end - right);
904        let log_range = self.logical_range(&phys_range);
905        let slice_len = self.get_focus().len();
906        let slice = &mut (self.get_focus().as_mut_slice())[left..(slice_len - right)];
907        (log_range, slice)
908    }
909}