You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
An index list is a hybrid between a vector and a linked-list, with some of the properties of each. Every element has an index in the vector and can be accessed directly there. This index is persistent as long as the element remains in the list and is not affected by other elements of the list. An index does not change if the element is moved in the list, nor when other elements are inserted or removed from the list.
6
6
7
7
The user is not meant to know the exact value of the index and should not create any Indexes themselves, but can safely copy an existing one. The index should only be used for the purpose of accessing the element data at that location or to traverse the list. This is why almost all methods on the Indexes are private.
@@ -15,13 +15,15 @@ Old indexes will be reused in FIFO fashion, before new indexes are added.
15
15
The list elements are placed in a vector, which is why they can be accessed directly, where each element knows the index of the element before and after it, as well as the data contained at that index. This indirection makes it easy to implement the list safely in Rust, because the traditional next and previous pointers are replaced by their respective indexes, which are just numbers.
16
16
17
17
You can think of a list node like this:
18
+
18
19
```rust
19
20
structIndexElem<T> {
20
-
next:Option<u32>,
21
-
prev:Option<u32>,
22
-
data:Option<T>,
21
+
next:Option<u32>,
22
+
prev:Option<u32>,
23
+
data:Option<T>,
23
24
}
24
25
```
26
+
25
27
Where an element without data is free and if either `next` or `prev` is `None` then that is the end of the list in that direction.
26
28
27
29
## The element vector
@@ -34,7 +36,7 @@ To walk the list the user needs a starting index. One can be obtained from eithe
34
36
35
37
See the included [example code](examples/indexlist.rs) for how this works.
36
38
37
-
Note that any calls to the `trim_swap` method, may invalidate one or more index. It van be verified because any index greater than the `capacity` has been moved. To prevent this invalidation, you can hold a reference to the list as well as the index, but this will also block any and all modifications to the list while the reference is held.
39
+
Note that any calls to the `trim_swap` method, may invalidate one or more index. It can be verified because any index greater than the `capacity` has been moved. To prevent this invalidation, you can hold a reference to the list as well as the index, but this will also block any and all modifications to the list while the reference is held.
38
40
39
41
## The list capacity
40
42
@@ -75,8 +77,8 @@ The core of this crate is implemented in 100% safe Rust, with no `unsafe` code b
75
77
76
78
However, there are two things to be aware of:
77
79
78
-
1.The `trim_swap` method, while being 100% safe, is considered "unsafe" from a logical point of view because it can invalidate indexes. If you have cached an index somewhere, it may point to a different element after `trim_swap` is called. Use this method with care.
79
-
2.The optional `iter_mut` feature uses a small `unsafe` block to create a mutable iterator. This is a common pattern for this kind of data structure, but it is important to be aware of it.
80
+
1. The `trim_swap` method, while being 100% safe, is considered "unsafe" from a logical point of view because it can invalidate indexes. If you have cached an index somewhere, it may point to a different element after `trim_swap` is called. Use this method with care.
81
+
2. The optional `iter_mut` feature uses a small `unsafe` block to create a mutable iterator. This is a common pattern for this kind of data structure, but it is important to be aware of it.
80
82
81
83
## Performance
82
84
@@ -88,13 +90,13 @@ This crate comes with a comprehensive benchmark suite that compares `IndexList`
88
90
89
91
### Available Benchmarks
90
92
91
-
***head:** Measures the performance of adding and removing elements from the front of the list.
92
-
***tail:** Measures the performance of adding and removing elements from the back of the list.
93
-
***body:** Measures the performance of inserting and removing elements in the middle of the list.
94
-
***random:** Measures the performance of inserting and removing elements at random positions.
95
-
***walk:** Measures the performance of iterating through the list using `next_index` and `prev_index`.
96
-
***iter:** Measures the performance of iterating through the list using the `iter()` method.
97
-
***iter_mut:** Measures the performance of mutable iteration using the `iter_mut()` method.
93
+
-**head:** Measures the performance of adding and removing elements from the front of the list.
94
+
-**tail:** Measures the performance of adding and removing elements from the back of the list.
95
+
-**body:** Measures the performance of inserting and removing elements in the middle of the list.
96
+
-**random:** Measures the performance of inserting and removing elements at random positions.
97
+
-**walk:** Measures the performance of iterating through the list using `next_index` and `prev_index`.
98
+
-**iter:** Measures the performance of iterating through the list using the `iter()` method.
99
+
-**iter_mut:** Measures the performance of mutable iteration using the `iter_mut()` method.
98
100
99
101
> NOTE: These benchmarks may not reflect any real-life performance difference and you are urged to evaluate this in your own use-case rather than relying on the figures provided by the included benchmarks.
100
102
@@ -134,34 +136,34 @@ This project is licensed under the [Mozilla Public License, v. 2.0](LICENSE).
134
136
135
137
## Reasons to use IndexList
136
138
137
-
* Data that is frequently inserted or removed from the body of the list (not the ends).
138
-
* Use-case where walking the list is required.
139
-
* Data that is reordered often, or sorted.
140
-
* Need persistent indexes even when data is inserted or removed.
141
-
* Want to maintain skip elements for taking larger steps through the list.
142
-
* Need to cache certain elements for fast retrieval, without holding a reference to it.
139
+
- Data that is frequently inserted or removed from the body of the list (not the ends).
140
+
- Use-case where walking the list is required.
141
+
- Data that is reordered often, or sorted.
142
+
- Need persistent indexes even when data is inserted or removed.
143
+
- Want to maintain skip elements for taking larger steps through the list.
144
+
- Need to cache certain elements for fast retrieval, without holding a reference to it.
143
145
144
146
## Reasons to use other alternatives
145
147
146
-
* Data that is mainly inserted and removed at the ends of the list, then VecDeque is likely a better alternative.
147
-
* Merges and splits of the lists are common; these are heavy `O(n)` operations in the IndexList design. The LinkedList is likely much better in this respect.
148
-
* When handling lists longer than 4 billion entries, as this list is limited to 32-bit indexes.
149
-
* When you need to shrink the list often, because `trim_swap` is expensive and has the side-effect of potentially invalidating indexes. For instance a LinkedList does not require trimming at all.
148
+
- Data that is mainly inserted and removed at the ends of the list, then VecDeque is likely a better alternative.
149
+
- Merges and splits of the lists are common; these are heavy `O(n)` operations in the IndexList design. The LinkedList is likely much better in this respect.
150
+
- When handling lists longer than 4 billion entries, as this list is limited to 32-bit indexes.
151
+
- When you need to shrink the list often, because `trim_swap` is expensive and has the side-effect of potentially invalidating indexes. For instance a LinkedList does not require trimming at all.
150
152
151
153
This is not an exhaustive list of alternatives, and I may have missed important choices, but these were the ones that I was aware of at the time of writing this.
0 commit comments