1use alloc::vec::{self, Vec};
2use std::cell::{Cell, RefCell};
3
4trait KeyFunction<A> {
6 type Key;
7 fn call_mut(&mut self, arg: A) -> Self::Key;
8}
9
10impl<A, K, F> KeyFunction<A> for F
11where
12 F: FnMut(A) -> K + ?Sized,
13{
14 type Key = K;
15 #[inline]
16 fn call_mut(&mut self, arg: A) -> Self::Key {
17 (*self)(arg)
18 }
19}
20
21#[derive(Debug, Clone)]
23struct ChunkIndex {
24 size: usize,
25 index: usize,
26 key: usize,
27}
28
29impl ChunkIndex {
30 #[inline(always)]
31 fn new(size: usize) -> Self {
32 Self {
33 size,
34 index: 0,
35 key: 0,
36 }
37 }
38}
39
40impl<A> KeyFunction<A> for ChunkIndex {
41 type Key = usize;
42 #[inline(always)]
43 fn call_mut(&mut self, _arg: A) -> Self::Key {
44 if self.index == self.size {
45 self.key += 1;
46 self.index = 0;
47 }
48 self.index += 1;
49 self.key
50 }
51}
52
53#[derive(Clone)]
54struct GroupInner<K, I, F>
55where
56 I: Iterator,
57{
58 key: F,
59 iter: I,
60 current_key: Option<K>,
61 current_elt: Option<I::Item>,
62 done: bool,
64 top_group: usize,
66 oldest_buffered_group: usize,
68 bottom_group: usize,
72 buffer: Vec<vec::IntoIter<I::Item>>,
74 dropped_group: usize,
77}
78
79impl<K, I, F> GroupInner<K, I, F>
80where
81 I: Iterator,
82 F: for<'a> KeyFunction<&'a I::Item, Key = K>,
83 K: PartialEq,
84{
85 #[inline(always)]
87 fn step(&mut self, client: usize) -> Option<I::Item> {
88 if client < self.oldest_buffered_group {
95 None
96 } else if client < self.top_group
97 || (client == self.top_group && self.buffer.len() > self.top_group - self.bottom_group)
98 {
99 self.lookup_buffer(client)
100 } else if self.done {
101 None
102 } else if self.top_group == client {
103 self.step_current()
104 } else {
105 self.step_buffering(client)
106 }
107 }
108
109 #[inline(never)]
110 fn lookup_buffer(&mut self, client: usize) -> Option<I::Item> {
111 let bufidx = client - self.bottom_group;
113 if client < self.oldest_buffered_group {
114 return None;
115 }
116 let elt = self.buffer.get_mut(bufidx).and_then(|queue| queue.next());
117 if elt.is_none() && client == self.oldest_buffered_group {
118 self.oldest_buffered_group += 1;
122 while self
124 .buffer
125 .get(self.oldest_buffered_group - self.bottom_group)
126 .map_or(false, |buf| buf.len() == 0)
127 {
128 self.oldest_buffered_group += 1;
129 }
130
131 let nclear = self.oldest_buffered_group - self.bottom_group;
132 if nclear > 0 && nclear >= self.buffer.len() / 2 {
133 let mut i = 0;
134 self.buffer.retain(|buf| {
135 i += 1;
136 debug_assert!(buf.len() == 0 || i > nclear);
137 i > nclear
138 });
139 self.bottom_group = self.oldest_buffered_group;
140 }
141 }
142 elt
143 }
144
145 #[inline(always)]
148 fn next_element(&mut self) -> Option<I::Item> {
149 debug_assert!(!self.done);
150 match self.iter.next() {
151 None => {
152 self.done = true;
153 None
154 }
155 otherwise => otherwise,
156 }
157 }
158
159 #[inline(never)]
160 fn step_buffering(&mut self, client: usize) -> Option<I::Item> {
161 debug_assert!(self.top_group + 1 == client);
167 let mut group = Vec::new();
168
169 if let Some(elt) = self.current_elt.take() {
170 if self.top_group != self.dropped_group {
171 group.push(elt);
172 }
173 }
174 let mut first_elt = None; while let Some(elt) = self.next_element() {
177 let key = self.key.call_mut(&elt);
178 match self.current_key.take() {
179 None => {}
180 Some(old_key) => {
181 if old_key != key {
182 self.current_key = Some(key);
183 first_elt = Some(elt);
184 break;
185 }
186 }
187 }
188 self.current_key = Some(key);
189 if self.top_group != self.dropped_group {
190 group.push(elt);
191 }
192 }
193
194 if self.top_group != self.dropped_group {
195 self.push_next_group(group);
196 }
197 if first_elt.is_some() {
198 self.top_group += 1;
199 debug_assert!(self.top_group == client);
200 }
201 first_elt
202 }
203
204 fn push_next_group(&mut self, group: Vec<I::Item>) {
205 while self.top_group - self.bottom_group > self.buffer.len() {
207 if self.buffer.is_empty() {
208 self.bottom_group += 1;
209 self.oldest_buffered_group += 1;
210 } else {
211 self.buffer.push(Vec::new().into_iter());
212 }
213 }
214 self.buffer.push(group.into_iter());
215 debug_assert!(self.top_group + 1 - self.bottom_group == self.buffer.len());
216 }
217
218 #[inline]
220 fn step_current(&mut self) -> Option<I::Item> {
221 debug_assert!(!self.done);
222 if let elt @ Some(..) = self.current_elt.take() {
223 return elt;
224 }
225 match self.next_element() {
226 None => None,
227 Some(elt) => {
228 let key = self.key.call_mut(&elt);
229 match self.current_key.take() {
230 None => {}
231 Some(old_key) => {
232 if old_key != key {
233 self.current_key = Some(key);
234 self.current_elt = Some(elt);
235 self.top_group += 1;
236 return None;
237 }
238 }
239 }
240 self.current_key = Some(key);
241 Some(elt)
242 }
243 }
244 }
245
246 fn group_key(&mut self, client: usize) -> K {
252 debug_assert!(!self.done);
257 debug_assert!(client == self.top_group);
258 debug_assert!(self.current_key.is_some());
259 debug_assert!(self.current_elt.is_none());
260 let old_key = self.current_key.take().unwrap();
261 if let Some(elt) = self.next_element() {
262 let key = self.key.call_mut(&elt);
263 if old_key != key {
264 self.top_group += 1;
265 }
266 self.current_key = Some(key);
267 self.current_elt = Some(elt);
268 }
269 old_key
270 }
271}
272
273impl<K, I, F> GroupInner<K, I, F>
274where
275 I: Iterator,
276{
277 fn drop_group(&mut self, client: usize) {
279 if self.dropped_group == !0 || client > self.dropped_group {
281 self.dropped_group = client;
282 }
283 }
284}
285
286#[deprecated(note = "Use `ChunkBy` instead", since = "0.13.0")]
287pub type GroupBy<K, I, F> = ChunkBy<K, I, F>;
289
290#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
304pub struct ChunkBy<K, I, F>
305where
306 I: Iterator,
307{
308 inner: RefCell<GroupInner<K, I, F>>,
309 index: Cell<usize>,
312}
313
314pub fn new<K, J, F>(iter: J, f: F) -> ChunkBy<K, J::IntoIter, F>
316where
317 J: IntoIterator,
318 F: FnMut(&J::Item) -> K,
319{
320 ChunkBy {
321 inner: RefCell::new(GroupInner {
322 key: f,
323 iter: iter.into_iter(),
324 current_key: None,
325 current_elt: None,
326 done: false,
327 top_group: 0,
328 oldest_buffered_group: 0,
329 bottom_group: 0,
330 buffer: Vec::new(),
331 dropped_group: !0,
332 }),
333 index: Cell::new(0),
334 }
335}
336
337impl<K, I, F> ChunkBy<K, I, F>
338where
339 I: Iterator,
340{
341 fn step(&self, client: usize) -> Option<I::Item>
343 where
344 F: FnMut(&I::Item) -> K,
345 K: PartialEq,
346 {
347 self.inner.borrow_mut().step(client)
348 }
349
350 fn drop_group(&self, client: usize) {
352 self.inner.borrow_mut().drop_group(client);
353 }
354}
355
356impl<'a, K, I, F> IntoIterator for &'a ChunkBy<K, I, F>
357where
358 I: Iterator,
359 I::Item: 'a,
360 F: FnMut(&I::Item) -> K,
361 K: PartialEq,
362{
363 type Item = (K, Group<'a, K, I, F>);
364 type IntoIter = Groups<'a, K, I, F>;
365
366 fn into_iter(self) -> Self::IntoIter {
367 Groups { parent: self }
368 }
369}
370
371#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
378pub struct Groups<'a, K, I, F>
379where
380 I: Iterator + 'a,
381 I::Item: 'a,
382 K: 'a,
383 F: 'a,
384{
385 parent: &'a ChunkBy<K, I, F>,
386}
387
388impl<'a, K, I, F> Iterator for Groups<'a, K, I, F>
389where
390 I: Iterator,
391 I::Item: 'a,
392 F: FnMut(&I::Item) -> K,
393 K: PartialEq,
394{
395 type Item = (K, Group<'a, K, I, F>);
396
397 #[inline]
398 fn next(&mut self) -> Option<Self::Item> {
399 let index = self.parent.index.get();
400 self.parent.index.set(index + 1);
401 let inner = &mut *self.parent.inner.borrow_mut();
402 inner.step(index).map(|elt| {
403 let key = inner.group_key(index);
404 (
405 key,
406 Group {
407 parent: self.parent,
408 index,
409 first: Some(elt),
410 },
411 )
412 })
413 }
414}
415
416pub struct Group<'a, K, I, F>
420where
421 I: Iterator + 'a,
422 I::Item: 'a,
423 K: 'a,
424 F: 'a,
425{
426 parent: &'a ChunkBy<K, I, F>,
427 index: usize,
428 first: Option<I::Item>,
429}
430
431impl<'a, K, I, F> Drop for Group<'a, K, I, F>
432where
433 I: Iterator,
434 I::Item: 'a,
435{
436 fn drop(&mut self) {
437 self.parent.drop_group(self.index);
438 }
439}
440
441impl<'a, K, I, F> Iterator for Group<'a, K, I, F>
442where
443 I: Iterator,
444 I::Item: 'a,
445 F: FnMut(&I::Item) -> K,
446 K: PartialEq,
447{
448 type Item = I::Item;
449 #[inline]
450 fn next(&mut self) -> Option<Self::Item> {
451 if let elt @ Some(..) = self.first.take() {
452 return elt;
453 }
454 self.parent.step(self.index)
455 }
456}
457
458pub fn new_chunks<J>(iter: J, size: usize) -> IntoChunks<J::IntoIter>
462where
463 J: IntoIterator,
464{
465 IntoChunks {
466 inner: RefCell::new(GroupInner {
467 key: ChunkIndex::new(size),
468 iter: iter.into_iter(),
469 current_key: None,
470 current_elt: None,
471 done: false,
472 top_group: 0,
473 oldest_buffered_group: 0,
474 bottom_group: 0,
475 buffer: Vec::new(),
476 dropped_group: !0,
477 }),
478 index: Cell::new(0),
479 }
480}
481
482#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
496pub struct IntoChunks<I>
497where
498 I: Iterator,
499{
500 inner: RefCell<GroupInner<usize, I, ChunkIndex>>,
501 index: Cell<usize>,
504}
505
506impl<I> Clone for IntoChunks<I>
507where
508 I: Clone + Iterator,
509 I::Item: Clone,
510{
511 clone_fields!(inner, index);
512}
513
514impl<I> IntoChunks<I>
515where
516 I: Iterator,
517{
518 fn step(&self, client: usize) -> Option<I::Item> {
520 self.inner.borrow_mut().step(client)
521 }
522
523 fn drop_group(&self, client: usize) {
525 self.inner.borrow_mut().drop_group(client);
526 }
527}
528
529impl<'a, I> IntoIterator for &'a IntoChunks<I>
530where
531 I: Iterator,
532 I::Item: 'a,
533{
534 type Item = Chunk<'a, I>;
535 type IntoIter = Chunks<'a, I>;
536
537 fn into_iter(self) -> Self::IntoIter {
538 Chunks { parent: self }
539 }
540}
541
542#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
548#[derive(Clone)]
549pub struct Chunks<'a, I>
550where
551 I: Iterator + 'a,
552 I::Item: 'a,
553{
554 parent: &'a IntoChunks<I>,
555}
556
557impl<'a, I> Iterator for Chunks<'a, I>
558where
559 I: Iterator,
560 I::Item: 'a,
561{
562 type Item = Chunk<'a, I>;
563
564 #[inline]
565 fn next(&mut self) -> Option<Self::Item> {
566 let index = self.parent.index.get();
567 self.parent.index.set(index + 1);
568 let inner = &mut *self.parent.inner.borrow_mut();
569 inner.step(index).map(|elt| Chunk {
570 parent: self.parent,
571 index,
572 first: Some(elt),
573 })
574 }
575}
576
577pub struct Chunk<'a, I>
581where
582 I: Iterator + 'a,
583 I::Item: 'a,
584{
585 parent: &'a IntoChunks<I>,
586 index: usize,
587 first: Option<I::Item>,
588}
589
590impl<'a, I> Drop for Chunk<'a, I>
591where
592 I: Iterator,
593 I::Item: 'a,
594{
595 fn drop(&mut self) {
596 self.parent.drop_group(self.index);
597 }
598}
599
600impl<'a, I> Iterator for Chunk<'a, I>
601where
602 I: Iterator,
603 I::Item: 'a,
604{
605 type Item = I::Item;
606 #[inline]
607 fn next(&mut self) -> Option<Self::Item> {
608 if let elt @ Some(..) = self.first.take() {
609 return elt;
610 }
611 self.parent.step(self.index)
612 }
613}