concurrent_slice/
lib.rs

1//! The crate extends slice-type types with methods for concurrent processing.
2
3mod chunk;
4mod chunks;
5mod common;
6mod guard;
7mod iter;
8mod slice;
9mod windows;
10
11pub use chunk::*;
12pub use chunks::*;
13pub use guard::*;
14pub use iter::*;
15pub use slice::*;
16pub use windows::*;
17
18#[cfg(test)]
19mod tests {
20    use super::*;
21    use itertools::izip;
22    use std::sync::Arc;
23
24    #[test]
25    fn merge_chunks_test() {
26        let orig: Vec<_> = (0..16).collect();
27
28        let mut chunks = orig.concurrent_chunks_by_division(3);
29        let _ = chunks.next().unwrap();
30        let _ = chunks.next().unwrap();
31        let _ = chunks.next().unwrap();
32
33        let guard = chunks.guard();
34        drop(chunks);
35        let new = guard.try_unwrap().unwrap();
36
37        assert!(izip!(new, 0..16).all(|(lhs, rhs)| lhs == rhs));
38    }
39
40    #[test]
41    fn concat_chunks_test() {
42        let orig: Vec<_> = (0..25).collect();
43
44        let mut chunks = orig.concurrent_chunks_by_division(4);
45        let chunk1 = chunks.next().unwrap();
46        let chunk2 = chunks.next().unwrap();
47        let chunk3 = chunks.next().unwrap();
48        let chunk4 = chunks.next().unwrap();
49        drop(chunks); // decrease ref count
50
51        let chunk12 = Chunk::cat(vec![chunk1, chunk2]);
52        assert!(izip!(&chunk12, 0..14).all(|(&lhs, rhs)| lhs == rhs));
53
54        let chunk34 = Chunk::cat(vec![chunk3, chunk4]);
55        assert!(izip!(&chunk34, 14..25).all(|(&lhs, rhs)| lhs == rhs));
56
57        let chunk1234 = Chunk::cat(vec![chunk12, chunk34]);
58        assert!(izip!(&chunk1234, 0..25).all(|(&lhs, rhs)| lhs == rhs));
59
60        let guard = chunk1234.guard();
61        drop(chunk1234);
62        let new = guard.try_unwrap().unwrap();
63
64        assert!(izip!(&new, 0..25).all(|(&lhs, rhs)| lhs == rhs));
65    }
66
67    #[test]
68    fn concurrent_chunks_test() {
69        let vec: Vec<_> = (0..16).collect();
70        let chunks: Vec<_> = vec.concurrent_chunks_by_division(3).collect();
71        assert_eq!(chunks.len(), 3);
72        assert!(izip!(&chunks[0], 0..6).all(|(&lhs, rhs)| lhs == rhs));
73        assert!(izip!(&chunks[1], 6..12).all(|(&lhs, rhs)| lhs == rhs));
74        assert!(izip!(&chunks[2], 12..16).all(|(&lhs, rhs)| lhs == rhs));
75    }
76
77    #[test]
78    fn empty_concurrent_chunks_test() {
79        assert_eq!([(); 0].concurrent_chunks(2).count(), 0);
80        assert_eq!([(); 0].concurrent_chunks_by_division(None).count(), 0);
81    }
82
83    #[test]
84    fn owning_iter_test() {
85        let owner: Vec<_> = (0..3).collect();
86        let owner = Arc::new(owner);
87        let mut windows = owner.owning_iter();
88        assert_eq!(*windows.next().unwrap(), 0);
89        assert_eq!(*windows.next().unwrap(), 1);
90        assert_eq!(*windows.next().unwrap(), 2);
91        assert!(windows.next().is_none());
92    }
93
94    #[test]
95    fn owning_windows_test() {
96        let owner: Vec<_> = (0..5).collect();
97        let owner = Arc::new(owner);
98        let mut windows = owner.owning_windows(3);
99        assert_eq!(&*windows.next().unwrap(), &[0, 1, 2]);
100        assert_eq!(&*windows.next().unwrap(), &[1, 2, 3]);
101        assert_eq!(&*windows.next().unwrap(), &[2, 3, 4]);
102        assert!(windows.next().is_none());
103    }
104
105    #[test]
106    fn split_at_test() {
107        let vec: Vec<_> = (0..16).collect();
108        let (lslice, rslice) = vec.concurrent_split_at(5);
109        assert!(izip!(&lslice, 0..5).all(|(&lhs, rhs)| lhs == rhs));
110        assert!(izip!(&rslice, 5..16).all(|(&lhs, rhs)| lhs == rhs));
111    }
112
113    #[test]
114    fn chunks_of_chunk_test() {
115        let owner: Vec<_> = (0..9).collect();
116        let mut chunks = owner.concurrent_chunks_by_division(2);
117
118        let chunk1 = chunks.next().unwrap();
119        let chunk2 = chunks.next().unwrap();
120        assert!(chunks.next().is_none());
121        drop(chunks);
122
123        let mut chunks = chunk1.chunks(3);
124        let chunk3 = chunks.next().unwrap();
125        let chunk4 = chunks.next().unwrap();
126        assert!(chunks.next().is_none());
127        assert_eq!(&*chunk3, &[0, 1, 2]);
128        assert_eq!(&*chunk4, &[3, 4]);
129        drop(chunks);
130
131        let mut chunks = chunk2.chunks_by_division(3);
132        let chunk5 = chunks.next().unwrap();
133        let chunk6 = chunks.next().unwrap();
134        assert!(chunks.next().is_none());
135        assert_eq!(&*chunk5, &[5, 6]);
136        assert_eq!(&*chunk6, &[7, 8]);
137
138        let chunk7 = Chunk::cat(vec![chunk4, chunk5]);
139        assert_eq!(&*chunk7, &[3, 4, 5, 6]);
140
141        let (chunk8, chunk9) = chunk7.split_at(1);
142        assert_eq!(&*chunk8, &[3]);
143        assert_eq!(&*chunk9, &[4, 5, 6]);
144
145        // if the ref count is correct, the data should be recovered
146        let guard = chunk6.guard();
147
148        drop(chunks);
149        drop(chunk3);
150        drop(chunk6);
151        drop(chunk8);
152        drop(chunk9);
153
154        let owner = guard.try_unwrap().unwrap();
155        assert_eq!(owner, (0..9).collect::<Vec<_>>());
156    }
157}