cranpose_foundation/lazy/
nearest_range.rs1use std::ops::Range;
8
9pub const NEAREST_ITEMS_SLIDING_WINDOW_SIZE: usize = 30;
12
13pub const NEAREST_ITEMS_EXTRA_COUNT: usize = 100;
16
17#[derive(Debug, Clone)]
25pub struct NearestRangeState {
26 value: Range<usize>,
27 last_first_visible_item: usize,
28 sliding_window_size: usize,
29 extra_item_count: usize,
30}
31
32impl Default for NearestRangeState {
33 fn default() -> Self {
34 Self::new(0)
35 }
36}
37
38impl NearestRangeState {
39 pub fn new(first_visible_item: usize) -> Self {
41 Self::with_sizes(
42 first_visible_item,
43 NEAREST_ITEMS_SLIDING_WINDOW_SIZE,
44 NEAREST_ITEMS_EXTRA_COUNT,
45 )
46 }
47
48 pub fn with_sizes(
50 first_visible_item: usize,
51 sliding_window_size: usize,
52 extra_item_count: usize,
53 ) -> Self {
54 let value =
55 Self::calculate_range(first_visible_item, sliding_window_size, extra_item_count);
56 Self {
57 value,
58 last_first_visible_item: first_visible_item,
59 sliding_window_size,
60 extra_item_count,
61 }
62 }
63
64 pub fn range(&self) -> Range<usize> {
66 self.value.clone()
67 }
68
69 pub fn update(&mut self, first_visible_item: usize) {
72 if first_visible_item != self.last_first_visible_item {
73 self.last_first_visible_item = first_visible_item;
74 self.value = Self::calculate_range(
75 first_visible_item,
76 self.sliding_window_size,
77 self.extra_item_count,
78 );
79 }
80 }
81
82 fn calculate_range(
83 first_visible_item: usize,
84 sliding_window_size: usize,
85 extra_item_count: usize,
86 ) -> Range<usize> {
87 let sliding_window_start =
88 sliding_window_size.saturating_mul(first_visible_item / sliding_window_size);
89 let start = sliding_window_start.saturating_sub(extra_item_count);
90 let end = sliding_window_start
91 .saturating_add(sliding_window_size)
92 .saturating_add(extra_item_count);
93 start..end
94 }
95}
96
97#[cfg(test)]
98#[path = "tests/nearest_range_tests.rs"]
99mod tests;