1use {Array, DynamicArray};
2
3use std::marker::PhantomData;
4use std::ops::{Index, IndexMut};
5
6#[derive(Clone)]
17pub struct NestedArray<T, S, M, N> {
18 len: usize,
19 cap: usize,
20 data: M,
21 split: S,
22 _marker: PhantomData<(T, N)>,
23}
24
25impl<T, S, M, N> NestedArray<T, S, M, N>
26where
27 S: Split,
28 M: Array<N>,
29 N: Array<T>,
30{
31 #[inline]
32 fn max_nested(&self) -> usize {
33 self.split.max_nested()
34 }
35
36 #[inline]
37 fn split(&self, i: usize) -> (usize, usize) {
38 self.split.split(i)
39 }
40
41 #[cfg(test)]
42 fn compute_len(&self) -> usize {
43 self.data.iter().map(|d| d.len()).sum()
44 }
45}
46
47impl<T, S, M, N> Index<usize> for NestedArray<T, S, M, N>
48where
49 S: Split,
50 M: Array<N>,
51 N: Array<T> + Clone,
52{
53 type Output = T;
54
55 #[inline]
56 fn index(&self, index: usize) -> &Self::Output {
57 assert!(index < self.len);
58 unsafe { self.get_unchecked(index) }
59 }
60}
61
62impl<T, S, M, N> IndexMut<usize> for NestedArray<T, S, M, N>
63where
64 S: Split,
65 M: Array<N>,
66 N: Array<T> + Clone,
67{
68 #[inline]
69 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
70 assert!(index < self.len);
71 unsafe { self.get_unchecked_mut(index) }
72 }
73}
74
75impl<T, S, M, N> Array<T> for NestedArray<T, S, M, N>
76where
77 S: Split,
78 M: Array<N>,
79 N: Array<T> + Clone,
80{
81 fn with_value(value: T, n: usize) -> Self
82 where
83 T: Clone,
84 {
85 let s = S::new(n);
86 let max = s.max_nested();
87 let (div, rem) = div_rem(n, max);
88
89 let data = {
90 if n == 0 {
91 M::with_value(N::with_value(value, 0), 0)
92 } else if n < s.max_nested() {
93 M::with_value(N::with_value(value, n), 1)
94 } else if rem == 0 {
95 M::with_value(N::with_value(value, max), div)
96 } else {
97 let mut data = M::with_value(N::with_value(value.clone(), max), div + 1);
99 data[div] = N::with_value(value, rem);
101 data
102 }
103 };
104
105 NestedArray {
106 len: n,
107 cap: n,
108 data: data,
109 split: s,
110 _marker: PhantomData,
111 }
112 }
113
114 #[inline]
115 fn len(&self) -> usize {
116 self.len
117 }
118
119 #[inline]
120 unsafe fn get_unchecked(&self, index: usize) -> &T {
121 let (i, j) = self.split(index);
122 self.data.get_unchecked(i).get_unchecked(j)
123 }
124
125 #[inline]
126 unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T {
127 let (i, j) = self.split(index);
128 self.data.get_unchecked_mut(i).get_unchecked_mut(j)
129 }
130}
131
132impl<T, S, M, N> DynamicArray<T> for NestedArray<T, S, M, N>
133where
134 S: Split,
135 M: DynamicArray<N>,
136 N: DynamicArray<T> + Clone,
137{
138 fn with_capacity(capacity: usize) -> Self
139 where
140 Self: Sized,
141 {
142 let s = S::new(capacity);
143 let max = s.max_nested();
144 let (div, rem) = div_rem(capacity, max);
145
146 let mut data = if rem == 0 {
147 M::with_capacity(div)
148 } else {
149 M::with_capacity(div + 1)
150 };
151
152 let mut cap = 0;
153
154 while cap + max <= capacity {
155 cap += max;
156 data.push(N::with_capacity(max));
157 }
158
159 if rem != 0 {
160 data.push(N::with_capacity(rem));
161 }
162
163 NestedArray {
164 len: 0,
165 cap: capacity,
166 data: data,
167 split: s,
168 _marker: PhantomData,
169 }
170 }
171
172 fn capacity(&self) -> usize {
175 self.cap
176 }
177
178 unsafe fn set_len(&mut self, len: usize) {
179 if self.len == len {
180 return;
181 }
182
183 let (i, j) = self.split(len);
184 let max = self.max_nested();
185 let old = self.data.len();
186
187 if j == 0 {
188 self.data.set_len(i);
189 if i != 0 {
190 self.data[i - 1].set_len(max);
191 }
192 } else {
193 self.data.set_len(i + 1);
194 self.data[i].set_len(j);
195 }
196
197 let new = self.data.len();
198
199 if new != 0 && old < new - 1 {
200 for i in old..new - 1 {
201 self.data[i].set_len(max)
202 }
203 }
204
205 self.len = len;
206 }
207}
208
209pub trait Split {
211 fn new(n: usize) -> Self;
213
214 fn split(&self, index: usize) -> (usize, usize);
216
217 fn max_nested(&self) -> usize;
219}
220
221#[derive(Copy, Clone)]
222pub struct SqrtSplit(usize);
223
224impl Split for SqrtSplit {
225 fn new(n: usize) -> Self {
226 SqrtSplit(::std::cmp::max(1, (n as f64).sqrt() as usize))
227 }
228
229 fn split(&self, index: usize) -> (usize, usize) {
230 div_rem(index, self.0)
231 }
232
233 fn max_nested(&self) -> usize {
234 self.0
235 }
236}
237
238#[derive(Copy, Clone)]
239pub struct BalancedShiftSplit(usize);
240
241impl Split for BalancedShiftSplit {
242 fn new(n: usize) -> Self {
243 let mut s = 1;
244
245 while (1 << s) * (1 << s) < n {
246 s += 1;
247 }
248
249 BalancedShiftSplit(s)
250 }
251
252 fn split(&self, index: usize) -> (usize, usize) {
253 (index >> self.0, index & (self.max_nested() - 1))
254 }
255
256 fn max_nested(&self) -> usize {
257 1 << self.0
258 }
259}
260
261fn div_rem(a: usize, b: usize) -> (usize, usize) {
262 (a / b, a % b)
263}
264
265pub mod shift {
267 use super::Split;
268 macro_rules! def_shift {
269 ($name:ident, $num:expr) => {
270 #[allow(missing_docs)]
271 #[derive(Clone)]
272 pub struct $name;
273
274 impl Split for $name {
275 #[inline]
276 fn new(_n: usize) -> Self {
277 $name
278 }
279
280 #[inline]
281 fn split(&self, index: usize) -> (usize, usize) {
282 (index >> $num, index & (self.max_nested() - 1))
283 }
284
285 #[inline]
286 fn max_nested(&self) -> usize {
287 (1 << $num)
288 }
289 }
290 };
291 }
292
293 macro_rules! def_shifts {
294 ($($name:ident $num:expr)+) => (
295 $(def_shift!{$name, $num})+
296 )
297 }
298
299 def_shifts!{
300 Shift1 1 Shift2 2 Shift3 3 Shift4 4 Shift5 5 Shift6 6 Shift7 7
301 Shift8 8 Shift9 9 Shift10 10 Shift11 11 Shift12 12 Shift13 13 Shift14 14
302 Shift15 15 Shift16 16 Shift17 17 Shift18 18 Shift19 19 Shift20 20 Shift21 21
303 Shift22 22 Shift23 23 Shift24 24 Shift25 25 Shift26 26 Shift27 27 Shift28 28
304 Shift29 29 Shift30 30 Shift31 31
305 }
306
307 #[cfg(target_pointer_width = "64")]
308 def_shifts!{
309 Shift32 32 Shift33 33 Shift34 34 Shift35 35
310 Shift36 36 Shift37 37 Shift38 38 Shift39 39 Shift40 40 Shift41 41 Shift42 42
311 Shift43 43 Shift44 44 Shift45 45 Shift46 46 Shift47 47 Shift48 48 Shift49 49
312 Shift50 50 Shift51 51 Shift52 52 Shift53 53 Shift54 54 Shift55 55 Shift56 56
313 Shift57 57 Shift58 58 Shift59 59 Shift60 60 Shift61 61 Shift62 62 Shift63 63
314 }
315}
316
317#[cfg(test)]
318mod tests {
319 use super::*;
320 use {ArrayTests, BalancedShiftSplit, DynamicArray, DynamicArrayTests, VecArray};
321
322 #[test]
323 fn sqrt_split() {
324 let s = SqrtSplit::new(10);
325 assert_eq!(3, s.max_nested());
326 assert_eq!((0, 0), s.split(0));
327 assert_eq!((0, 1), s.split(1));
328 assert_eq!((0, 2), s.split(2));
329 assert_eq!((1, 0), s.split(3));
330 assert_eq!((1, 1), s.split(4));
331 assert_eq!((2, 0), s.split(6));
332 assert_eq!((3, 0), s.split(9));
333 }
334
335 #[test]
336 fn sqrt_split_zero() {
337 let s = SqrtSplit::new(0);
338 assert_eq!(1, s.max_nested());
339 assert_eq!((0, 0), s.split(0));
340 assert_eq!((1024, 0), s.split(1024));
341 }
342
343 #[test]
344 fn shift_split_zero() {
345 let s = BalancedShiftSplit::new(0);
346 assert_eq!(2, s.max_nested());
347 assert_eq!((0, 0), s.split(0));
348 assert_eq!((512, 0), s.split(1024));
349 }
350
351 #[test]
352 fn shift_split() {
353 let s = BalancedShiftSplit::new(10);
354 assert_eq!(4, s.max_nested());
355 assert_eq!((0, 0), s.split(0));
356 assert_eq!((0, 3), s.split(3));
357 assert_eq!((1, 0), s.split(4));
358 assert_eq!((1, 1), s.split(5));
359 assert_eq!((2, 0), s.split(8));
360 assert_eq!((2, 1), s.split(9));
361 }
362
363 #[test]
364 fn set_len() {
365 let mut v: NestedArray<
366 usize,
367 BalancedShiftSplit,
368 VecArray<VecArray<usize>>,
369 VecArray<usize>,
370 > = NestedArray::with_capacity(14);
371
372 assert_eq!(0, v.len());
373 assert_eq!(0, v.compute_len());
374
375 for i in 0..15 {
376 unsafe {
377 v.set_len(i);
378 }
379 assert_eq!(i, v.len());
380 assert_eq!(i, v.compute_len());
381 }
382
383 for i in 0..15 {
384 unsafe {
385 v.set_len(14 - i);
386 }
387 assert_eq!(14 - i, v.len());
388 assert_eq!(14 - i, v.compute_len());
389 }
390
391 unsafe {
392 v.set_len(13);
393 }
394 assert_eq!(13, v.len());
395 assert_eq!(13, v.compute_len());
396
397 unsafe {
398 v.set_len(5);
399 }
400
401 assert_eq!(5, v.len());
402 assert_eq!(5, v.compute_len());
403 }
404
405 struct T;
406
407 impl ArrayTests for T {
408 type A = NestedArray<usize, BalancedShiftSplit, VecArray<VecArray<usize>>, VecArray<usize>>;
409 }
410
411 delegate_tests!{
412 T,
413 basic_0,
414 basic_001k,
415 basic_100k,
416 clone_001k,
417 clone_100k
418 }
419
420 impl DynamicArrayTests for T {}
421
422 delegate_tests!{
423 T,
424 capacity,
425 push_1k,
426 clone_push
427 }
428
429 #[cfg(all(feature = "nightly", test))]
430 mod benchs {
431 use super::T;
432 use test::Bencher;
433 use ArrayBenchs;
434
435 impl ArrayBenchs for T {}
436
437 delegate_benchs!{
438 T,
439 fold_xor_0001k,
440 fold_xor_0010k,
441 fold_xor_0100k,
442 fold_xor_1000k,
443 clone_change_0001k,
444 clone_change_0010k,
445 clone_change_0100k,
446 clone_change_1000k
447 }
448 }
449}