tantivy_columnar/column_values/
monotonic_column.rs1use std::fmt::Debug;
2use std::marker::PhantomData;
3use std::ops::{Range, RangeInclusive};
4
5use crate::column_values::monotonic_mapping::StrictlyMonotonicFn;
6use crate::ColumnValues;
7
8struct MonotonicMappingColumn<C, T, Input> {
9 from_column: C,
10 monotonic_mapping: T,
11 _phantom: PhantomData<Input>,
12}
13
14pub fn monotonic_map_column<C, T, Input, Output>(
30 from_column: C,
31 monotonic_mapping: T,
32) -> impl ColumnValues<Output>
33where
34 C: ColumnValues<Input> + 'static,
35 T: StrictlyMonotonicFn<Input, Output> + Send + Sync + 'static,
36 Input: PartialOrd + Debug + Send + Sync + Clone + 'static,
37 Output: PartialOrd + Debug + Send + Sync + Clone + 'static,
38{
39 MonotonicMappingColumn {
40 from_column,
41 monotonic_mapping,
42 _phantom: PhantomData,
43 }
44}
45
46impl<C, T, Input, Output> ColumnValues<Output> for MonotonicMappingColumn<C, T, Input>
47where
48 C: ColumnValues<Input> + 'static,
49 T: StrictlyMonotonicFn<Input, Output> + Send + Sync + 'static,
50 Input: PartialOrd + Send + Debug + Sync + Clone + 'static,
51 Output: PartialOrd + Send + Debug + Sync + Clone + 'static,
52{
53 #[inline(always)]
54 fn get_val(&self, idx: u32) -> Output {
55 let from_val = self.from_column.get_val(idx);
56 self.monotonic_mapping.mapping(from_val)
57 }
58
59 fn min_value(&self) -> Output {
60 let from_min_value = self.from_column.min_value();
61 self.monotonic_mapping.mapping(from_min_value)
62 }
63
64 fn max_value(&self) -> Output {
65 let from_max_value = self.from_column.max_value();
66 self.monotonic_mapping.mapping(from_max_value)
67 }
68
69 fn num_vals(&self) -> u32 {
70 self.from_column.num_vals()
71 }
72
73 fn iter(&self) -> Box<dyn Iterator<Item = Output> + '_> {
74 Box::new(
75 self.from_column
76 .iter()
77 .map(|el| self.monotonic_mapping.mapping(el)),
78 )
79 }
80
81 fn get_row_ids_for_value_range(
82 &self,
83 range: RangeInclusive<Output>,
84 doc_id_range: Range<u32>,
85 positions: &mut Vec<u32>,
86 ) {
87 self.from_column.get_row_ids_for_value_range(
88 self.monotonic_mapping.inverse(range.start().clone())
89 ..=self.monotonic_mapping.inverse(range.end().clone()),
90 doc_id_range,
91 positions,
92 )
93 }
94
95 }
98
99#[cfg(test)]
100mod tests {
101 use super::*;
102 use crate::column_values::monotonic_mapping::{
103 StrictlyMonotonicMappingInverter, StrictlyMonotonicMappingToInternal,
104 };
105 use crate::column_values::VecColumn;
106
107 #[test]
108 fn test_monotonic_mapping_iter() {
109 let vals: Vec<u64> = (0..100u64).map(|el| el * 10).collect();
110 let col = VecColumn::from(vals);
111 let mapped = monotonic_map_column(
112 col,
113 StrictlyMonotonicMappingInverter::from(StrictlyMonotonicMappingToInternal::<i64>::new()),
114 );
115 let val_i64s: Vec<u64> = mapped.iter().collect();
116 for i in 0..100 {
117 assert_eq!(val_i64s[i as usize], mapped.get_val(i));
118 }
119 }
120}