binius_math/
rows_batch.rs1use std::ops::{Bound, RangeBounds};
4
5pub struct RowsBatch<'a, T> {
7 rows: Vec<&'a [T]>,
8 row_len: usize,
9}
10
11impl<'a, T> RowsBatch<'a, T> {
12 #[inline]
17 pub fn new(rows: Vec<&'a [T]>, row_len: usize) -> Self {
18 for row in &rows {
19 assert_eq!(row.len(), row_len);
20 }
21
22 Self { rows, row_len }
23 }
24
25 #[inline]
30 pub fn new_from_iter(rows: impl IntoIterator<Item = &'a [T]>, row_len: usize) -> Self {
31 let rows = rows.into_iter().map(|x| &x[..row_len]).collect();
32 Self { rows, row_len }
33 }
34
35 #[inline(always)]
36 pub fn get_ref(&self) -> RowsBatchRef<'_, T> {
37 RowsBatchRef {
38 rows: self.rows.as_slice(),
39 row_len: self.row_len,
40 offset: 0,
41 }
42 }
43}
44
45pub struct RowsBatchRef<'a, T> {
53 rows: &'a [&'a [T]],
54 row_len: usize,
55 offset: usize,
56}
57
58impl<'a, T> RowsBatchRef<'a, T> {
59 #[inline]
64 pub fn new(rows: &'a [&'a [T]], row_len: usize) -> Self {
65 Self::new_with_offset(rows, 0, row_len)
66 }
67
68 #[inline]
73 pub fn new_with_offset(rows: &'a [&'a [T]], offset: usize, row_len: usize) -> Self {
74 for row in rows {
75 assert!(offset + row_len <= row.len());
76 }
77
78 Self {
79 rows,
80 row_len,
81 offset,
82 }
83 }
84
85 pub unsafe fn new_unchecked(rows: &'a [&'a [T]], row_len: usize) -> Self {
92 unsafe { Self::new_with_offset_unchecked(rows, 0, row_len) }
93 }
94
95 pub unsafe fn new_with_offset_unchecked(
102 rows: &'a [&'a [T]],
103 offset: usize,
104 row_len: usize,
105 ) -> Self {
106 Self {
107 rows,
108 row_len,
109 offset,
110 }
111 }
112
113 #[inline]
114 pub fn iter(&self) -> impl Iterator<Item = &'a [T]> + '_ {
115 self.rows.as_ref().iter().copied()
116 }
117
118 #[inline(always)]
119 pub fn row(&self, index: usize) -> &'a [T] {
120 &self.rows[index][self.offset..self.offset + self.row_len]
121 }
122
123 #[inline(always)]
124 pub fn n_rows(&self) -> usize {
125 self.rows.as_ref().len()
126 }
127
128 #[inline(always)]
129 pub fn row_len(&self) -> usize {
130 self.row_len
131 }
132
133 #[inline(always)]
134 pub fn is_empty(&self) -> bool {
135 self.rows.as_ref().is_empty()
136 }
137
138 pub fn map(&self, indices: impl AsRef<[usize]>) -> RowsBatch<'a, T> {
140 let rows = indices.as_ref().iter().map(|&i| self.rows[i]).collect();
141
142 RowsBatch {
143 rows,
144 row_len: self.row_len,
145 }
146 }
147
148 pub fn columns_subrange(&self, range: impl RangeBounds<usize>) -> Self {
150 let start = match range.start_bound() {
151 Bound::Included(&start) => start,
152 Bound::Excluded(&start) => start + 1,
153 Bound::Unbounded => 0,
154 };
155 let end = match range.end_bound() {
156 Bound::Included(&end) => end + 1,
157 Bound::Excluded(&end) => end,
158 Bound::Unbounded => self.row_len,
159 };
160
161 assert!(start <= end);
162 assert!(end <= self.row_len);
163
164 Self {
165 rows: self.rows,
166 row_len: end - start,
167 offset: self.offset + start,
168 }
169 }
170}