1use super::BtiError;
18use crate::error::Result;
19use crate::types::{UdtValue, Value};
20
21pub struct ByteComparableEncoder {
27 buffer: Vec<u8>,
29 config: EncoderConfig,
31}
32
33#[derive(Debug, Clone)]
35pub struct EncoderConfig {
36 pub use_varint_encoding: bool,
38 pub max_nesting_depth: usize,
40 pub enable_prefix_compression: bool,
42 pub strict_compliance: bool,
44}
45
46impl Default for EncoderConfig {
47 fn default() -> Self {
48 Self {
49 use_varint_encoding: true,
50 max_nesting_depth: 32,
51 enable_prefix_compression: true,
52 strict_compliance: true,
53 }
54 }
55}
56
57mod type_prefixes {
59 pub const NULL: u8 = 0x00;
60 pub const BOOLEAN_FALSE: u8 = 0x01;
61 pub const BOOLEAN_TRUE: u8 = 0x02;
62 pub const TINYINT: u8 = 0x10;
63 pub const SMALLINT: u8 = 0x11;
64 pub const INTEGER: u8 = 0x12;
65 pub const BIGINT: u8 = 0x13;
66 pub const FLOAT: u8 = 0x20;
67 pub const DOUBLE: u8 = 0x21;
68 #[allow(dead_code)]
69 pub const DECIMAL: u8 = 0x22;
70 #[allow(dead_code)]
71 pub const VARINT: u8 = 0x23;
72 pub const TEXT: u8 = 0x30;
73 pub const BLOB: u8 = 0x31;
74 pub const UUID: u8 = 0x40;
75 pub const TIMESTAMP: u8 = 0x41;
76 #[allow(dead_code)]
77 pub const DATE: u8 = 0x42;
78 #[allow(dead_code)]
79 pub const TIME: u8 = 0x43;
80 #[allow(dead_code)]
81 pub const DURATION: u8 = 0x44;
82 pub const LIST: u8 = 0x50;
83 pub const SET: u8 = 0x51;
84 pub const MAP: u8 = 0x52;
85 pub const TUPLE: u8 = 0x60;
86 pub const UDT: u8 = 0x61;
87 pub const FROZEN: u8 = 0x70;
88 #[allow(dead_code)]
89 pub const TOMBSTONE: u8 = 0x80;
90 #[allow(dead_code)]
91 pub const ESCAPE: u8 = 0xFF;
92 pub const SEPARATOR: u8 = 0x00;
93 pub const TERMINATOR: u8 = 0x01;
94}
95
96mod escape_sequences {
98 #[allow(dead_code)]
99 pub const ESCAPE_BYTE: u8 = 0xFF;
100 #[allow(dead_code)]
101 pub const ESCAPED_NULL: &[u8] = &[0xFF, 0x00];
102 #[allow(dead_code)]
103 pub const ESCAPED_ESCAPE: &[u8] = &[0xFF, 0xFF];
104 #[allow(dead_code)]
105 pub const ESCAPED_SEPARATOR: &[u8] = &[0xFF, 0x01];
106}
107
108impl Default for ByteComparableEncoder {
109 fn default() -> Self {
110 Self::new()
111 }
112}
113
114impl ByteComparableEncoder {
115 pub fn new() -> Self {
117 Self {
118 buffer: Vec::new(),
119 config: EncoderConfig::default(),
120 }
121 }
122
123 pub fn with_config(config: EncoderConfig) -> Self {
125 Self {
126 buffer: Vec::new(),
127 config,
128 }
129 }
130
131 pub fn config(&self) -> &EncoderConfig {
133 &self.config
134 }
135
136 pub fn set_config(&mut self, config: EncoderConfig) {
138 self.config = config;
139 }
140
141 pub fn encode_value(&mut self, value: &Value) -> Result<Vec<u8>> {
143 self.buffer.clear();
144 self.encode_value_to_buffer(value)?;
145 Ok(self.buffer.clone())
146 }
147
148 pub fn encode_composite_key(&mut self, values: &[Value]) -> Result<Vec<u8>> {
150 self.buffer.clear();
151
152 for (i, value) in values.iter().enumerate() {
153 if i > 0 {
154 self.buffer.push(0x00);
156 }
157 self.encode_value_to_buffer(value)?;
158 }
159
160 Ok(self.buffer.clone())
161 }
162
163 fn encode_value_to_buffer(&mut self, value: &Value) -> Result<()> {
165 self.encode_value_to_buffer_with_depth(value, 0)
166 }
167
168 fn encode_value_to_buffer_with_depth(&mut self, value: &Value, depth: usize) -> Result<()> {
170 if depth > self.config.max_nesting_depth {
171 return Err(BtiError::InvalidByteComparableKey(format!(
172 "Maximum nesting depth {} exceeded",
173 self.config.max_nesting_depth
174 ))
175 .into());
176 }
177
178 match value {
179 Value::Null => self.encode_null(),
180 Value::Boolean(b) => self.encode_boolean(*b),
181 Value::TinyInt(i) => self.encode_tinyint(*i),
182 Value::SmallInt(i) => self.encode_smallint(*i),
183 Value::Integer(i) => self.encode_int(*i),
184 Value::BigInt(i) => self.encode_bigint(*i),
185 Value::Counter(c) => self.encode_bigint(*c), Value::Float32(f) => self.encode_float32(*f),
187 Value::Float(f) => self.encode_double(*f),
188 Value::Text(s) => self
189 .encode_text(std::str::from_utf8(s).map_err(|e| {
190 crate::Error::corruption(format!("invalid UTF-8 in text: {e}"))
191 })?),
192 Value::Blob(bytes) => self.encode_blob(bytes),
193 Value::Uuid(uuid) => self.encode_uuid_bytes(uuid),
194 Value::Timestamp(ts) => self.encode_timestamp(*ts),
195 Value::Json(json) => self.encode_json(json),
196 Value::List(items) => self.encode_list_with_depth(items, depth + 1),
197 Value::Set(items) => self.encode_set_with_depth(items, depth + 1),
198 Value::Map(map) => self.encode_map_with_depth(map, depth + 1),
199 Value::Tuple(items) => self.encode_tuple_with_depth(items, depth + 1),
200 Value::Udt(udt) => self.encode_udt_with_depth(udt, depth + 1),
201 Value::Frozen(inner) => {
202 self.buffer.push(type_prefixes::FROZEN);
203 self.encode_value_to_buffer_with_depth(inner, depth + 1)
204 }
205 Value::Varint(data) => {
206 self.encode_blob(data)
208 }
209 Value::Decimal { scale: _, unscaled } => self.encode_blob(unscaled), Value::Duration {
211 months,
212 days,
213 nanos,
214 } => {
215 self.buffer.push(type_prefixes::DURATION);
217 self.encode_int(*months)?;
218 self.encode_int(*days)?;
219 self.encode_bigint(*nanos)?;
220 Ok(())
221 }
222 Value::Tombstone(_) => {
223 self.buffer.push(type_prefixes::NULL);
225 self.buffer.push(0xFF); Ok(())
227 }
228 Value::Date(d) => {
229 self.buffer.push(type_prefixes::DATE);
230 self.encode_int(*d)
231 }
232 Value::Time(t) => {
233 self.buffer.push(type_prefixes::TIME);
234 self.encode_bigint(*t)
235 }
236 Value::Inet(bytes) => self.encode_blob(bytes),
237 }
238 }
239
240 fn encode_null(&mut self) -> Result<()> {
242 self.buffer.push(type_prefixes::NULL);
243 Ok(())
244 }
245
246 fn encode_text(&mut self, text: &str) -> Result<()> {
248 self.buffer.push(type_prefixes::TEXT);
249
250 for &byte in text.as_bytes() {
252 match byte {
253 0x00 => self
254 .buffer
255 .extend_from_slice(escape_sequences::ESCAPED_NULL),
256 0xFF => self
257 .buffer
258 .extend_from_slice(escape_sequences::ESCAPED_ESCAPE),
259 _ => self.buffer.push(byte),
260 }
261 }
262
263 self.buffer.push(type_prefixes::TERMINATOR);
265 Ok(())
266 }
267
268 fn encode_json(&mut self, json: &serde_json::Value) -> Result<()> {
270 let json_str = json.to_string();
271 self.encode_text(&json_str)
272 }
273
274 fn encode_tinyint(&mut self, value: i8) -> Result<()> {
276 self.buffer.push(type_prefixes::TINYINT);
277 let unsigned = (value as i16 + 128) as u8;
279 self.buffer.push(unsigned);
280 Ok(())
281 }
282
283 fn encode_smallint(&mut self, value: i16) -> Result<()> {
285 self.buffer.push(type_prefixes::SMALLINT);
286 let unsigned = (value as i32 + 32768) as u16;
288 self.buffer.extend_from_slice(&unsigned.to_be_bytes());
289 Ok(())
290 }
291
292 fn encode_int(&mut self, value: i32) -> Result<()> {
294 self.buffer.push(type_prefixes::INTEGER);
295
296 let unsigned = (value as u32) ^ 0x8000_0000;
299
300 self.buffer.extend_from_slice(&unsigned.to_be_bytes());
301 Ok(())
302 }
303
304 fn encode_bigint(&mut self, value: i64) -> Result<()> {
306 self.buffer.push(type_prefixes::BIGINT);
307
308 let unsigned = if value >= 0 {
310 (value as u64) + 0x8000_0000_0000_0000
311 } else {
312 (value as u64) ^ 0xFFFF_FFFF_FFFF_FFFF
313 };
314
315 self.buffer.extend_from_slice(&unsigned.to_be_bytes());
316 Ok(())
317 }
318
319 fn encode_uuid_bytes(&mut self, uuid: &[u8; 16]) -> Result<()> {
321 self.buffer.push(type_prefixes::UUID);
322 self.buffer.extend_from_slice(uuid);
324 Ok(())
325 }
326
327 fn encode_timestamp(&mut self, timestamp: i64) -> Result<()> {
329 self.buffer.push(type_prefixes::TIMESTAMP);
330
331 let unsigned = if timestamp >= 0 {
333 (timestamp as u64) + 0x8000_0000_0000_0000
334 } else {
335 (timestamp as u64) ^ 0xFFFF_FFFF_FFFF_FFFF
336 };
337
338 self.buffer.extend_from_slice(&unsigned.to_be_bytes());
339 Ok(())
340 }
341
342 fn encode_boolean(&mut self, value: bool) -> Result<()> {
344 if value {
345 self.buffer.push(type_prefixes::BOOLEAN_TRUE);
346 } else {
347 self.buffer.push(type_prefixes::BOOLEAN_FALSE);
348 }
349 Ok(())
350 }
351
352 fn encode_float32(&mut self, value: f32) -> Result<()> {
354 self.buffer.push(type_prefixes::FLOAT);
355
356 if value.is_nan() {
358 self.buffer.extend_from_slice(&[0xFF, 0xFF, 0xFF, 0xFF]);
360 return Ok(());
361 }
362
363 let bits = value.to_bits();
364
365 let adjusted = if (bits & 0x8000_0000) == 0 {
367 bits | 0x8000_0000
369 } else {
370 !bits
372 };
373
374 self.buffer.extend_from_slice(&adjusted.to_be_bytes());
375 Ok(())
376 }
377
378 fn encode_double(&mut self, value: f64) -> Result<()> {
380 self.buffer.push(type_prefixes::DOUBLE);
381
382 if value.is_nan() {
384 self.buffer
386 .extend_from_slice(&[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]);
387 return Ok(());
388 }
389
390 let bits = value.to_bits();
391
392 let adjusted = if (bits & 0x8000_0000_0000_0000) == 0 {
394 bits | 0x8000_0000_0000_0000
396 } else {
397 !bits
399 };
400
401 self.buffer.extend_from_slice(&adjusted.to_be_bytes());
402 Ok(())
403 }
404
405 fn encode_blob(&mut self, bytes: &[u8]) -> Result<()> {
407 self.buffer.push(type_prefixes::BLOB);
408
409 for &byte in bytes {
411 match byte {
412 0x00 => self
413 .buffer
414 .extend_from_slice(escape_sequences::ESCAPED_NULL),
415 0xFF => self
416 .buffer
417 .extend_from_slice(escape_sequences::ESCAPED_ESCAPE),
418 _ => self.buffer.push(byte),
419 }
420 }
421
422 self.buffer.push(type_prefixes::TERMINATOR);
424 Ok(())
425 }
426
427 fn encode_list_with_depth(&mut self, items: &[Value], depth: usize) -> Result<()> {
429 self.buffer.push(type_prefixes::LIST);
430
431 if self.config.use_varint_encoding {
433 self.encode_varint(items.len() as u64)?;
434 } else {
435 self.buffer
436 .extend_from_slice(&(items.len() as u32).to_be_bytes());
437 }
438
439 for (i, item) in items.iter().enumerate() {
441 if i > 0 {
442 self.buffer.push(type_prefixes::SEPARATOR);
443 }
444 self.encode_value_to_buffer_with_depth(item, depth)?;
445 }
446
447 self.buffer.push(type_prefixes::TERMINATOR);
449 Ok(())
450 }
451
452 #[allow(dead_code)]
454 fn encode_list(&mut self, items: &[Value]) -> Result<()> {
455 self.encode_list_with_depth(items, 1)
456 }
457
458 fn encode_set_with_depth(&mut self, items: &[Value], _depth: usize) -> Result<()> {
460 self.buffer.push(type_prefixes::SET);
461
462 let mut encoded_items = Vec::new();
464
465 for item in items {
466 let mut encoder = ByteComparableEncoder::with_config(self.config.clone());
467 let encoded = encoder.encode_value(item)?;
468 encoded_items.push(encoded);
469 }
470
471 encoded_items.sort();
473
474 if self.config.use_varint_encoding {
476 self.encode_varint(encoded_items.len() as u64)?;
477 } else {
478 self.buffer
479 .extend_from_slice(&(encoded_items.len() as u32).to_be_bytes());
480 }
481
482 for (i, encoded_item) in encoded_items.iter().enumerate() {
484 if i > 0 {
485 self.buffer.push(type_prefixes::SEPARATOR);
486 }
487 self.buffer.extend_from_slice(encoded_item);
488 }
489
490 self.buffer.push(type_prefixes::TERMINATOR);
492 Ok(())
493 }
494
495 #[allow(dead_code)]
497 fn encode_set(&mut self, items: &[Value]) -> Result<()> {
498 self.encode_set_with_depth(items, 1)
499 }
500
501 fn encode_map_with_depth(&mut self, map: &Vec<(Value, Value)>, _depth: usize) -> Result<()> {
503 self.buffer.push(type_prefixes::MAP);
504
505 let mut encoded_pairs = Vec::new();
507
508 for (key, value) in map {
509 let mut key_encoder = ByteComparableEncoder::with_config(self.config.clone());
510 let encoded_key = key_encoder.encode_value(key)?;
511
512 let mut value_encoder = ByteComparableEncoder::with_config(self.config.clone());
513 let encoded_value = value_encoder.encode_value(value)?;
514
515 encoded_pairs.push((encoded_key, encoded_value));
516 }
517
518 encoded_pairs.sort_by(|a, b| a.0.cmp(&b.0));
520
521 if self.config.use_varint_encoding {
523 self.encode_varint(encoded_pairs.len() as u64)?;
524 } else {
525 self.buffer
526 .extend_from_slice(&(encoded_pairs.len() as u32).to_be_bytes());
527 }
528
529 for (i, (encoded_key, encoded_value)) in encoded_pairs.iter().enumerate() {
531 if i > 0 {
532 self.buffer.push(type_prefixes::SEPARATOR);
533 }
534
535 self.buffer.extend_from_slice(encoded_key);
537 self.buffer.push(type_prefixes::SEPARATOR);
538 self.buffer.extend_from_slice(encoded_value);
539 }
540
541 self.buffer.push(type_prefixes::TERMINATOR);
543 Ok(())
544 }
545
546 #[allow(dead_code)]
548 fn encode_map_vec(&mut self, map: &Vec<(Value, Value)>) -> Result<()> {
549 self.encode_map_with_depth(map, 1)
550 }
551
552 fn encode_tuple_with_depth(&mut self, items: &[Value], depth: usize) -> Result<()> {
554 self.buffer.push(type_prefixes::TUPLE);
555
556 if self.config.use_varint_encoding {
558 self.encode_varint(items.len() as u64)?;
559 } else {
560 self.buffer
561 .extend_from_slice(&(items.len() as u32).to_be_bytes());
562 }
563
564 for (i, item) in items.iter().enumerate() {
566 if i > 0 {
567 self.buffer.push(type_prefixes::SEPARATOR);
568 }
569 self.encode_value_to_buffer_with_depth(item, depth)?;
570 }
571
572 self.buffer.push(type_prefixes::TERMINATOR);
574 Ok(())
575 }
576
577 fn encode_udt_with_depth(&mut self, udt: &UdtValue, depth: usize) -> Result<()> {
579 self.buffer.push(type_prefixes::UDT);
580
581 self.encode_text(&udt.keyspace)?;
583 self.encode_text(&udt.type_name)?;
584
585 if self.config.use_varint_encoding {
587 self.encode_varint(udt.fields.len() as u64)?;
588 } else {
589 self.buffer
590 .extend_from_slice(&(udt.fields.len() as u32).to_be_bytes());
591 }
592
593 for (i, field) in udt.fields.iter().enumerate() {
595 if i > 0 {
596 self.buffer.push(type_prefixes::SEPARATOR);
597 }
598
599 self.encode_text(&field.name)?;
601 self.buffer.push(type_prefixes::SEPARATOR);
602
603 match &field.value {
605 Some(value) => self.encode_value_to_buffer_with_depth(value, depth)?,
606 None => self.encode_null()?,
607 }
608 }
609
610 self.buffer.push(type_prefixes::TERMINATOR);
612 Ok(())
613 }
614
615 fn encode_varint(&mut self, mut value: u64) -> Result<()> {
617 while value >= 0x80 {
618 self.buffer.push((value & 0xFF) as u8 | 0x80);
619 value >>= 7;
620 }
621 self.buffer.push(value as u8);
622 Ok(())
623 }
624}
625
626pub struct ByteComparableDecoder;
628
629impl ByteComparableDecoder {
630 pub fn decode_key_debug(encoded: &[u8]) -> String {
632 if encoded.is_empty() {
633 return "<empty>".to_string();
634 }
635
636 let hex: String = encoded
638 .iter()
639 .map(|b| format!("{:02x}", b))
640 .collect::<Vec<_>>()
641 .join(" ");
642
643 if let Ok(text) = std::str::from_utf8(encoded) {
645 let printable_count = text
647 .chars()
648 .filter(|c| c.is_ascii_graphic() || c.is_ascii_whitespace())
649 .count();
650 let total_count = text.chars().count();
651
652 if total_count > 0 && (printable_count as f32 / total_count as f32) >= 0.7 {
653 let clean_text = text.trim_end_matches('\0').trim();
654 if !clean_text.is_empty() {
655 return format!("\"{}\" ({})", clean_text, hex);
656 }
657 }
658 }
659
660 let mut text_parts = Vec::new();
662 let mut current_text = String::new();
663
664 for &byte in encoded {
665 if byte.is_ascii_graphic() || byte == b' ' {
666 current_text.push(byte as char);
667 } else if !current_text.is_empty() {
668 text_parts.push(current_text.clone());
669 current_text.clear();
670 }
671 }
672
673 if !current_text.is_empty() {
674 text_parts.push(current_text);
675 }
676
677 if !text_parts.is_empty() {
679 let text_content = text_parts.join(" ");
680 return format!("\"{}\" ({})", text_content, hex);
681 }
682
683 format!("0x{}", hex)
684 }
685}
686
687pub struct BatchEncoder {
689 encoder: ByteComparableEncoder,
690 batch_buffer: Vec<Vec<u8>>,
691}
692
693impl Default for BatchEncoder {
694 fn default() -> Self {
695 Self::new()
696 }
697}
698
699impl BatchEncoder {
700 pub fn new() -> Self {
702 Self {
703 encoder: ByteComparableEncoder::new(),
704 batch_buffer: Vec::new(),
705 }
706 }
707
708 pub fn encode_batch(&mut self, values: &[Value]) -> Result<Vec<Vec<u8>>> {
710 self.batch_buffer.clear();
711 self.batch_buffer.reserve(values.len());
712
713 for value in values {
714 let encoded = self.encoder.encode_value(value)?;
715 self.batch_buffer.push(encoded);
716 }
717
718 Ok(self.batch_buffer.clone())
719 }
720
721 pub fn clear(&mut self) {
723 self.batch_buffer.clear();
724 }
725}
726
727#[derive(Debug, Clone, Default)]
729pub struct EncoderStats {
730 pub buffer_capacity: usize,
732 pub buffer_size: usize,
734 pub encodings_performed: u64,
736 pub total_bytes_encoded: u64,
738}
739
740impl ByteComparableEncoder {
741 pub fn reserve(&mut self, additional: usize) {
743 self.buffer.reserve(additional);
744 }
745
746 pub fn get_stats(&self) -> EncoderStats {
748 EncoderStats {
749 buffer_capacity: self.buffer.capacity(),
750 buffer_size: self.buffer.len(),
751 encodings_performed: 0, total_bytes_encoded: self.buffer.len() as u64,
753 }
754 }
755
756 pub fn validate_encoded_key(&self, encoded: &[u8]) -> Result<()> {
758 if encoded.is_empty() {
759 return Err(BtiError::InvalidByteComparableKey("Empty encoded key".to_string()).into());
760 }
761
762 let type_prefix = encoded[0];
763
764 match type_prefix {
766 type_prefixes::NULL => {
767 if encoded.len() > 2 {
768 return Err(BtiError::InvalidByteComparableKey(
769 "Null value too long".to_string(),
770 )
771 .into());
772 }
773 }
774 type_prefixes::BOOLEAN_FALSE | type_prefixes::BOOLEAN_TRUE => {
775 if encoded.len() != 1 {
776 return Err(BtiError::InvalidByteComparableKey(
777 "Boolean value should be exactly 1 byte".to_string(),
778 )
779 .into());
780 }
781 }
782 type_prefixes::TINYINT => {
783 if encoded.len() != 2 {
784 return Err(BtiError::InvalidByteComparableKey(
785 "TinyInt should be exactly 2 bytes".to_string(),
786 )
787 .into());
788 }
789 }
790 type_prefixes::SMALLINT => {
791 if encoded.len() != 3 {
792 return Err(BtiError::InvalidByteComparableKey(
793 "SmallInt should be exactly 3 bytes".to_string(),
794 )
795 .into());
796 }
797 }
798 type_prefixes::INTEGER => {
799 if encoded.len() != 5 {
800 return Err(BtiError::InvalidByteComparableKey(
801 "Integer should be exactly 5 bytes".to_string(),
802 )
803 .into());
804 }
805 }
806 type_prefixes::BIGINT | type_prefixes::TIMESTAMP => {
807 if encoded.len() != 9 {
808 return Err(BtiError::InvalidByteComparableKey(
809 "BigInt/Timestamp should be exactly 9 bytes".to_string(),
810 )
811 .into());
812 }
813 }
814 type_prefixes::FLOAT => {
815 if encoded.len() != 5 {
816 return Err(BtiError::InvalidByteComparableKey(
817 "Float should be exactly 5 bytes".to_string(),
818 )
819 .into());
820 }
821 }
822 type_prefixes::DOUBLE => {
823 if encoded.len() != 9 {
824 return Err(BtiError::InvalidByteComparableKey(
825 "Double should be exactly 9 bytes".to_string(),
826 )
827 .into());
828 }
829 }
830 type_prefixes::UUID => {
831 if encoded.len() != 17 {
832 return Err(BtiError::InvalidByteComparableKey(
833 "UUID should be exactly 17 bytes".to_string(),
834 )
835 .into());
836 }
837 }
838 type_prefixes::TEXT | type_prefixes::BLOB => {
839 if encoded.len() < 2 || encoded[encoded.len() - 1] != type_prefixes::TERMINATOR {
840 return Err(BtiError::InvalidByteComparableKey(
841 "Text/Blob should end with terminator".to_string(),
842 )
843 .into());
844 }
845 }
846 type_prefixes::LIST
847 | type_prefixes::SET
848 | type_prefixes::MAP
849 | type_prefixes::TUPLE
850 | type_prefixes::UDT => {
851 if encoded.len() < 2 || encoded[encoded.len() - 1] != type_prefixes::TERMINATOR {
852 return Err(BtiError::InvalidByteComparableKey(
853 "Collection/Complex type should end with terminator".to_string(),
854 )
855 .into());
856 }
857 }
858 _ => {
859 return Err(BtiError::InvalidByteComparableKey(format!(
860 "Unknown type prefix: 0x{:02x}",
861 type_prefix
862 ))
863 .into());
864 }
865 }
866
867 Ok(())
868 }
869}
870
871#[cfg(test)]
872mod tests {
873 use super::*;
874 use uuid::Uuid;
875
876 #[test]
877 fn test_text_encoding() {
878 let mut encoder = ByteComparableEncoder::new();
879
880 let encoded_a = encoder.encode_value(&Value::text("a".to_string())).unwrap();
881 let encoded_b = encoder.encode_value(&Value::text("b".to_string())).unwrap();
882 let encoded_aa = encoder
883 .encode_value(&Value::text("aa".to_string()))
884 .unwrap();
885
886 assert!(encoded_a < encoded_b);
888 assert!(encoded_a < encoded_aa);
889 assert!(encoded_aa < encoded_b);
890 }
891
892 #[test]
893 fn test_integer_encoding() {
894 let mut encoder = ByteComparableEncoder::new();
895
896 let encoded_neg = encoder.encode_value(&Value::Integer(-100)).unwrap();
897 let encoded_zero = encoder.encode_value(&Value::Integer(0)).unwrap();
898 let encoded_pos = encoder.encode_value(&Value::Integer(100)).unwrap();
899
900 assert!(encoded_neg < encoded_zero);
902 assert!(encoded_zero < encoded_pos);
903 }
904
905 #[test]
906 fn test_boolean_encoding() {
907 let mut encoder = ByteComparableEncoder::new();
908
909 let encoded_false = encoder.encode_value(&Value::Boolean(false)).unwrap();
910 let encoded_true = encoder.encode_value(&Value::Boolean(true)).unwrap();
911
912 assert!(encoded_false < encoded_true);
914 }
915
916 #[test]
917 fn test_uuid_encoding() {
918 let mut encoder = ByteComparableEncoder::new();
919
920 let uuid1 = Uuid::parse_str("00000000-0000-0000-0000-000000000001").unwrap();
921 let uuid2 = Uuid::parse_str("00000000-0000-0000-0000-000000000002").unwrap();
922
923 let encoded1 = encoder
924 .encode_value(&Value::Uuid(*uuid1.as_bytes()))
925 .unwrap();
926 let encoded2 = encoder
927 .encode_value(&Value::Uuid(*uuid2.as_bytes()))
928 .unwrap();
929
930 assert!(encoded1 < encoded2);
931 }
932
933 #[test]
934 fn test_composite_key_encoding() {
935 let mut encoder = ByteComparableEncoder::new();
936
937 let key1 = vec![Value::text("partition1".to_string()), Value::Integer(1)];
938 let key2 = vec![Value::text("partition1".to_string()), Value::Integer(2)];
939 let key3 = vec![Value::text("partition2".to_string()), Value::Integer(1)];
940
941 let encoded1 = encoder.encode_composite_key(&key1).unwrap();
942 let encoded2 = encoder.encode_composite_key(&key2).unwrap();
943 let encoded3 = encoder.encode_composite_key(&key3).unwrap();
944
945 assert!(encoded1 < encoded2); assert!(encoded2 < encoded3); }
949
950 #[test]
951 fn test_list_encoding() {
952 let mut encoder = ByteComparableEncoder::new();
953
954 let list1 = Value::List(vec![Value::Integer(1), Value::Integer(2)]);
955 let list2 = Value::List(vec![
956 Value::Integer(1),
957 Value::Integer(2),
958 Value::Integer(3),
959 ]);
960
961 let encoded1 = encoder.encode_value(&list1).unwrap();
962 let encoded2 = encoder.encode_value(&list2).unwrap();
963
964 assert!(encoded1 < encoded2);
966 }
967
968 #[test]
969 fn test_float_special_values() {
970 let mut encoder = ByteComparableEncoder::new();
971
972 let neg_inf = encoder
973 .encode_value(&Value::Float(f64::NEG_INFINITY))
974 .unwrap();
975 let neg_one = encoder.encode_value(&Value::Float(-1.0)).unwrap();
976 let zero = encoder.encode_value(&Value::Float(0.0)).unwrap();
977 let one = encoder.encode_value(&Value::Float(1.0)).unwrap();
978 let pos_inf = encoder.encode_value(&Value::Float(f64::INFINITY)).unwrap();
979
980 assert!(neg_inf < neg_one);
982 assert!(neg_one < zero);
983 assert!(zero < one);
984 assert!(one < pos_inf);
985 }
986
987 #[test]
988 fn test_decode_key_debug() {
989 let text_bytes = b"hello\0";
990 let decoded = ByteComparableDecoder::decode_key_debug(text_bytes);
991 assert!(decoded.contains("hello"));
992
993 let binary_bytes = &[0xFF, 0xFE, 0xFD];
994 let decoded = ByteComparableDecoder::decode_key_debug(binary_bytes);
995 assert!(decoded.starts_with("0x"));
996 }
997
998 #[test]
999 fn test_encoder_reuse() {
1000 let mut encoder = ByteComparableEncoder::new();
1001
1002 let encoded1 = encoder
1003 .encode_value(&Value::text("test1".to_string()))
1004 .unwrap();
1005 let encoded2 = encoder
1006 .encode_value(&Value::text("test2".to_string()))
1007 .unwrap();
1008
1009 assert_ne!(encoded1, encoded2);
1011 assert!(encoded1 < encoded2);
1012 }
1013
1014 #[test]
1015 fn test_encoder_config() {
1016 let config = EncoderConfig {
1017 use_varint_encoding: false,
1018 max_nesting_depth: 16,
1019 enable_prefix_compression: false,
1020 strict_compliance: false,
1021 };
1022
1023 let encoder = ByteComparableEncoder::with_config(config);
1024 assert!(!encoder.config().use_varint_encoding);
1025 assert_eq!(encoder.config().max_nesting_depth, 16);
1026 }
1027
1028 #[test]
1029 fn test_max_nesting_depth() {
1030 let config = EncoderConfig {
1031 max_nesting_depth: 2,
1032 ..Default::default()
1033 };
1034
1035 let mut encoder = ByteComparableEncoder::with_config(config);
1036
1037 let deep_nested = Value::List(vec![Value::List(vec![Value::List(vec![Value::Integer(
1039 1,
1040 )])])]);
1041
1042 let result = encoder.encode_value(&deep_nested);
1044 assert!(result.is_err());
1045 }
1046
1047 #[test]
1048 fn test_batch_encoder() {
1049 let mut batch_encoder = BatchEncoder::new();
1050
1051 let values = vec![
1052 Value::Integer(1),
1053 Value::text("hello".to_string()),
1054 Value::Boolean(true),
1055 ];
1056
1057 let encoded_batch = batch_encoder.encode_batch(&values).unwrap();
1058 assert_eq!(encoded_batch.len(), 3);
1059
1060 let mut single_encoder = ByteComparableEncoder::new();
1062 for (i, value) in values.iter().enumerate() {
1063 let single_encoded = single_encoder.encode_value(value).unwrap();
1064 assert_eq!(encoded_batch[i], single_encoded);
1065 }
1066 }
1067
1068 #[test]
1069 fn test_ordering_across_types() {
1070 let mut encoder = ByteComparableEncoder::new();
1071
1072 let null_val = encoder.encode_value(&Value::Null).unwrap();
1074 let bool_val = encoder.encode_value(&Value::Boolean(false)).unwrap();
1075 let int_val = encoder.encode_value(&Value::Integer(0)).unwrap();
1076 let text_val = encoder.encode_value(&Value::text("".to_string())).unwrap();
1077
1078 assert!(null_val < bool_val);
1080 assert!(bool_val < int_val);
1081 assert!(int_val < text_val);
1082 }
1083
1084 #[test]
1085 fn test_validation() {
1086 let encoder = ByteComparableEncoder::new();
1087
1088 assert!(encoder.validate_encoded_key(&[type_prefixes::NULL]).is_ok());
1090 assert!(encoder
1091 .validate_encoded_key(&[type_prefixes::BOOLEAN_TRUE])
1092 .is_ok());
1093
1094 assert!(encoder.validate_encoded_key(&[]).is_err()); assert!(encoder
1097 .validate_encoded_key(&[type_prefixes::NULL, 0x00, 0x00, 0x00])
1098 .is_err()); }
1100
1101 #[test]
1102 fn test_performance_stats() {
1103 let mut encoder = ByteComparableEncoder::new();
1104 encoder.reserve(1024);
1105
1106 let stats = encoder.get_stats();
1107 assert!(stats.buffer_capacity >= 1024);
1108 assert_eq!(stats.buffer_size, 0);
1109
1110 encoder
1112 .encode_value(&Value::text("test".to_string()))
1113 .unwrap();
1114 let stats_after = encoder.get_stats();
1115 assert!(stats_after.buffer_size > 0);
1116 }
1117
1118 #[test]
1119 fn test_timestamp_encoding() {
1120 let mut encoder = ByteComparableEncoder::new();
1121
1122 let past = encoder.encode_value(&Value::Timestamp(-1000)).unwrap();
1123 let epoch = encoder.encode_value(&Value::Timestamp(0)).unwrap();
1124 let future = encoder.encode_value(&Value::Timestamp(1000)).unwrap();
1125
1126 assert_eq!(past[0], type_prefixes::TIMESTAMP);
1128 assert_eq!(epoch[0], type_prefixes::TIMESTAMP);
1129 assert_eq!(future[0], type_prefixes::TIMESTAMP);
1130
1131 assert!(past < epoch);
1133 assert!(epoch < future);
1134 }
1135
1136 #[test]
1137 fn test_blob_encoding() {
1138 let mut encoder = ByteComparableEncoder::new();
1139
1140 let blob1 = encoder
1141 .encode_value(&Value::blob(vec![0x01, 0x02]))
1142 .unwrap();
1143 let blob2 = encoder
1144 .encode_value(&Value::blob(vec![0x01, 0x03]))
1145 .unwrap();
1146 let blob_with_null = encoder
1147 .encode_value(&Value::blob(vec![0x01, 0x00, 0x02]))
1148 .unwrap();
1149
1150 assert_eq!(blob1[0], type_prefixes::BLOB);
1152 assert_eq!(blob2[0], type_prefixes::BLOB);
1153
1154 assert!(blob1 < blob2);
1156
1157 assert!(blob_with_null
1159 .windows(2)
1160 .any(|w| w == escape_sequences::ESCAPED_NULL));
1161 }
1162
1163 #[test]
1164 fn test_comprehensive_ordering() {
1165 let mut encoder = ByteComparableEncoder::new();
1166
1167 let values = vec![
1169 Value::Null,
1170 Value::Boolean(false),
1171 Value::Boolean(true),
1172 Value::TinyInt(-1),
1173 Value::TinyInt(0),
1174 Value::TinyInt(1),
1175 Value::SmallInt(-100),
1176 Value::SmallInt(100),
1177 Value::Integer(-1000),
1178 Value::Integer(1000),
1179 Value::BigInt(-10000),
1180 Value::BigInt(10000),
1181 Value::Float32(-1.0),
1182 Value::Float32(1.0),
1183 Value::Float(-1.0),
1184 Value::Float(1.0),
1185 Value::text("a".to_string()),
1186 Value::text("z".to_string()),
1187 Value::blob(vec![0x01]),
1188 Value::blob(vec![0xFF]),
1189 Value::Uuid([0u8; 16]),
1190 Value::Uuid([0xFFu8; 16]),
1191 Value::Timestamp(-1000),
1192 Value::Timestamp(1000),
1193 ];
1194
1195 let encoded_values: Vec<_> = values
1196 .iter()
1197 .map(|v| encoder.encode_value(v).unwrap())
1198 .collect();
1199
1200 for i in 0..encoded_values.len() - 1 {
1202 assert!(
1203 encoded_values[i] <= encoded_values[i + 1],
1204 "Ordering violation at index {} and {}",
1205 i,
1206 i + 1
1207 );
1208 }
1209 }
1210}