Skip to main content

reifydb_core/value/column/data/
reorder.rs

1// SPDX-License-Identifier: AGPL-3.0-or-later
2// Copyright (c) 2025 ReifyDB
3
4use reifydb_type::storage::DataBitVec;
5
6use crate::value::column::{ColumnData, data::with_container};
7
8impl ColumnData {
9	pub fn reorder(&mut self, indices: &[usize]) {
10		match self {
11			ColumnData::Option {
12				inner,
13				bitvec,
14			} => {
15				inner.reorder(indices);
16				let mut new_bitvec = DataBitVec::spawn(bitvec, indices.len());
17				for &idx in indices {
18					if idx < DataBitVec::len(bitvec) {
19						DataBitVec::push(&mut new_bitvec, DataBitVec::get(bitvec, idx));
20					} else {
21						DataBitVec::push(&mut new_bitvec, false);
22					}
23				}
24				*bitvec = new_bitvec;
25			}
26			_ => with_container!(self, |c| c.reorder(indices)),
27		}
28	}
29}
30
31#[cfg(test)]
32pub mod tests {
33	use reifydb_type::value::{Value, identity::IdentityId, r#type::Type};
34
35	use crate::value::column::ColumnData;
36
37	#[test]
38	fn test_reorder_bool() {
39		let mut col = ColumnData::bool([true, false, true]);
40		col.reorder(&[2, 0, 1]);
41
42		assert_eq!(col.len(), 3);
43		assert_eq!(col.get_value(0), Value::Boolean(true));
44		assert_eq!(col.get_value(1), Value::Boolean(true));
45		assert_eq!(col.get_value(2), Value::Boolean(false));
46	}
47
48	#[test]
49	fn test_reorder_float4() {
50		let mut col = ColumnData::float4([1.0, 2.0, 3.0]);
51		col.reorder(&[2, 0, 1]);
52
53		assert_eq!(col.len(), 3);
54		// Check data after reordering
55		match col.get_value(0) {
56			Value::Float4(v) => assert_eq!(v.value(), 3.0),
57			_ => panic!("Expected Float4"),
58		}
59		match col.get_value(1) {
60			Value::Float4(v) => assert_eq!(v.value(), 1.0),
61			_ => panic!("Expected Float4"),
62		}
63		match col.get_value(2) {
64			Value::Float4(v) => assert_eq!(v.value(), 2.0),
65			_ => panic!("Expected Float4"),
66		}
67	}
68
69	#[test]
70	fn test_reorder_int4() {
71		let mut col = ColumnData::int4([1, 2, 3]);
72		col.reorder(&[2, 0, 1]);
73
74		assert_eq!(col.len(), 3);
75		assert_eq!(col.get_value(0), Value::Int4(3));
76		assert_eq!(col.get_value(1), Value::Int4(1));
77		assert_eq!(col.get_value(2), Value::Int4(2));
78	}
79
80	#[test]
81	fn test_reorder_string() {
82		let mut col = ColumnData::utf8(["a".to_string(), "b".to_string(), "c".to_string()]);
83		col.reorder(&[2, 0, 1]);
84
85		assert_eq!(col.len(), 3);
86		assert_eq!(col.get_value(0), Value::Utf8("c".to_string()));
87		assert_eq!(col.get_value(1), Value::Utf8("a".to_string()));
88		assert_eq!(col.get_value(2), Value::Utf8("b".to_string()));
89	}
90
91	#[test]
92	fn test_reorder_none() {
93		let mut col = ColumnData::none_typed(Type::Boolean, 3);
94		col.reorder(&[2, 0, 1]);
95		assert_eq!(col.len(), 3);
96
97		col.reorder(&[1, 0]);
98		assert_eq!(col.len(), 2);
99	}
100
101	#[test]
102	fn test_reorder_identity_id() {
103		let id1 = IdentityId::generate();
104		let id2 = IdentityId::generate();
105		let id3 = IdentityId::generate();
106
107		let mut col = ColumnData::identity_id([id1, id2, id3]);
108		col.reorder(&[2, 0, 1]);
109
110		assert_eq!(col.len(), 3);
111		assert_eq!(col.get_value(0), Value::IdentityId(id3));
112		assert_eq!(col.get_value(1), Value::IdentityId(id1));
113		assert_eq!(col.get_value(2), Value::IdentityId(id2));
114	}
115
116	#[test]
117	fn test_reorder_dictionary_id() {
118		use reifydb_type::value::dictionary::DictionaryEntryId;
119
120		let e1 = DictionaryEntryId::U4(10);
121		let e2 = DictionaryEntryId::U4(20);
122		let e3 = DictionaryEntryId::U4(30);
123
124		let mut col = ColumnData::dictionary_id([e1, e2, e3]);
125		col.reorder(&[2, 0, 1]);
126
127		assert_eq!(col.len(), 3);
128		assert_eq!(col.get_value(0), Value::DictionaryId(e3));
129		assert_eq!(col.get_value(1), Value::DictionaryId(e1));
130		assert_eq!(col.get_value(2), Value::DictionaryId(e2));
131	}
132}