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/.
5 use std
::mem
::{replace, swap}
;
6 use std
::ops
::{Range, RangeBounds}
;
8 use std
::sync
::atomic
::{AtomicPtr, Ordering}
;
10 use nodes
::chunk
::Chunk
;
12 use util
::{to_range, Ref}
;
13 use vector
::{Iter, IterMut, Vector, RRB}
;
15 /// Focused indexing over a [`Vector`][Vector].
17 /// By remembering the last tree node accessed through an index lookup and the
18 /// path we took to get there, we can speed up lookups for adjacent indices
19 /// tremendously. Lookups on indices in the same node are instantaneous, and
20 /// lookups on sibling nodes are also very fast.
22 /// A `Focus` can also be used as a restricted view into a vector, using the
23 /// [`narrow`][narrow] and [`split_at`][split_at] methods.
25 /// # When should I use a `Focus` for better performance?
27 /// `Focus` is useful when you need to perform a large number of index lookups
28 /// that are more likely than not to be close to each other. It's usually worth
29 /// using a `Focus` in any situation where you're batching a lot of index
30 /// lookups together, even if they're not obviously adjacent - there's likely
31 /// to be some performance gain for even completely random access.
33 /// If you're just iterating forwards or backwards over the [`Vector`][Vector]
34 /// in order, you're better off with a regular iterator, which, in fact, is
35 /// implemented using a `Focus`, but provides a simpler interface.
37 /// If you're just doing a very small number of index lookups, the setup cost
38 /// for the `Focus` is probably not worth it.
40 /// A `Focus` is never faster than an index lookup on a small [`Vector`][Vector]
41 /// with a length below the internal RRB tree's branching factor of 64.
45 /// This example is contrived, as the better way to iterate forwards or
46 /// backwards over a vector is with an actual iterator. Even so, the version
47 /// using a `Focus` should run nearly an order of magnitude faster than the
48 /// version using index lookups at a length of 1000. It should also be noted
49 /// that [`vector::Iter`][Iter] is actually implemented using a `Focus` behind
50 /// the scenes, so the performance of the two should be identical.
53 /// # #[macro_use] extern crate im_rc as im;
54 /// # use im::vector::Vector;
55 /// # use std::iter::FromIterator;
57 /// let mut vec: Vector<i64> = Vector::from_iter(0..1000);
59 /// // Summing a vector, the slow way:
61 /// for i in 0..1000 {
62 /// sum += *vec.get(i).unwrap();
64 /// assert_eq!(499500, sum);
66 /// // Summing a vector faster using a Focus:
68 /// let mut focus = vec.focus();
69 /// for i in 0..1000 {
70 /// sum += *focus.get(i).unwrap();
72 /// assert_eq!(499500, sum);
74 /// // And the easy way, for completeness:
75 /// let sum: i64 = vec.iter().sum();
76 /// assert_eq!(499500, sum);
80 /// [Vector]: enum.Vector.html
81 /// [Iter]: struct.Iter.html
82 /// [narrow]: #method.narrow
83 /// [split_at]: #method.split_at
94 impl<'a
, A
> Focus
<'a
, A
>
98 /// Construct a `Focus` for a [`Vector`][Vector].
100 /// [Vector]: enum.Vector.html
101 pub fn new(vector
: &'a Vector
<A
>) -> Self {
103 Vector
::Single(chunk
) => Focus
::Single(chunk
),
104 Vector
::Full(tree
) => Focus
::Full(TreeFocus
::new(tree
)),
108 /// Get the length of the focused [`Vector`][Vector].
110 /// [Vector]: enum.Vector.html
111 pub fn len(&self) -> usize {
113 Focus
::Single(chunk
) => chunk
.len(),
114 Focus
::Full(tree
) => tree
.len(),
118 /// Test if the focused [`Vector`][Vector] is empty.
120 /// [Vector]: enum.Vector.html
121 pub fn is_empty(&self) -> bool
{
125 /// Get a reference to the value at a given index.
126 pub fn get(&mut self, index
: usize) -> Option
<&A
> {
128 Focus
::Single(chunk
) => chunk
.get(index
),
129 Focus
::Full(tree
) => tree
.get(index
),
133 /// Get a reference to the value at a given index.
135 /// Panics if the index is out of bounds.
136 pub fn index(&mut self, index
: usize) -> &A
{
137 self.get(index
).expect("index out of bounds")
140 /// Get the chunk for the given index.
142 /// This gives you a reference to the leaf node that contains the index,
143 /// along with its start and end indices.
144 pub fn chunk_at(&mut self, index
: usize) -> (Range
<usize>, &[A
]) {
145 let len
= self.len();
147 panic
!("vector::Focus::chunk_at: index out of bounds");
150 Focus
::Single(chunk
) => (0..len
, chunk
),
151 Focus
::Full(tree
) => tree
.get_chunk(index
),
155 /// Narrow the focus onto a subslice of the vector.
157 /// `Focus::narrow(range)` has the same effect as `&slice[range]`, without
158 /// actually modifying the underlying vector.
160 /// Panics if the range isn't fully inside the current focus.
165 /// # #[macro_use] extern crate im_rc as im;
166 /// # use im::vector::Vector;
167 /// # use std::iter::FromIterator;
169 /// let vec = Vector::from_iter(0..1000);
170 /// let narrowed = vec.focus().narrow(100..200);
171 /// let narrowed_vec = narrowed.into_iter().cloned().collect();
172 /// assert_eq!(Vector::from_iter(100..200), narrowed_vec);
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 pub fn narrow
<R
>(self, range
: R
) -> Self
180 R
: RangeBounds
<usize>,
182 let r
= to_range(&range
, self.len());
183 if r
.start
>= r
.end
|| r
.start
>= self.len() {
184 panic
!("vector::Focus::narrow: range out of bounds");
187 Focus
::Single(chunk
) => Focus
::Single(&chunk
[r
]),
188 Focus
::Full(tree
) => Focus
::Full(tree
.narrow(r
)),
192 /// Split the focus into two.
194 /// Given an index `index`, consume the focus and produce two new foci, the
195 /// left onto indices `0..index`, and the right onto indices `index..N`
196 /// where `N` is the length of the current focus.
198 /// Panics if the index is out of bounds.
200 /// This is the moral equivalent of [`slice::split_at`][slice::split_at], in
201 /// that it leaves the underlying data structure unchanged, unlike
202 /// [`Vector::split_at`][Vector::split_at].
207 /// # #[macro_use] extern crate im_rc as im;
208 /// # use im::vector::Vector;
209 /// # 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);
220 /// [slice::split_at]: https://doc.rust-lang.org/std/primitive.slice.html#method.split_at
221 /// [Vector::split_at]: enum.Vector.html#method.split_at
222 pub fn split_at(self, index
: usize) -> (Self, Self) {
223 if index
>= self.len() {
224 panic
!("vector::Focus::split_at: index out of bounds");
227 Focus
::Single(chunk
) => {
228 let (left
, right
) = chunk
.split_at(index
);
229 (Focus
::Single(left
), Focus
::Single(right
))
231 Focus
::Full(tree
) => {
232 let (left
, right
) = tree
.split_at(index
);
233 (Focus
::Full(left
), Focus
::Full(right
))
239 impl<'a
, A
> IntoIterator
for Focus
<'a
, A
>
244 type IntoIter
= Iter
<'a
, A
>;
246 fn into_iter(self) -> Self::IntoIter
{
247 Iter
::from_focus(self)
251 impl<'a
, A
> Clone
for Focus
<'a
, A
>
255 fn clone(&self) -> Self {
257 Focus
::Single(chunk
) => Focus
::Single(chunk
),
258 Focus
::Full(tree
) => Focus
::Full(tree
.clone()),
263 pub struct TreeFocus
<A
> {
266 middle_range
: Range
<usize>,
267 target_range
: Range
<usize>,
268 target_ptr
: *const Chunk
<A
>,
271 impl<A
> Clone
for TreeFocus
<A
> {
272 fn clone(&self) -> Self {
273 let tree
= self.tree
.clone();
275 view
: self.view
.clone(),
276 middle_range
: self.middle_range
.clone(),
284 #[allow(unsafe_code)]
286 unsafe impl<A
> Send
for TreeFocus
<A
> {}
287 #[allow(unsafe_code)]
289 unsafe impl<A
> Sync
for TreeFocus
<A
> {}
292 fn contains
<A
: Ord
>(range
: &Range
<A
>, index
: &A
) -> bool
{
293 *index
>= range
.start
&& *index
< range
.end
300 fn new(tree
: &RRB
<A
>) -> Self {
301 let middle_start
= tree
.outer_f
.len() + tree
.inner_f
.len();
302 let middle_end
= middle_start
+ tree
.middle
.len();
305 view
: 0..tree
.length
,
306 middle_range
: middle_start
..middle_end
,
312 fn len(&self) -> usize {
313 self.view
.end
- self.view
.start
316 fn narrow(self, mut view
: Range
<usize>) -> Self {
317 view
.start
+= self.view
.start
;
318 view
.end
+= self.view
.start
;
321 middle_range
: self.middle_range
.clone(),
328 fn split_at(self, index
: usize) -> (Self, Self) {
329 let len
= self.len();
330 let left
= self.clone().narrow(0..index
);
331 let right
= self.narrow(index
..len
);
335 fn physical_index(&self, index
: usize) -> usize {
336 debug_assert
!(index
< self.view
.end
);
337 self.view
.start
+ index
340 fn logical_range(&self, range
: &Range
<usize>) -> Range
<usize> {
341 (range
.start
- self.view
.start
)..(range
.end
- self.view
.start
)
344 fn set_focus(&mut self, index
: usize) {
345 if index
< self.middle_range
.start
{
346 let outer_len
= self.tree
.outer_f
.len();
347 if index
< outer_len
{
348 self.target_range
= 0..outer_len
;
349 self.target_ptr
= &*self.tree
.outer_f
;
351 self.target_range
= outer_len
..self.middle_range
.start
;
352 self.target_ptr
= &*self.tree
.inner_f
;
354 } else if index
>= self.middle_range
.end
{
355 let outer_start
= self.middle_range
.end
+ self.tree
.inner_b
.len();
356 if index
< outer_start
{
357 self.target_range
= self.middle_range
.end
..outer_start
;
358 self.target_ptr
= &*self.tree
.inner_b
;
360 self.target_range
= outer_start
..self.tree
.length
;
361 self.target_ptr
= &*self.tree
.outer_b
;
364 let tree_index
= index
- self.middle_range
.start
;
365 let (range
, ptr
) = self
368 .lookup_chunk(self.tree
.middle_level
, 0, tree_index
);
370 (range
.start
+ self.middle_range
.start
)..(range
.end
+ self.middle_range
.start
);
371 self.target_ptr
= ptr
;
375 #[allow(unsafe_code)]
376 fn get_focus(&self) -> &Chunk
<A
> {
377 unsafe { &*self.target_ptr }
380 pub fn get(&mut self, index
: usize) -> Option
<&A
> {
381 if index
>= self.len() {
384 let phys_index
= self.physical_index(index
);
385 if !contains(&self.target_range
, &phys_index
) {
386 self.set_focus(phys_index
);
388 let target_phys_index
= phys_index
- self.target_range
.start
;
389 Some(&self.get_focus()[target_phys_index
])
392 pub fn get_chunk(&mut self, index
: usize) -> (Range
<usize>, &[A
]) {
393 let phys_index
= self.physical_index(index
);
394 if !contains(&self.target_range
, &phys_index
) {
395 self.set_focus(phys_index
);
397 let mut slice
: &[A
] = self.get_focus();
400 if self.target_range
.start
< self.view
.start
{
401 left
= self.view
.start
- self.target_range
.start
;
403 if self.target_range
.end
> self.view
.end
{
404 right
= self.target_range
.end
- self.view
.end
;
406 slice
= &slice
[left
..(slice
.len() - right
)];
407 let phys_range
= (self.target_range
.start
+ left
)..(self.target_range
.end
- right
);
408 (self.logical_range(&phys_range
), slice
)
412 /// A mutable version of [`Focus`][Focus].
414 /// See [`Focus`][Focus] for more details.
416 /// You can only build one `FocusMut` at a time for a vector, effectively
417 /// keeping a lock on the vector until you're done with the focus, which relies
418 /// on the structure of the vector not changing while it exists.
420 /// ```rust,compile_fail
421 /// # #[macro_use] extern crate im_rc as im;
422 /// # use im::vector::Vector;
423 /// # use std::iter::FromIterator;
425 /// let mut vec = Vector::from_iter(0..1000);
426 /// let focus1 = vec.focus_mut();
427 /// // Fails here because you already have a focus
428 /// let focus2 = vec.focus_mut();
432 /// On the other hand, you can split that one focus into multiple sub-foci,
433 /// which is safe because they can't overlap:
436 /// # #[macro_use] extern crate im_rc as im;
437 /// # use im::vector::Vector;
438 /// # use std::iter::FromIterator;
440 /// let mut vec = Vector::from_iter(0..1000);
441 /// let focus = vec.focus_mut();
442 /// let (left, right) = focus.split_at(500);
446 /// These sub-foci also work as a lock on the vector, even if the focus they
447 /// were created from goes out of scope.
449 /// ```rust,compile_fail
450 /// # #[macro_use] extern crate im_rc as im;
451 /// # use im::vector::Vector;
452 /// # use std::iter::FromIterator;
454 /// let mut vec = Vector::from_iter(0..1000);
455 /// let (left, right) = {
456 /// let focus = vec.focus_mut();
457 /// focus.split_at(500)
459 /// // `left` and `right` are still in scope even if `focus` isn't, so we can't
460 /// // create another focus:
461 /// let focus2 = vec.focus_mut();
465 /// [Focus]: enum.Focus.html
466 pub enum FocusMut
<'a
, A
>
473 Full(TreeFocusMut
<'a
, A
>),
476 impl<'a
, A
> FocusMut
<'a
, A
>
480 /// Construct a `FocusMut` for a `Vector`.
481 pub fn new(vector
: &'a
mut Vector
<A
>) -> Self {
483 Vector
::Single(chunk
) => FocusMut
::Single(Ref
::make_mut(chunk
).as_mut_slice()),
484 Vector
::Full(tree
) => FocusMut
::Full(TreeFocusMut
::new(tree
)),
488 /// Get the length of the focused `Vector`.
489 pub fn len(&self) -> usize {
491 FocusMut
::Single(chunk
) => chunk
.len(),
492 FocusMut
::Full(tree
) => tree
.len(),
496 /// Test if the focused `Vector` is empty.
497 pub fn is_empty(&self) -> bool
{
501 /// Get a reference to the value at a given index.
502 pub fn get(&mut self, index
: usize) -> Option
<&A
> {
503 self.get_mut(index
).map(|r
| &*r
)
506 /// Get a mutable reference to the value at a given index.
507 pub fn get_mut(&mut self, index
: usize) -> Option
<&mut A
> {
509 FocusMut
::Single(chunk
) => chunk
.get_mut(index
),
510 FocusMut
::Full(tree
) => tree
.get(index
),
514 /// Get a reference to the value at a given index.
516 /// Panics if the index is out of bounds.
517 pub fn index(&mut self, index
: usize) -> &A
{
518 &*self.index_mut(index
)
521 /// Get a mutable reference to the value at a given index.
523 /// Panics if the index is out of bounds.
524 #[allow(clippy::should_implement_trait)] // would if I could
525 pub fn index_mut(&mut self, index
: usize) -> &mut A
{
526 self.get_mut(index
).expect("index out of bounds")
529 /// Update the value at a given index.
531 /// Returns `None` if the index is out of bounds, or the replaced value
533 pub fn set(&mut self, index
: usize, value
: A
) -> Option
<A
> {
534 match self.get_mut(index
) {
535 Some(ref mut pos
) => Some(replace(pos
, value
)),
540 /// Swap the values at two given indices.
542 /// Panics if either index is out of bounds.
544 /// If the indices are equal, this function returns without doing anything.
545 pub fn swap(&mut self, a
: usize, b
: usize) {
549 self.pair(a
, b
, |left
, right
| swap(left
, right
));
552 /// Lookup two indices simultaneously and run a function over them.
554 /// Useful because the borrow checker won't let you have more than one
555 /// mutable reference into the same data structure at any given time.
557 /// Panics if either index is out of bounds, or if they are the same index.
562 /// # #[macro_use] extern crate im_rc as im;
563 /// # use im::vector::Vector;
564 /// # use std::iter::FromIterator;
566 /// let mut vec = vector![1, 2, 3, 4, 5];
567 /// vec.focus_mut().pair(1, 3, |a, b| *a += *b);
568 /// assert_eq!(vector![1, 6, 3, 4, 5], vec);
571 #[allow(unsafe_code)]
572 pub fn pair
<F
, B
>(&mut self, a
: usize, b
: usize, mut f
: F
) -> B
574 F
: FnMut(&mut A
, &mut A
) -> B
,
577 panic
!("vector::FocusMut::pair: indices cannot be equal!");
579 let pa
: *mut A
= self.index_mut(a
);
580 let pb
: *mut A
= self.index_mut(b
);
581 unsafe { f(&mut *pa, &mut *pb) }
584 /// Lookup three indices simultaneously and run a function over them.
586 /// Useful because the borrow checker won't let you have more than one
587 /// mutable reference into the same data structure at any given time.
589 /// Panics if any index is out of bounds, or if any indices are equal.
594 /// # #[macro_use] extern crate im_rc as im;
595 /// # use im::vector::Vector;
596 /// # use std::iter::FromIterator;
598 /// let mut vec = vector![1, 2, 3, 4, 5];
599 /// vec.focus_mut().triplet(0, 2, 4, |a, b, c| *a += *b + *c);
600 /// assert_eq!(vector![9, 2, 3, 4, 5], vec);
603 #[allow(unsafe_code)]
604 pub fn triplet
<F
, B
>(&mut self, a
: usize, b
: usize, c
: usize, mut f
: F
) -> B
606 F
: FnMut(&mut A
, &mut A
, &mut A
) -> B
,
608 if a
== b
|| b
== c
|| a
== c
{
609 panic
!("vector::FocusMut::triplet: indices cannot be equal!");
611 let pa
: *mut A
= self.index_mut(a
);
612 let pb
: *mut A
= self.index_mut(b
);
613 let pc
: *mut A
= self.index_mut(c
);
614 unsafe { f(&mut *pa, &mut *pb, &mut *pc) }
617 /// Get the chunk for the given index.
619 /// This gives you a reference to the leaf node that contains the index,
620 /// along with its start and end indices.
621 pub fn chunk_at(&mut self, index
: usize) -> (Range
<usize>, &mut [A
]) {
622 let len
= self.len();
624 panic
!("vector::FocusMut::chunk_at: index out of bounds");
627 FocusMut
::Single(chunk
) => (0..len
, chunk
),
628 FocusMut
::Full(tree
) => {
629 let (range
, chunk
) = tree
.get_chunk(index
);
635 /// Narrow the focus onto a subslice of the vector.
637 /// `FocusMut::narrow(range)` has the same effect as `&slice[range]`, without
638 /// actually modifying the underlying vector.
640 /// Panics if the range isn't fully inside the current focus.
645 /// # #[macro_use] extern crate im_rc as im;
646 /// # use im::vector::Vector;
647 /// # use std::iter::FromIterator;
649 /// let mut vec = Vector::from_iter(0..1000);
650 /// let narrowed = vec.focus_mut().narrow(100..200);
651 /// let narrowed_vec = narrowed.unmut().into_iter().cloned().collect();
652 /// assert_eq!(Vector::from_iter(100..200), narrowed_vec);
656 /// [slice::split_at]: https://doc.rust-lang.org/std/primitive.slice.html#method.split_at
657 /// [Vector::split_at]: enum.Vector.html#method.split_at
658 pub fn narrow
<R
>(self, range
: R
) -> Self
660 R
: RangeBounds
<usize>,
662 let r
= to_range(&range
, self.len());
663 if r
.start
> r
.end
|| r
.start
> self.len() {
664 panic
!("vector::FocusMut::narrow: range out of bounds");
667 FocusMut
::Single(chunk
) => FocusMut
::Single(&mut chunk
[r
]),
668 FocusMut
::Full(tree
) => FocusMut
::Full(tree
.narrow(r
)),
672 /// Split the focus into two.
674 /// Given an index `index`, consume the focus and produce two new foci, the
675 /// left onto indices `0..index`, and the right onto indices `index..N`
676 /// where `N` is the length of the current focus.
678 /// Panics if the index is out of bounds.
680 /// This is the moral equivalent of [`slice::split_at`][slice::split_at], in
681 /// that it leaves the underlying data structure unchanged, unlike
682 /// [`Vector::split_at`][Vector::split_at].
687 /// # #[macro_use] extern crate im_rc as im;
688 /// # use im::vector::Vector;
689 /// # use std::iter::FromIterator;
691 /// let mut vec = Vector::from_iter(0..1000);
693 /// let (left, right) = vec.focus_mut().split_at(500);
694 /// for ptr in left {
697 /// for ptr in right {
701 /// let expected = Vector::from_iter(100..600)
702 /// + Vector::from_iter(400..900);
703 /// assert_eq!(expected, vec);
707 /// [slice::split_at]: https://doc.rust-lang.org/std/primitive.slice.html#method.split_at
708 /// [Vector::split_at]: enum.Vector.html#method.split_at
709 pub fn split_at(self, index
: usize) -> (Self, Self) {
710 if index
> self.len() {
711 panic
!("vector::FocusMut::split_at: index out of bounds");
714 FocusMut
::Single(chunk
) => {
715 let (left
, right
) = chunk
.split_at_mut(index
);
716 (FocusMut
::Single(left
), FocusMut
::Single(right
))
718 FocusMut
::Full(tree
) => {
719 let (left
, right
) = tree
.split_at(index
);
720 (FocusMut
::Full(left
), FocusMut
::Full(right
))
725 /// Convert a `FocusMut` into a `Focus`.
726 pub fn unmut(self) -> Focus
<'a
, A
> {
728 FocusMut
::Single(chunk
) => Focus
::Single(chunk
),
729 FocusMut
::Full(mut tree
) => Focus
::Full(TreeFocus
{
731 let t
= tree
.tree
.lock().unwrap();
734 view
: tree
.view
.clone(),
735 middle_range
: tree
.middle_range
.clone(),
743 impl<'a
, A
> IntoIterator
for FocusMut
<'a
, A
>
747 type Item
= &'a
mut A
;
748 type IntoIter
= IterMut
<'a
, A
>;
750 fn into_iter(self) -> Self::IntoIter
{
751 IterMut
::from_focus(self)
755 impl<'a
, A
> Into
<Focus
<'a
, A
>> for FocusMut
<'a
, A
>
759 fn into(self) -> Focus
<'a
, A
> {
764 pub struct TreeFocusMut
<'a
, A
>
768 tree
: Lock
<&'a
mut RRB
<A
>>,
770 middle_range
: Range
<usize>,
771 target_range
: Range
<usize>,
772 target_ptr
: AtomicPtr
<Chunk
<A
>>,
775 impl<'a
, A
> TreeFocusMut
<'a
, A
>
779 fn new(tree
: &'a
mut RRB
<A
>) -> Self {
780 let middle_start
= tree
.outer_f
.len() + tree
.inner_f
.len();
781 let middle_end
= middle_start
+ tree
.middle
.len();
783 view
: 0..tree
.length
,
784 tree
: Lock
::new(tree
),
785 middle_range
: middle_start
..middle_end
,
787 target_ptr
: AtomicPtr
::default(),
791 fn len(&self) -> usize {
792 self.view
.end
- self.view
.start
795 fn narrow(self, mut view
: Range
<usize>) -> Self {
796 view
.start
+= self.view
.start
;
797 view
.end
+= self.view
.start
;
800 middle_range
: self.middle_range
.clone(),
802 target_ptr
: AtomicPtr
::default(),
807 fn split_at(self, index
: usize) -> (Self, Self) {
808 let len
= self.len();
809 debug_assert
!(index
<= len
);
810 #[allow(unsafe_code)]
811 let left
= TreeFocusMut
{
812 view
: self.view
.start
..(self.view
.start
+ index
),
813 middle_range
: self.middle_range
.clone(),
815 target_ptr
: AtomicPtr
::default(),
816 tree
: self.tree
.clone(),
818 let right
= TreeFocusMut
{
819 view
: (self.view
.start
+ index
)..(self.view
.start
+ len
),
820 middle_range
: self.middle_range
.clone(),
822 target_ptr
: AtomicPtr
::default(),
828 fn physical_index(&self, index
: usize) -> usize {
829 debug_assert
!(index
< self.view
.end
);
830 self.view
.start
+ index
833 fn logical_range(&self, range
: &Range
<usize>) -> Range
<usize> {
834 (range
.start
- self.view
.start
)..(range
.end
- self.view
.start
)
837 fn set_focus(&mut self, index
: usize) {
841 .expect("im::vector::Focus::set_focus: unable to acquire exclusive lock on Vector");
842 if index
< self.middle_range
.start
{
843 let outer_len
= tree
.outer_f
.len();
844 if index
< outer_len
{
845 self.target_range
= 0..outer_len
;
847 .store(Ref
::make_mut(&mut tree
.outer_f
), Ordering
::Relaxed
);
849 self.target_range
= outer_len
..self.middle_range
.start
;
851 .store(Ref
::make_mut(&mut tree
.inner_f
), Ordering
::Relaxed
);
853 } else if index
>= self.middle_range
.end
{
854 let outer_start
= self.middle_range
.end
+ tree
.inner_b
.len();
855 if index
< outer_start
{
856 self.target_range
= self.middle_range
.end
..outer_start
;
858 .store(Ref
::make_mut(&mut tree
.inner_b
), Ordering
::Relaxed
);
860 self.target_range
= outer_start
..tree
.length
;
862 .store(Ref
::make_mut(&mut tree
.outer_b
), Ordering
::Relaxed
);
865 let tree_index
= index
- self.middle_range
.start
;
866 let level
= tree
.middle_level
;
867 let middle
= Ref
::make_mut(&mut tree
.middle
);
868 let (range
, ptr
) = middle
.lookup_chunk_mut(level
, 0, tree_index
);
870 (range
.start
+ self.middle_range
.start
)..(range
.end
+ self.middle_range
.start
);
871 self.target_ptr
.store(ptr
, Ordering
::Relaxed
);
875 #[allow(unsafe_code)]
876 fn get_focus(&mut self) -> &mut Chunk
<A
> {
877 unsafe { &mut *self.target_ptr.load(Ordering::Relaxed) }
880 pub fn get(&mut self, index
: usize) -> Option
<&mut A
> {
881 if index
>= self.len() {
884 let phys_index
= self.physical_index(index
);
885 if !contains(&self.target_range
, &phys_index
) {
886 self.set_focus(phys_index
);
888 let target_phys_index
= phys_index
- self.target_range
.start
;
889 Some(&mut self.get_focus()[target_phys_index
])
892 pub fn get_chunk(&mut self, index
: usize) -> (Range
<usize>, &mut [A
]) {
893 let phys_index
= self.physical_index(index
);
894 if !contains(&self.target_range
, &phys_index
) {
895 self.set_focus(phys_index
);
899 if self.target_range
.start
< self.view
.start
{
900 left
= self.view
.start
- self.target_range
.start
;
902 if self.target_range
.end
> self.view
.end
{
903 right
= self.target_range
.end
- self.view
.end
;
905 let phys_range
= (self.target_range
.start
+ left
)..(self.target_range
.end
- right
);
906 let log_range
= self.logical_range(&phys_range
);
907 let slice_len
= self.get_focus().len();
908 let slice
= &mut (self.get_focus().as_mut_slice())[left
..(slice_len
- right
)];