Skip to main content

reifydb_core/value/column/buffer/
reorder.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3
4use reifydb_value::util::bitvec::BitVec;
5
6use crate::value::column::{ColumnBuffer, buffer::with_container};
7
8impl ColumnBuffer {
9	pub fn reorder(&mut self, indices: &[usize]) {
10		match self {
11			ColumnBuffer::Option {
12				inner,
13				bitvec,
14			} => {
15				inner.reorder(indices);
16				let mut new_bitvec = BitVec::with_capacity(indices.len());
17				for &idx in indices {
18					if idx < bitvec.len() {
19						new_bitvec.push(bitvec.get(idx));
20					} else {
21						new_bitvec.push(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_runtime::context::{
34		clock::{Clock, MockClock},
35		rng::Rng,
36	};
37	use reifydb_value::value::{Value, dictionary::DictionaryEntryId, identity::IdentityId, value_type::ValueType};
38
39	use crate::value::column::ColumnBuffer;
40
41	fn test_clock_and_rng() -> (MockClock, Clock, Rng) {
42		let mock = MockClock::from_millis(1000);
43		let clock = Clock::Mock(mock.clone());
44		let rng = Rng::seeded(42);
45		(mock, clock, rng)
46	}
47
48	#[test]
49	fn test_reorder_bool() {
50		let mut col = ColumnBuffer::bool([true, false, true]);
51		col.reorder(&[2, 0, 1]);
52
53		assert_eq!(col.len(), 3);
54		assert_eq!(col.get_value(0), Value::Boolean(true));
55		assert_eq!(col.get_value(1), Value::Boolean(true));
56		assert_eq!(col.get_value(2), Value::Boolean(false));
57	}
58
59	#[test]
60	fn test_reorder_float4() {
61		let mut col = ColumnBuffer::float4([1.0, 2.0, 3.0]);
62		col.reorder(&[2, 0, 1]);
63
64		assert_eq!(col.len(), 3);
65		match col.get_value(0) {
66			Value::Float4(v) => assert_eq!(v.value(), 3.0),
67			_ => panic!("Expected Float4"),
68		}
69		match col.get_value(1) {
70			Value::Float4(v) => assert_eq!(v.value(), 1.0),
71			_ => panic!("Expected Float4"),
72		}
73		match col.get_value(2) {
74			Value::Float4(v) => assert_eq!(v.value(), 2.0),
75			_ => panic!("Expected Float4"),
76		}
77	}
78
79	#[test]
80	fn test_reorder_int4() {
81		let mut col = ColumnBuffer::int4([1, 2, 3]);
82		col.reorder(&[2, 0, 1]);
83
84		assert_eq!(col.len(), 3);
85		assert_eq!(col.get_value(0), Value::Int4(3));
86		assert_eq!(col.get_value(1), Value::Int4(1));
87		assert_eq!(col.get_value(2), Value::Int4(2));
88	}
89
90	#[test]
91	fn test_reorder_string() {
92		let mut col = ColumnBuffer::utf8(["a".to_string(), "b".to_string(), "c".to_string()]);
93		col.reorder(&[2, 0, 1]);
94
95		assert_eq!(col.len(), 3);
96		assert_eq!(col.get_value(0), Value::Utf8("c".to_string()));
97		assert_eq!(col.get_value(1), Value::Utf8("a".to_string()));
98		assert_eq!(col.get_value(2), Value::Utf8("b".to_string()));
99	}
100
101	#[test]
102	fn test_reorder_none() {
103		let mut col = ColumnBuffer::none_typed(ValueType::Boolean, 3);
104		col.reorder(&[2, 0, 1]);
105		assert_eq!(col.len(), 3);
106
107		col.reorder(&[1, 0]);
108		assert_eq!(col.len(), 2);
109	}
110
111	#[test]
112	fn test_reorder_identity_id() {
113		let (mock, clock, rng) = test_clock_and_rng();
114		let id1 = IdentityId::generate(&clock, &rng);
115		mock.advance_millis(1);
116		let id2 = IdentityId::generate(&clock, &rng);
117		mock.advance_millis(1);
118		let id3 = IdentityId::generate(&clock, &rng);
119
120		let mut col = ColumnBuffer::identity_id([id1, id2, id3]);
121		col.reorder(&[2, 0, 1]);
122
123		assert_eq!(col.len(), 3);
124		assert_eq!(col.get_value(0), Value::IdentityId(id3));
125		assert_eq!(col.get_value(1), Value::IdentityId(id1));
126		assert_eq!(col.get_value(2), Value::IdentityId(id2));
127	}
128
129	#[test]
130	fn test_reorder_dictionary_id() {
131		let e1 = DictionaryEntryId::U4(10);
132		let e2 = DictionaryEntryId::U4(20);
133		let e3 = DictionaryEntryId::U4(30);
134
135		let mut col = ColumnBuffer::dictionary_id([e1, e2, e3]);
136		col.reorder(&[2, 0, 1]);
137
138		assert_eq!(col.len(), 3);
139		assert_eq!(col.get_value(0), Value::DictionaryId(e3));
140		assert_eq!(col.get_value(1), Value::DictionaryId(e1));
141		assert_eq!(col.get_value(2), Value::DictionaryId(e2));
142	}
143}