risingwave_common/row/
slice.rs1use std::ops::{Range, RangeBounds};
16
17use super::Row;
18use crate::types::DatumRef;
19
20#[derive(Debug, Clone)]
22pub struct Slice<R> {
23 row: R,
24 range: Range<usize>,
25}
26
27impl<R: Row> PartialEq for Slice<R> {
28 fn eq(&self, other: &Self) -> bool {
29 self.iter().eq(other.iter())
30 }
31}
32impl<R: Row> Eq for Slice<R> {}
33
34impl<R: Row> Row for Slice<R> {
35 #[inline]
36 fn datum_at(&self, index: usize) -> DatumRef<'_> {
37 assert!(index < self.len());
38 unsafe { self.row.datum_at_unchecked(self.range.start + index) }
40 }
41
42 #[inline]
43 unsafe fn datum_at_unchecked(&self, index: usize) -> DatumRef<'_> {
44 unsafe { self.row.datum_at_unchecked(self.range.start + index) }
45 }
46
47 #[inline]
48 fn len(&self) -> usize {
49 self.range.len()
50 }
51
52 #[inline]
53 fn iter(&self) -> impl Iterator<Item = DatumRef<'_>> {
54 self.row
55 .iter()
56 .skip(self.range.start)
57 .take(self.range.len())
58 }
59}
60
61impl<R: Row> Slice<R> {
62 pub(crate) fn new(row: R, range: impl RangeBounds<usize>) -> Self {
63 use std::ops::Bound::*;
64 let start = match range.start_bound() {
65 Included(&i) => i,
66 Excluded(&i) => i + 1,
67 Unbounded => 0,
68 };
69 let end = match range.end_bound() {
70 Included(&i) => i + 1,
71 Excluded(&i) => i,
72 Unbounded => row.len(),
73 };
74 let range = start..end;
75 assert!(range.end <= row.len(), "range out of bounds");
76 Self { row, range }
77 }
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83 use crate::row::{OwnedRow, RowExt};
84 use crate::types::{ScalarImpl, ScalarRefImpl};
85
86 #[test]
87 fn test_slice() {
88 let r0 = OwnedRow::new((0..=8).map(|i| Some(ScalarImpl::Int64(i))).collect());
89 let r_expected = OwnedRow::new((2..4).map(|i| Some(ScalarImpl::Int64(i))).collect());
90
91 let r = r0.slice(2..4);
92 assert_eq!(r.len(), 2);
93 assert!(r.iter().eq(r_expected.iter()));
94
95 for i in 0..2 {
96 assert_eq!(r.datum_at(i), Some(ScalarRefImpl::Int64(i as i64 + 2)));
97 }
98 }
99}