1use std::sync::Arc;
5
6use arrow_array::{Array, RecordBatch, make_array};
7use arrow_buffer::{BooleanBuffer, Buffer, NullBuffer};
8use arrow_data::{ArrayData, ArrayDataBuilder, transform::MutableArrayData};
9
10pub fn deep_copy_buffer(buffer: &Buffer) -> Buffer {
11 Buffer::from(buffer.as_slice())
12}
13
14pub fn deep_copy_nulls(nulls: Option<&NullBuffer>) -> Option<NullBuffer> {
15 let nulls = nulls?;
16 let bit_buffer = deep_copy_buffer(nulls.inner().inner());
17 Some(unsafe {
27 NullBuffer::new_unchecked(
28 BooleanBuffer::new(bit_buffer, nulls.offset(), nulls.len()),
29 nulls.null_count(),
30 )
31 })
32}
33
34pub fn deep_copy_array_data(data: &ArrayData) -> ArrayData {
35 let data_type = data.data_type().clone();
36 let len = data.len();
37 let nulls = deep_copy_nulls(data.nulls());
38 let offset = data.offset();
39 let buffers = data
40 .buffers()
41 .iter()
42 .map(deep_copy_buffer)
43 .collect::<Vec<_>>();
44 let child_data = data
45 .child_data()
46 .iter()
47 .map(deep_copy_array_data)
48 .collect::<Vec<_>>();
49 unsafe {
63 ArrayDataBuilder::new(data_type)
64 .len(len)
65 .nulls(nulls)
66 .offset(offset)
67 .buffers(buffers)
68 .child_data(child_data)
69 .build_unchecked()
70 }
71}
72
73pub fn deep_copy_array(array: &dyn Array) -> Arc<dyn Array> {
74 let data = array.to_data();
75 let data = deep_copy_array_data(&data);
76 make_array(data)
77}
78
79pub fn deep_copy_batch(batch: &RecordBatch) -> crate::Result<RecordBatch> {
80 let arrays = batch
81 .columns()
82 .iter()
83 .map(|array| deep_copy_array(array))
84 .collect::<Vec<_>>();
85 RecordBatch::try_new(batch.schema(), arrays)
86}
87
88pub fn deep_copy_array_data_sliced(data: &ArrayData) -> ArrayData {
91 let mut mutable = MutableArrayData::new(vec![data], false, data.len());
93
94 mutable.extend(0, data.offset(), data.offset() + data.len());
96
97 mutable.freeze()
99}
100
101pub fn deep_copy_array_sliced(array: &dyn Array) -> Arc<dyn Array> {
103 let data = array.to_data();
104 let data = deep_copy_array_data_sliced(&data);
105 make_array(data)
106}
107
108pub fn deep_copy_batch_sliced(batch: &RecordBatch) -> crate::Result<RecordBatch> {
110 let arrays = batch
111 .columns()
112 .iter()
113 .map(|array| deep_copy_array_sliced(array))
114 .collect::<Vec<_>>();
115 RecordBatch::try_new(batch.schema(), arrays)
116}
117
118#[cfg(test)]
119mod tests {
120 use std::sync::Arc;
121
122 use arrow_array::{Array, Int32Array, RecordBatch, StringArray};
123 use arrow_schema::{DataType, Field, Schema};
124
125 #[test]
126 fn test_deep_copy_sliced_array_with_nulls() {
127 let array = Arc::new(Int32Array::from(vec![
128 Some(1),
129 None,
130 Some(3),
131 None,
132 Some(5),
133 ]));
134 let sliced_array = array.slice(1, 3);
135 let copied_array = super::deep_copy_array(&sliced_array);
136 assert_eq!(sliced_array.len(), copied_array.len());
137 assert_eq!(sliced_array.nulls(), copied_array.nulls());
138 }
139
140 #[test]
141 fn test_deep_copy_array_data_sliced() {
142 let array = Int32Array::from((0..1000).collect::<Vec<i32>>());
143 let sliced = array.slice(100, 10);
144
145 let sliced_data = sliced.to_data();
146 let copied_data = super::deep_copy_array_data_sliced(&sliced_data);
147
148 assert_eq!(copied_data.len(), 10);
149 assert_eq!(copied_data.offset(), 0);
150
151 let copied_array = Int32Array::from(copied_data);
153 for i in 0..10 {
154 assert_eq!(copied_array.value(i), 100 + i as i32);
155 }
156 }
157
158 #[test]
159 fn test_deep_copy_array_sliced() {
160 let array = Arc::new(Int32Array::from(vec![1, 2, 3, 4, 5]));
161 let sliced = array.slice(1, 3);
162
163 let copied = super::deep_copy_array_sliced(&sliced);
164
165 assert_eq!(copied.len(), 3);
166 let copied_int = copied.as_any().downcast_ref::<Int32Array>().unwrap();
167 assert_eq!(copied_int.value(0), 2);
168 assert_eq!(copied_int.value(1), 3);
169 assert_eq!(copied_int.value(2), 4);
170 }
171
172 #[test]
173 fn test_deep_copy_batch_sliced() {
174 let schema = Arc::new(Schema::new(vec![
175 Field::new("id", DataType::Int32, false),
176 Field::new("name", DataType::Utf8, false),
177 ]));
178
179 let id_array = Arc::new(Int32Array::from((0..100).collect::<Vec<i32>>()));
180 let name_array = Arc::new(StringArray::from(
181 (0..100)
182 .map(|i| format!("name_{}", i))
183 .collect::<Vec<String>>(),
184 ));
185
186 let batch = RecordBatch::try_new(
187 schema,
188 vec![id_array as Arc<dyn Array>, name_array as Arc<dyn Array>],
189 )
190 .unwrap();
191
192 let sliced = batch.slice(10, 5);
193 let copied = super::deep_copy_batch_sliced(&sliced).unwrap();
194
195 assert_eq!(copied.num_rows(), 5);
196 assert_eq!(copied.num_columns(), 2);
197
198 let id_col = copied
200 .column(0)
201 .as_any()
202 .downcast_ref::<Int32Array>()
203 .unwrap();
204 let name_col = copied
205 .column(1)
206 .as_any()
207 .downcast_ref::<StringArray>()
208 .unwrap();
209
210 for i in 0..5 {
211 assert_eq!(id_col.value(i), 10 + i as i32);
212 assert_eq!(name_col.value(i), format!("name_{}", 10 + i));
213 }
214 }
215
216 #[test]
217 fn test_deep_copy_array_sliced_with_nulls() {
218 let array = Arc::new(Int32Array::from(vec![
219 Some(1),
220 None,
221 Some(3),
222 None,
223 Some(5),
224 ]));
225 let sliced = array.slice(1, 3); let copied = super::deep_copy_array_sliced(&sliced);
228
229 assert_eq!(copied.len(), 3);
230 assert_eq!(copied.null_count(), 2); let copied_int = copied.as_any().downcast_ref::<Int32Array>().unwrap();
233 assert!(!copied_int.is_valid(0)); assert!(copied_int.is_valid(1)); assert!(!copied_int.is_valid(2)); assert_eq!(copied_int.value(1), 3);
237 }
238}