1use std::cmp::max;
2use std::ops::{Index, IndexMut};
3use std::vec::Drain;
4
5use serde::{Deserialize, Serialize};
6
7use super::Row;
8use crate::grid::GridCell;
9use crate::index::{Column, Line};
10
11const MAX_CACHE_SIZE: usize = 1_000;
13
14#[derive(Clone, Debug, Deserialize, Serialize)]
31pub struct Storage<T> {
32 inner: Vec<Row<T>>,
33
34 zero: usize,
40
41 visible_lines: Line,
43
44 len: usize,
51}
52
53impl<T: PartialEq> PartialEq for Storage<T> {
54 fn eq(&self, other: &Self) -> bool {
55 assert_eq!(self.zero, 0);
57 assert_eq!(other.zero, 0);
58
59 self.inner == other.inner && self.len == other.len
60 }
61}
62
63impl<T> Storage<T> {
64 #[inline]
65 pub fn with_capacity(visible_lines: Line, template: Row<T>) -> Storage<T>
66 where
67 T: Clone,
68 {
69 let inner = vec![template; visible_lines.0];
71
72 Storage { inner, zero: 0, visible_lines, len: visible_lines.0 }
73 }
74
75 pub fn grow_visible_lines(&mut self, next: Line, template_row: Row<T>)
77 where
78 T: Clone,
79 {
80 let growage = next - self.visible_lines;
82 self.grow_lines(growage.0, template_row);
83
84 self.visible_lines = next;
86 }
87
88 fn grow_lines(&mut self, growage: usize, template_row: Row<T>)
90 where
91 T: Clone,
92 {
93 let mut new_growage = 0;
95 if growage > (self.inner.len() - self.len) {
96 new_growage = growage - (self.inner.len() - self.len);
98
99 let mut start_buffer = self.inner.split_off(self.zero);
101
102 let mut new_lines = vec![template_row; new_growage];
104 self.inner.append(&mut new_lines);
105
106 self.inner.append(&mut start_buffer);
108 }
109
110 self.zero += new_growage;
112 self.len += growage;
113 }
114
115 pub fn shrink_visible_lines(&mut self, next: Line) {
117 let shrinkage = self.visible_lines - next;
119 self.shrink_lines(shrinkage.0);
120
121 self.visible_lines = next;
123 }
124
125 pub fn shrink_lines(&mut self, shrinkage: usize) {
127 self.len -= shrinkage;
128
129 if self.inner.len() > self.len + MAX_CACHE_SIZE {
131 self.truncate();
132 }
133 }
134
135 pub fn truncate(&mut self) {
137 self.inner.rotate_left(self.zero);
138 self.inner.truncate(self.len);
139
140 self.zero = 0;
141 }
142
143 #[inline]
145 pub fn initialize(&mut self, additional_rows: usize, template: &T, cols: Column)
146 where
147 T: GridCell + Copy,
148 {
149 if self.len + additional_rows > self.inner.len() {
150 let realloc_size = max(additional_rows, MAX_CACHE_SIZE);
151 let mut new = vec![Row::new(cols, template); realloc_size];
152 let mut split = self.inner.split_off(self.zero);
153 self.inner.append(&mut new);
154 self.inner.append(&mut split);
155 self.zero += realloc_size;
156 }
157
158 self.len += additional_rows;
159 }
160
161 #[inline]
162 pub fn len(&self) -> usize {
163 self.len
164 }
165
166 #[inline]
168 fn compute_index(&self, requested: usize) -> usize {
169 debug_assert!(requested < self.len);
170
171 let zeroed = self.zero + requested;
172
173 if zeroed >= self.inner.len() {
178 zeroed - self.inner.len()
179 } else {
180 zeroed
181 }
182 }
183
184 pub fn swap_lines(&mut self, a: Line, b: Line) {
185 let offset = self.inner.len() + self.zero + *self.visible_lines - 1;
186 let a = (offset - *a) % self.inner.len();
187 let b = (offset - *b) % self.inner.len();
188 self.inner.swap(a, b);
189 }
190
191 pub fn swap(&mut self, a: usize, b: usize) {
200 debug_assert_eq!(std::mem::size_of::<Row<T>>(), 32);
201
202 let a = self.compute_index(a);
203 let b = self.compute_index(b);
204
205 unsafe {
206 let a_ptr = self.inner.as_mut_ptr().add(a) as *mut usize;
210 let b_ptr = self.inner.as_mut_ptr().add(b) as *mut usize;
211
212 let mut tmp: usize;
216 for i in 0..4 {
217 tmp = *a_ptr.offset(i);
218 *a_ptr.offset(i) = *b_ptr.offset(i);
219 *b_ptr.offset(i) = tmp;
220 }
221 }
222 }
223
224 #[inline]
226 pub fn rotate(&mut self, count: isize) {
227 debug_assert!(count.abs() as usize <= self.inner.len());
228
229 let len = self.inner.len();
230 self.zero = (self.zero as isize + count + len as isize) as usize % self.inner.len();
231 }
232
233 #[inline]
237 pub fn rotate_up(&mut self, count: usize) {
238 self.zero = (self.zero + count) % self.inner.len();
239 }
240
241 pub fn drain(&mut self) -> Drain<'_, Row<T>> {
243 self.truncate();
244 self.inner.drain(..)
245 }
246
247 pub fn replace_inner(&mut self, vec: Vec<Row<T>>) {
249 self.len = vec.len();
250 self.inner = vec;
251 self.zero = 0;
252 }
253}
254
255impl<T> Index<usize> for Storage<T> {
256 type Output = Row<T>;
257
258 #[inline]
259 fn index(&self, index: usize) -> &Self::Output {
260 &self.inner[self.compute_index(index)]
261 }
262}
263
264impl<T> IndexMut<usize> for Storage<T> {
265 #[inline]
266 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
267 let index = self.compute_index(index); &mut self.inner[index]
269 }
270}
271
272impl<T> Index<Line> for Storage<T> {
273 type Output = Row<T>;
274
275 #[inline]
276 fn index(&self, index: Line) -> &Self::Output {
277 let index = self.visible_lines - 1 - index;
278 &self[*index]
279 }
280}
281
282impl<T> IndexMut<Line> for Storage<T> {
283 #[inline]
284 fn index_mut(&mut self, index: Line) -> &mut Self::Output {
285 let index = self.visible_lines - 1 - index;
286 &mut self[*index]
287 }
288}
289
290#[cfg(test)]
291mod test {
292 use crate::grid::row::Row;
293 use crate::grid::storage::{Storage, MAX_CACHE_SIZE};
294 use crate::grid::GridCell;
295 use crate::index::{Column, Line};
296 use crate::term::cell::Flags;
297
298 impl GridCell for char {
299 fn is_empty(&self) -> bool {
300 *self == ' ' || *self == '\t'
301 }
302
303 fn flags(&self) -> &Flags {
304 unimplemented!();
305 }
306
307 fn flags_mut(&mut self) -> &mut Flags {
308 unimplemented!();
309 }
310
311 fn fast_eq(&self, other: Self) -> bool {
312 self == &other
313 }
314 }
315
316 #[test]
317 fn with_capacity() {
318 let storage = Storage::with_capacity(Line(3), Row::new(Column(0), &' '));
319
320 assert_eq!(storage.inner.len(), 3);
321 assert_eq!(storage.len, 3);
322 assert_eq!(storage.zero, 0);
323 assert_eq!(storage.visible_lines, Line(3));
324 }
325
326 #[test]
327 fn indexing() {
328 let mut storage = Storage::with_capacity(Line(3), Row::new(Column(0), &' '));
329
330 storage[0] = Row::new(Column(1), &'0');
331 storage[1] = Row::new(Column(1), &'1');
332 storage[2] = Row::new(Column(1), &'2');
333
334 assert_eq!(storage[0], Row::new(Column(1), &'0'));
335 assert_eq!(storage[1], Row::new(Column(1), &'1'));
336 assert_eq!(storage[2], Row::new(Column(1), &'2'));
337
338 storage.zero += 1;
339
340 assert_eq!(storage[0], Row::new(Column(1), &'1'));
341 assert_eq!(storage[1], Row::new(Column(1), &'2'));
342 assert_eq!(storage[2], Row::new(Column(1), &'0'));
343 }
344
345 #[test]
346 #[should_panic]
347 fn indexing_above_inner_len() {
348 let storage = Storage::with_capacity(Line(1), Row::new(Column(0), &' '));
349 let _ = &storage[2];
350 }
351
352 #[test]
353 fn rotate() {
354 let mut storage = Storage::with_capacity(Line(3), Row::new(Column(0), &' '));
355 storage.rotate(2);
356 assert_eq!(storage.zero, 2);
357 storage.shrink_lines(2);
358 assert_eq!(storage.len, 1);
359 assert_eq!(storage.inner.len(), 3);
360 assert_eq!(storage.zero, 2);
361 }
362
363 #[test]
375 fn grow_after_zero() {
376 let mut storage = Storage {
378 inner: vec![
379 Row::new(Column(1), &'0'),
380 Row::new(Column(1), &'1'),
381 Row::new(Column(1), &'-'),
382 ],
383 zero: 0,
384 visible_lines: Line(3),
385 len: 3,
386 };
387
388 storage.grow_visible_lines(Line(4), Row::new(Column(1), &'-'));
390
391 let expected = Storage {
393 inner: vec![
394 Row::new(Column(1), &'-'),
395 Row::new(Column(1), &'0'),
396 Row::new(Column(1), &'1'),
397 Row::new(Column(1), &'-'),
398 ],
399 zero: 1,
400 visible_lines: Line(4),
401 len: 4,
402 };
403 assert_eq!(storage.visible_lines, expected.visible_lines);
404 assert_eq!(storage.inner, expected.inner);
405 assert_eq!(storage.zero, expected.zero);
406 assert_eq!(storage.len, expected.len);
407 }
408
409 #[test]
421 fn grow_before_zero() {
422 let mut storage = Storage {
424 inner: vec![
425 Row::new(Column(1), &'-'),
426 Row::new(Column(1), &'0'),
427 Row::new(Column(1), &'1'),
428 ],
429 zero: 1,
430 visible_lines: Line(3),
431 len: 3,
432 };
433
434 storage.grow_visible_lines(Line(4), Row::new(Column(1), &'-'));
436
437 let expected = Storage {
439 inner: vec![
440 Row::new(Column(1), &'-'),
441 Row::new(Column(1), &'-'),
442 Row::new(Column(1), &'0'),
443 Row::new(Column(1), &'1'),
444 ],
445 zero: 2,
446 visible_lines: Line(4),
447 len: 4,
448 };
449 assert_eq!(storage.visible_lines, expected.visible_lines);
450 assert_eq!(storage.inner, expected.inner);
451 assert_eq!(storage.zero, expected.zero);
452 assert_eq!(storage.len, expected.len);
453 }
454
455 #[test]
466 fn shrink_before_zero() {
467 let mut storage = Storage {
469 inner: vec![
470 Row::new(Column(1), &'2'),
471 Row::new(Column(1), &'0'),
472 Row::new(Column(1), &'1'),
473 ],
474 zero: 1,
475 visible_lines: Line(3),
476 len: 3,
477 };
478
479 storage.shrink_visible_lines(Line(2));
481
482 let expected = Storage {
484 inner: vec![
485 Row::new(Column(1), &'2'),
486 Row::new(Column(1), &'0'),
487 Row::new(Column(1), &'1'),
488 ],
489 zero: 1,
490 visible_lines: Line(2),
491 len: 2,
492 };
493 assert_eq!(storage.visible_lines, expected.visible_lines);
494 assert_eq!(storage.inner, expected.inner);
495 assert_eq!(storage.zero, expected.zero);
496 assert_eq!(storage.len, expected.len);
497 }
498
499 #[test]
510 fn shrink_after_zero() {
511 let mut storage = Storage {
513 inner: vec![
514 Row::new(Column(1), &'0'),
515 Row::new(Column(1), &'1'),
516 Row::new(Column(1), &'2'),
517 ],
518 zero: 0,
519 visible_lines: Line(3),
520 len: 3,
521 };
522
523 storage.shrink_visible_lines(Line(2));
525
526 let expected = Storage {
528 inner: vec![
529 Row::new(Column(1), &'0'),
530 Row::new(Column(1), &'1'),
531 Row::new(Column(1), &'2'),
532 ],
533 zero: 0,
534 visible_lines: Line(2),
535 len: 2,
536 };
537 assert_eq!(storage.visible_lines, expected.visible_lines);
538 assert_eq!(storage.inner, expected.inner);
539 assert_eq!(storage.zero, expected.zero);
540 assert_eq!(storage.len, expected.len);
541 }
542
543 #[test]
560 fn shrink_before_and_after_zero() {
561 let mut storage = Storage {
563 inner: vec![
564 Row::new(Column(1), &'4'),
565 Row::new(Column(1), &'5'),
566 Row::new(Column(1), &'0'),
567 Row::new(Column(1), &'1'),
568 Row::new(Column(1), &'2'),
569 Row::new(Column(1), &'3'),
570 ],
571 zero: 2,
572 visible_lines: Line(6),
573 len: 6,
574 };
575
576 storage.shrink_visible_lines(Line(2));
578
579 let expected = Storage {
581 inner: vec![
582 Row::new(Column(1), &'4'),
583 Row::new(Column(1), &'5'),
584 Row::new(Column(1), &'0'),
585 Row::new(Column(1), &'1'),
586 Row::new(Column(1), &'2'),
587 Row::new(Column(1), &'3'),
588 ],
589 zero: 2,
590 visible_lines: Line(2),
591 len: 2,
592 };
593 assert_eq!(storage.visible_lines, expected.visible_lines);
594 assert_eq!(storage.inner, expected.inner);
595 assert_eq!(storage.zero, expected.zero);
596 assert_eq!(storage.len, expected.len);
597 }
598
599 #[test]
612 fn truncate_invisible_lines() {
613 let mut storage = Storage {
615 inner: vec![
616 Row::new(Column(1), &'4'),
617 Row::new(Column(1), &'5'),
618 Row::new(Column(1), &'0'),
619 Row::new(Column(1), &'1'),
620 Row::new(Column(1), &'2'),
621 Row::new(Column(1), &'3'),
622 ],
623 zero: 2,
624 visible_lines: Line(1),
625 len: 2,
626 };
627
628 storage.truncate();
630
631 let expected = Storage {
633 inner: vec![Row::new(Column(1), &'0'), Row::new(Column(1), &'1')],
634 zero: 0,
635 visible_lines: Line(1),
636 len: 2,
637 };
638 assert_eq!(storage.visible_lines, expected.visible_lines);
639 assert_eq!(storage.inner, expected.inner);
640 assert_eq!(storage.zero, expected.zero);
641 assert_eq!(storage.len, expected.len);
642 }
643
644 #[test]
654 fn truncate_invisible_lines_beginning() {
655 let mut storage = Storage {
657 inner: vec![
658 Row::new(Column(1), &'1'),
659 Row::new(Column(1), &'2'),
660 Row::new(Column(1), &'0'),
661 ],
662 zero: 2,
663 visible_lines: Line(1),
664 len: 2,
665 };
666
667 storage.truncate();
669
670 let expected = Storage {
672 inner: vec![Row::new(Column(1), &'0'), Row::new(Column(1), &'1')],
673 zero: 0,
674 visible_lines: Line(1),
675 len: 2,
676 };
677 assert_eq!(storage.visible_lines, expected.visible_lines);
678 assert_eq!(storage.inner, expected.inner);
679 assert_eq!(storage.zero, expected.zero);
680 assert_eq!(storage.len, expected.len);
681 }
682
683 #[test]
708 fn shrink_then_grow() {
709 let mut storage = Storage {
711 inner: vec![
712 Row::new(Column(1), &'4'),
713 Row::new(Column(1), &'5'),
714 Row::new(Column(1), &'0'),
715 Row::new(Column(1), &'1'),
716 Row::new(Column(1), &'2'),
717 Row::new(Column(1), &'3'),
718 ],
719 zero: 2,
720 visible_lines: Line(0),
721 len: 6,
722 };
723
724 storage.shrink_lines(3);
726
727 let shrinking_expected = Storage {
729 inner: vec![
730 Row::new(Column(1), &'4'),
731 Row::new(Column(1), &'5'),
732 Row::new(Column(1), &'0'),
733 Row::new(Column(1), &'1'),
734 Row::new(Column(1), &'2'),
735 Row::new(Column(1), &'3'),
736 ],
737 zero: 2,
738 visible_lines: Line(0),
739 len: 3,
740 };
741 assert_eq!(storage.inner, shrinking_expected.inner);
742 assert_eq!(storage.zero, shrinking_expected.zero);
743 assert_eq!(storage.len, shrinking_expected.len);
744
745 storage.grow_lines(4, Row::new(Column(1), &'-'));
747
748 let growing_expected = Storage {
750 inner: vec![
751 Row::new(Column(1), &'4'),
752 Row::new(Column(1), &'5'),
753 Row::new(Column(1), &'-'),
754 Row::new(Column(1), &'0'),
755 Row::new(Column(1), &'1'),
756 Row::new(Column(1), &'2'),
757 Row::new(Column(1), &'3'),
758 ],
759 zero: 3,
760 visible_lines: Line(0),
761 len: 7,
762 };
763 assert_eq!(storage.inner, growing_expected.inner);
764 assert_eq!(storage.zero, growing_expected.zero);
765 assert_eq!(storage.len, growing_expected.len);
766 }
767
768 #[test]
769 fn initialize() {
770 let mut storage = Storage {
772 inner: vec![
773 Row::new(Column(1), &'4'),
774 Row::new(Column(1), &'5'),
775 Row::new(Column(1), &'0'),
776 Row::new(Column(1), &'1'),
777 Row::new(Column(1), &'2'),
778 Row::new(Column(1), &'3'),
779 ],
780 zero: 2,
781 visible_lines: Line(0),
782 len: 6,
783 };
784
785 let init_size = 3;
787 storage.initialize(init_size, &'-', Column(1));
788
789 let expected_init_size = std::cmp::max(init_size, MAX_CACHE_SIZE);
792 let mut expected_inner = vec![Row::new(Column(1), &'4'), Row::new(Column(1), &'5')];
793 expected_inner.append(&mut vec![Row::new(Column(1), &'-'); expected_init_size]);
794 expected_inner.append(&mut vec![
795 Row::new(Column(1), &'0'),
796 Row::new(Column(1), &'1'),
797 Row::new(Column(1), &'2'),
798 Row::new(Column(1), &'3'),
799 ]);
800 let expected_storage = Storage {
801 inner: expected_inner,
802 zero: 2 + expected_init_size,
803 visible_lines: Line(0),
804 len: 9,
805 };
806
807 assert_eq!(storage.inner, expected_storage.inner);
808 assert_eq!(storage.zero, expected_storage.zero);
809 assert_eq!(storage.len, expected_storage.len);
810 }
811
812 #[test]
813 fn rotate_wrap_zero() {
814 let mut storage = Storage {
815 inner: vec![
816 Row::new(Column(1), &'-'),
817 Row::new(Column(1), &'-'),
818 Row::new(Column(1), &'-'),
819 ],
820 zero: 2,
821 visible_lines: Line(0),
822 len: 3,
823 };
824
825 storage.rotate(2);
826
827 assert!(storage.zero < storage.inner.len());
828 }
829}