1use noxu_db::DatabaseEntry;
5use noxu_util::packed::{write_sorted_i32, write_sorted_i64};
6
7#[derive(Debug, Clone)]
16pub struct TupleOutput {
17 buf: Vec<u8>,
18}
19
20impl TupleOutput {
21 pub fn new() -> Self {
23 Self { buf: Vec::with_capacity(32) }
24 }
25
26 pub fn with_capacity(capacity: usize) -> Self {
28 Self { buf: Vec::with_capacity(capacity) }
29 }
30
31 pub fn to_vec(&self) -> Vec<u8> {
33 self.buf.clone()
34 }
35
36 pub fn into_vec(self) -> Vec<u8> {
38 self.buf
39 }
40
41 pub fn len(&self) -> usize {
43 self.buf.len()
44 }
45
46 pub fn is_empty(&self) -> bool {
48 self.buf.is_empty()
49 }
50
51 pub fn to_database_entry(&self) -> DatabaseEntry {
53 DatabaseEntry::from_vec(self.buf.clone())
54 }
55
56 pub fn as_bytes(&self) -> &[u8] {
58 &self.buf
59 }
60
61 pub fn write_bool(&mut self, val: bool) {
65 self.buf.push(if val { 1 } else { 0 });
66 }
67
68 pub fn write_u8(&mut self, val: u8) {
72 self.buf.push(val);
73 }
74
75 pub fn write_i8(&mut self, val: i8) {
79 self.buf.push((val as u8) ^ 0x80);
80 }
81
82 pub fn write_u16(&mut self, val: u16) {
86 self.buf.push((val >> 8) as u8);
87 self.buf.push(val as u8);
88 }
89
90 pub fn write_i16(&mut self, val: i16) {
94 let encoded = (val as u16) ^ 0x8000;
95 self.buf.push((encoded >> 8) as u8);
96 self.buf.push(encoded as u8);
97 }
98
99 pub fn write_u32(&mut self, val: u32) {
103 self.buf.push((val >> 24) as u8);
104 self.buf.push((val >> 16) as u8);
105 self.buf.push((val >> 8) as u8);
106 self.buf.push(val as u8);
107 }
108
109 pub fn write_i32(&mut self, val: i32) {
113 let encoded = (val as u32) ^ 0x80000000;
114 self.buf.push((encoded >> 24) as u8);
115 self.buf.push((encoded >> 16) as u8);
116 self.buf.push((encoded >> 8) as u8);
117 self.buf.push(encoded as u8);
118 }
119
120 pub fn write_u64(&mut self, val: u64) {
124 self.buf.push((val >> 56) as u8);
125 self.buf.push((val >> 48) as u8);
126 self.buf.push((val >> 40) as u8);
127 self.buf.push((val >> 32) as u8);
128 self.buf.push((val >> 24) as u8);
129 self.buf.push((val >> 16) as u8);
130 self.buf.push((val >> 8) as u8);
131 self.buf.push(val as u8);
132 }
133
134 pub fn write_i64(&mut self, val: i64) {
138 let encoded = (val as u64) ^ 0x8000000000000000;
139 self.buf.push((encoded >> 56) as u8);
140 self.buf.push((encoded >> 48) as u8);
141 self.buf.push((encoded >> 40) as u8);
142 self.buf.push((encoded >> 32) as u8);
143 self.buf.push((encoded >> 24) as u8);
144 self.buf.push((encoded >> 16) as u8);
145 self.buf.push((encoded >> 8) as u8);
146 self.buf.push(encoded as u8);
147 }
148
149 pub fn write_float(&mut self, val: f32) {
156 let bits = val.to_bits();
157 self.write_u32(bits);
158 }
159
160 pub fn write_double(&mut self, val: f64) {
167 let bits = val.to_bits();
168 self.write_u64(bits);
169 }
170
171 pub fn write_sorted_float(&mut self, val: f32) {
180 let bits = val.to_bits() as i32;
181 let encoded = if bits < 0 {
182 (bits as u32) ^ 0xFFFFFFFF
183 } else {
184 (bits as u32) ^ 0x80000000
185 };
186 self.write_u32(encoded);
187 }
188
189 pub fn write_sorted_double(&mut self, val: f64) {
198 let bits = val.to_bits() as i64;
199 let encoded = if bits < 0 {
200 (bits as u64) ^ 0xFFFFFFFFFFFFFFFF
201 } else {
202 (bits as u64) ^ 0x8000000000000000
203 };
204 self.write_u64(encoded);
205 }
206
207 pub fn write_packed_int(&mut self, value: i32) {
219 if (-119..=119).contains(&value) {
220 self.buf.push(value as u8);
221 return;
222 }
223
224 let negative = value < -119;
225 let adjusted: u32 = if negative {
227 (-(value as i64) - 119) as u32
228 } else {
229 (value - 119) as u32
230 };
231
232 let byte_len: u32 = if adjusted & 0xFFFFFF00 == 0 {
234 1
235 } else if adjusted & 0xFFFF0000 == 0 {
236 2
237 } else if adjusted & 0xFF000000 == 0 {
238 3
239 } else {
240 4
241 };
242
243 let header: u8 = if negative {
245 (-(119i16 + byte_len as i16)) as u8
246 } else {
247 (119 + byte_len) as u8
248 };
249 self.buf.push(header);
250
251 self.buf.push(adjusted as u8);
253 if byte_len > 1 {
254 self.buf.push((adjusted >> 8) as u8);
255 if byte_len > 2 {
256 self.buf.push((adjusted >> 16) as u8);
257 if byte_len > 3 {
258 self.buf.push((adjusted >> 24) as u8);
259 }
260 }
261 }
262 }
263
264 pub fn write_packed_long(&mut self, value: i64) {
276 if (-119..=119).contains(&value) {
277 self.buf.push(value as u8);
278 return;
279 }
280
281 let negative = value < -119;
282 let adjusted: u64 = if negative {
284 (-(value as i128) - 119) as u64
285 } else {
286 (value - 119) as u64
287 };
288
289 let byte_len = if adjusted & 0xFFFFFFFFFFFFFF00 == 0 {
291 1
292 } else if adjusted & 0xFFFFFFFFFFFF0000 == 0 {
293 2
294 } else if adjusted & 0xFFFFFFFFFF000000 == 0 {
295 3
296 } else if adjusted & 0xFFFFFFFF00000000 == 0 {
297 4
298 } else if adjusted & 0xFFFFFF0000000000 == 0 {
299 5
300 } else if adjusted & 0xFFFF000000000000 == 0 {
301 6
302 } else if adjusted & 0xFF00000000000000 == 0 {
303 7
304 } else {
305 8
306 };
307
308 let header: u8 = if negative {
310 (-(119i16 + byte_len as i16)) as u8
311 } else {
312 (119 + byte_len) as u8
313 };
314 self.buf.push(header);
315
316 self.buf.push(adjusted as u8);
318 if byte_len > 1 {
319 self.buf.push((adjusted >> 8) as u8);
320 if byte_len > 2 {
321 self.buf.push((adjusted >> 16) as u8);
322 if byte_len > 3 {
323 self.buf.push((adjusted >> 24) as u8);
324 if byte_len > 4 {
325 self.buf.push((adjusted >> 32) as u8);
326 if byte_len > 5 {
327 self.buf.push((adjusted >> 40) as u8);
328 if byte_len > 6 {
329 self.buf.push((adjusted >> 48) as u8);
330 if byte_len > 7 {
331 self.buf.push((adjusted >> 56) as u8);
332 }
333 }
334 }
335 }
336 }
337 }
338 }
339 }
340
341 pub fn write_string(&mut self, val: &str) {
350 for &b in val.as_bytes() {
351 if b == 0x00 {
352 self.buf.push(0x00);
353 self.buf.push(0x01);
354 } else {
355 self.buf.push(b);
356 }
357 }
358 self.buf.push(0x00);
360 self.buf.push(0x00);
361 }
362
363 pub fn write_bytes(&mut self, data: &[u8]) {
369 self.buf.extend_from_slice(data);
370 }
371
372 pub fn write_sorted_packed_int(&mut self, val: i32) {
386 write_sorted_i32(&mut self.buf, val)
387 .expect("write_sorted_i32 to Vec is infallible");
388 }
389
390 pub fn write_sorted_packed_long(&mut self, val: i64) {
404 write_sorted_i64(&mut self.buf, val)
405 .expect("write_sorted_i64 to Vec is infallible");
406 }
407
408 pub fn write_char(&mut self, val: u16) {
417 self.buf.push((val >> 8) as u8);
418 self.buf.push(val as u8);
419 }
420
421 pub fn reset(&mut self) {
423 self.buf.clear();
424 }
425}
426
427impl Default for TupleOutput {
428 fn default() -> Self {
429 Self::new()
430 }
431}
432
433#[cfg(test)]
434mod tests {
435 use super::*;
436
437 #[test]
438 fn test_new() {
439 let out = TupleOutput::new();
440 assert!(out.is_empty());
441 assert_eq!(out.len(), 0);
442 }
443
444 #[test]
445 fn test_write_bool() {
446 let mut out = TupleOutput::new();
447 out.write_bool(true);
448 out.write_bool(false);
449 assert_eq!(out.to_vec(), vec![1, 0]);
450 }
451
452 #[test]
453 fn test_write_i32_sort_order() {
454 let values = [i32::MIN, -1000, -1, 0, 1, 1000, i32::MAX];
456 let encoded: Vec<Vec<u8>> = values
457 .iter()
458 .map(|&v| {
459 let mut out = TupleOutput::new();
460 out.write_i32(v);
461 out.to_vec()
462 })
463 .collect();
464
465 for i in 0..encoded.len() - 1 {
466 assert!(
467 encoded[i] < encoded[i + 1],
468 "sort order violated: {} (encoded {:?}) should be < {} (encoded {:?})",
469 values[i],
470 encoded[i],
471 values[i + 1],
472 encoded[i + 1]
473 );
474 }
475 }
476
477 #[test]
478 fn test_write_i64_sort_order() {
479 let values = [i64::MIN, -1000, -1, 0, 1, 1000, i64::MAX];
480 let encoded: Vec<Vec<u8>> = values
481 .iter()
482 .map(|&v| {
483 let mut out = TupleOutput::new();
484 out.write_i64(v);
485 out.to_vec()
486 })
487 .collect();
488
489 for i in 0..encoded.len() - 1 {
490 assert!(
491 encoded[i] < encoded[i + 1],
492 "sort order violated: {} should be < {}",
493 values[i],
494 values[i + 1]
495 );
496 }
497 }
498
499 #[test]
500 fn test_write_sorted_float_sort_order() {
501 let values = [f32::MIN, -1.0, -0.5, 0.0, 0.5, 1.0, f32::MAX];
502 let encoded: Vec<Vec<u8>> = values
503 .iter()
504 .map(|&v| {
505 let mut out = TupleOutput::new();
506 out.write_sorted_float(v);
507 out.to_vec()
508 })
509 .collect();
510
511 for i in 0..encoded.len() - 1 {
512 assert!(
513 encoded[i] < encoded[i + 1],
514 "sort order violated: {} (encoded {:?}) should be < {} (encoded {:?})",
515 values[i],
516 encoded[i],
517 values[i + 1],
518 encoded[i + 1]
519 );
520 }
521 }
522
523 #[test]
524 fn test_write_sorted_double_sort_order() {
525 let values = [f64::MIN, -1.0, -0.5, 0.0, 0.5, 1.0, f64::MAX];
526 let encoded: Vec<Vec<u8>> = values
527 .iter()
528 .map(|&v| {
529 let mut out = TupleOutput::new();
530 out.write_sorted_double(v);
531 out.to_vec()
532 })
533 .collect();
534
535 for i in 0..encoded.len() - 1 {
536 assert!(
537 encoded[i] < encoded[i + 1],
538 "sort order violated: {} should be < {}",
539 values[i],
540 values[i + 1]
541 );
542 }
543 }
544
545 #[test]
546 fn test_to_database_entry() {
547 let mut out = TupleOutput::new();
548 out.write_i32(42);
549 let entry = out.to_database_entry();
550 assert_eq!(entry.data().len(), 4);
551 }
552
553 #[test]
554 fn test_reset() {
555 let mut out = TupleOutput::new();
556 out.write_i32(42);
557 assert_eq!(out.len(), 4);
558 out.reset();
559 assert!(out.is_empty());
560 }
561
562 #[test]
563 fn test_packed_int_single_byte() {
564 for v in -119..=119i32 {
566 let mut out = TupleOutput::new();
567 out.write_packed_int(v);
568 assert_eq!(out.len(), 1, "value {} should be 1 byte", v);
569 }
570 }
571
572 #[test]
573 fn test_packed_int_multi_byte() {
574 let mut out = TupleOutput::new();
575 out.write_packed_int(120);
576 assert!(out.len() > 1);
577
578 let mut out = TupleOutput::new();
579 out.write_packed_int(-120);
580 assert!(out.len() > 1);
581 }
582
583 #[test]
589 fn test_format_bool_size() {
590 let mut out = TupleOutput::new();
591 out.write_bool(true);
592 assert_eq!(out.len(), 1);
593 out.write_bool(false);
594 assert_eq!(out.len(), 2);
595 }
596
597 #[test]
599 fn test_format_byte_sizes() {
600 let mut out = TupleOutput::new();
601 out.write_u8(123);
602 assert_eq!(out.len(), 1);
603 let mut out = TupleOutput::new();
604 out.write_i8(-1);
605 assert_eq!(out.len(), 1);
606 }
607
608 #[test]
610 fn test_format_short_sizes() {
611 let mut out = TupleOutput::new();
612 out.write_u16(0xFFFF);
613 assert_eq!(out.len(), 2);
614 let mut out = TupleOutput::new();
615 out.write_i16(-1);
616 assert_eq!(out.len(), 2);
617 }
618
619 #[test]
621 fn test_format_int_sizes() {
622 let mut out = TupleOutput::new();
623 out.write_u32(0xFFFF_FFFF);
624 assert_eq!(out.len(), 4);
625 let mut out = TupleOutput::new();
626 out.write_i32(123);
627 assert_eq!(out.len(), 4);
628 }
629
630 #[test]
632 fn test_format_long_sizes() {
633 let mut out = TupleOutput::new();
634 out.write_u64(123);
635 assert_eq!(out.len(), 8);
636 let mut out = TupleOutput::new();
637 out.write_i64(123);
638 assert_eq!(out.len(), 8);
639 }
640
641 #[test]
643 fn test_format_float_sizes() {
644 let mut out = TupleOutput::new();
645 out.write_float(123.123);
646 assert_eq!(out.len(), 4);
647 let mut out = TupleOutput::new();
648 out.write_sorted_float(123.123);
649 assert_eq!(out.len(), 4);
650 }
651
652 #[test]
654 fn test_format_double_sizes() {
655 let mut out = TupleOutput::new();
656 out.write_double(123.123);
657 assert_eq!(out.len(), 8);
658 let mut out = TupleOutput::new();
659 out.write_sorted_double(123.123);
660 assert_eq!(out.len(), 8);
661 }
662
663 #[test]
665 fn test_format_char_size() {
666 let mut out = TupleOutput::new();
667 out.write_char(b'a' as u16);
668 assert_eq!(out.len(), 2);
669 }
670
671 #[test]
673 fn test_format_string_size() {
674 let mut out = TupleOutput::new();
675 out.write_string("abc");
676 assert_eq!(out.len(), 5); }
686
687 #[test]
689 fn test_format_empty_string_size() {
690 let mut out = TupleOutput::new();
691 out.write_string("");
692 assert_eq!(out.len(), 2); }
694
695 #[test]
697 fn test_format_multi_string_size() {
698 let mut out = TupleOutput::new();
699 out.write_string("abc"); out.write_string("defg"); assert_eq!(out.len(), 11);
702 }
703
704 #[test]
706 fn test_format_multi_bool_size() {
707 let mut out = TupleOutput::new();
708 out.write_bool(true);
709 out.write_bool(false);
710 out.write_bool(true);
711 assert_eq!(out.len(), 3);
712 }
713
714 #[test]
716 fn test_format_multi_int_size() {
717 let mut out = TupleOutput::new();
718 out.write_i32(0);
719 out.write_i32(1);
720 out.write_i32(-1);
721 assert_eq!(out.len(), 12);
722 }
723
724 #[test]
726 fn test_format_multi_long_size() {
727 let mut out = TupleOutput::new();
728 out.write_i64(0);
729 out.write_i64(1);
730 out.write_i64(-1);
731 assert_eq!(out.len(), 24);
732 }
733
734 #[test]
736 fn test_format_multi_float_size() {
737 let mut out = TupleOutput::new();
738 out.write_float(0.0);
739 out.write_float(1.0);
740 out.write_float(-1.0);
741 assert_eq!(out.len(), 12);
742 }
743
744 #[test]
746 fn test_format_multi_double_size() {
747 let mut out = TupleOutput::new();
748 out.write_double(0.0);
749 out.write_double(1.0);
750 out.write_double(-1.0);
751 assert_eq!(out.len(), 24);
752 }
753
754 fn encode_i8(v: i8) -> Vec<u8> {
760 let mut out = TupleOutput::new();
761 out.write_i8(v);
762 out.to_vec()
763 }
764 fn encode_i16(v: i16) -> Vec<u8> {
765 let mut out = TupleOutput::new();
766 out.write_i16(v);
767 out.to_vec()
768 }
769 fn encode_i32(v: i32) -> Vec<u8> {
770 let mut out = TupleOutput::new();
771 out.write_i32(v);
772 out.to_vec()
773 }
774 fn encode_i64(v: i64) -> Vec<u8> {
775 let mut out = TupleOutput::new();
776 out.write_i64(v);
777 out.to_vec()
778 }
779 fn encode_u8(v: u8) -> Vec<u8> {
780 let mut out = TupleOutput::new();
781 out.write_u8(v);
782 out.to_vec()
783 }
784 fn encode_u16(v: u16) -> Vec<u8> {
785 let mut out = TupleOutput::new();
786 out.write_u16(v);
787 out.to_vec()
788 }
789 fn encode_u32(v: u32) -> Vec<u8> {
790 let mut out = TupleOutput::new();
791 out.write_u32(v);
792 out.to_vec()
793 }
794 fn encode_f32_sorted(v: f32) -> Vec<u8> {
795 let mut out = TupleOutput::new();
796 out.write_sorted_float(v);
797 out.to_vec()
798 }
799 fn encode_f64_sorted(v: f64) -> Vec<u8> {
800 let mut out = TupleOutput::new();
801 out.write_sorted_double(v);
802 out.to_vec()
803 }
804 fn encode_f32(v: f32) -> Vec<u8> {
805 let mut out = TupleOutput::new();
806 out.write_float(v);
807 out.to_vec()
808 }
809 fn encode_f64(v: f64) -> Vec<u8> {
810 let mut out = TupleOutput::new();
811 out.write_double(v);
812 out.to_vec()
813 }
814
815 #[test]
817 fn test_ordering_i8_full_boundary() {
818 let data: &[i8] =
819 &[i8::MIN, i8::MIN + 1, -1, 0, 1, i8::MAX - 1, i8::MAX];
820 for i in 0..data.len() - 1 {
821 assert!(
822 encode_i8(data[i]) < encode_i8(data[i + 1]),
823 "i8 ordering violated: {} should be < {}",
824 data[i],
825 data[i + 1]
826 );
827 }
828 }
829
830 #[test]
832 fn test_ordering_i16_full_boundary() {
833 let data: &[i16] = &[
834 i16::MIN,
835 i16::MIN + 1,
836 i8::MIN as i16,
837 i8::MIN as i16 + 1,
838 -1,
839 0,
840 1,
841 i8::MAX as i16 - 1,
842 i8::MAX as i16,
843 i16::MAX - 1,
844 i16::MAX,
845 ];
846 for i in 0..data.len() - 1 {
847 assert!(
848 encode_i16(data[i]) < encode_i16(data[i + 1]),
849 "i16 ordering violated: {} should be < {}",
850 data[i],
851 data[i + 1]
852 );
853 }
854 }
855
856 #[test]
858 fn test_ordering_i32_full_boundary() {
859 let data: &[i32] = &[
860 i32::MIN,
861 i32::MIN + 1,
862 i16::MIN as i32,
863 i16::MIN as i32 + 1,
864 i8::MIN as i32,
865 i8::MIN as i32 + 1,
866 -1,
867 0,
868 1,
869 i8::MAX as i32 - 1,
870 i8::MAX as i32,
871 i16::MAX as i32 - 1,
872 i16::MAX as i32,
873 i32::MAX - 1,
874 i32::MAX,
875 ];
876 for i in 0..data.len() - 1 {
877 assert!(
878 encode_i32(data[i]) < encode_i32(data[i + 1]),
879 "i32 ordering violated: {} should be < {}",
880 data[i],
881 data[i + 1]
882 );
883 }
884 }
885
886 #[test]
888 fn test_ordering_i64_full_boundary() {
889 let data: &[i64] = &[
890 i64::MIN,
891 i64::MIN + 1,
892 i32::MIN as i64,
893 i32::MIN as i64 + 1,
894 i16::MIN as i64,
895 i16::MIN as i64 + 1,
896 i8::MIN as i64,
897 i8::MIN as i64 + 1,
898 -1,
899 0,
900 1,
901 i8::MAX as i64 - 1,
902 i8::MAX as i64,
903 i16::MAX as i64 - 1,
904 i16::MAX as i64,
905 i32::MAX as i64 - 1,
906 i32::MAX as i64,
907 i64::MAX - 1,
908 i64::MAX,
909 ];
910 for i in 0..data.len() - 1 {
911 assert!(
912 encode_i64(data[i]) < encode_i64(data[i + 1]),
913 "i64 ordering violated: {} should be < {}",
914 data[i],
915 data[i + 1]
916 );
917 }
918 }
919
920 #[test]
922 fn test_ordering_u8_full() {
923 let data: &[u8] = &[0, 1, 0x7F, 0xFF];
924 for i in 0..data.len() - 1 {
925 assert!(
926 encode_u8(data[i]) < encode_u8(data[i + 1]),
927 "u8 ordering violated: {} should be < {}",
928 data[i],
929 data[i + 1]
930 );
931 }
932 }
933
934 #[test]
936 fn test_ordering_u16_full() {
937 let data: &[u16] = &[0, 1, 0xFE, 0xFF, 0x800, 0x7FFF, 0xFFFF];
938 for i in 0..data.len() - 1 {
939 assert!(
940 encode_u16(data[i]) < encode_u16(data[i + 1]),
941 "u16 ordering violated: {} should be < {}",
942 data[i],
943 data[i + 1]
944 );
945 }
946 }
947
948 #[test]
950 fn test_ordering_u32_full() {
951 let data: &[u32] = &[
952 0, 1, 0xFE, 0xFF, 0x800, 0x7FFF, 0xFFFF, 0x80000, 0x7FFFFFFF,
953 0x80000000, 0xFFFFFFFF,
954 ];
955 for i in 0..data.len() - 1 {
956 assert!(
957 encode_u32(data[i]) < encode_u32(data[i + 1]),
958 "u32 ordering violated: {} should be < {}",
959 data[i],
960 data[i + 1]
961 );
962 }
963 }
964
965 #[test]
967 fn test_ordering_bool() {
968 let mut false_out = TupleOutput::new();
969 false_out.write_bool(false);
970 let mut true_out = TupleOutput::new();
971 true_out.write_bool(true);
972 assert!(false_out.to_vec() < true_out.to_vec());
973 }
974
975 #[test]
978 fn test_ordering_float_positive_only() {
979 let data: &[f32] = &[
980 0.0,
981 f32::MIN_POSITIVE,
982 2.0 * f32::MIN_POSITIVE,
983 0.01,
984 0.02,
985 0.99,
986 1.0,
987 1.01,
988 1.02,
989 1.99,
990 f32::MAX,
991 f32::INFINITY,
992 ];
993 for i in 0..data.len() - 1 {
994 assert!(
995 encode_f32(data[i]) < encode_f32(data[i + 1]),
996 "positive float ordering violated: {} should be < {}",
997 data[i],
998 data[i + 1]
999 );
1000 }
1001 }
1002
1003 #[test]
1005 fn test_ordering_double_positive_only() {
1006 let data: &[f64] = &[
1007 0.0,
1008 f64::MIN_POSITIVE,
1009 2.0 * f64::MIN_POSITIVE,
1010 0.001,
1011 0.002,
1012 0.999,
1013 1.0,
1014 1.001,
1015 1.002,
1016 1.999,
1017 f64::MAX,
1018 f64::INFINITY,
1019 ];
1020 for i in 0..data.len() - 1 {
1021 assert!(
1022 encode_f64(data[i]) < encode_f64(data[i + 1]),
1023 "positive double ordering violated: {} should be < {}",
1024 data[i],
1025 data[i + 1]
1026 );
1027 }
1028 }
1029
1030 #[test]
1032 fn test_ordering_sorted_float_full() {
1033 let data: &[f32] = &[
1034 f32::NEG_INFINITY,
1035 -f32::MAX,
1036 -1.99,
1037 -1.02,
1038 -1.01,
1039 -1.0,
1040 -0.99,
1041 -0.02,
1042 -0.01,
1043 -2.0 * f32::MIN_POSITIVE,
1044 -f32::MIN_POSITIVE,
1045 0.0,
1046 f32::MIN_POSITIVE,
1047 2.0 * f32::MIN_POSITIVE,
1048 0.01,
1049 0.02,
1050 0.99,
1051 1.0,
1052 1.01,
1053 1.02,
1054 1.99,
1055 f32::MAX,
1056 f32::INFINITY,
1057 f32::NAN,
1058 ];
1059 for i in 0..data.len() - 1 {
1060 assert!(
1061 encode_f32_sorted(data[i]) < encode_f32_sorted(data[i + 1]),
1062 "sorted float ordering violated at index {}: {} should be < {}",
1063 i,
1064 data[i],
1065 data[i + 1]
1066 );
1067 }
1068 }
1069
1070 #[test]
1072 fn test_ordering_sorted_double_full() {
1073 let data: &[f64] = &[
1074 f64::NEG_INFINITY,
1075 -f64::MAX,
1076 -1.999,
1077 -1.002,
1078 -1.001,
1079 -1.0,
1080 -0.999,
1081 -0.002,
1082 -0.001,
1083 -2.0 * f64::MIN_POSITIVE,
1084 -f64::MIN_POSITIVE,
1085 0.0,
1086 f64::MIN_POSITIVE,
1087 2.0 * f64::MIN_POSITIVE,
1088 0.001,
1089 0.002,
1090 0.999,
1091 1.0,
1092 1.001,
1093 1.002,
1094 1.999,
1095 f64::MAX,
1096 f64::INFINITY,
1097 f64::NAN,
1098 ];
1099 for i in 0..data.len() - 1 {
1100 assert!(
1101 encode_f64_sorted(data[i]) < encode_f64_sorted(data[i + 1]),
1102 "sorted double ordering violated at index {}: {} should be < {}",
1103 i,
1104 data[i],
1105 data[i + 1]
1106 );
1107 }
1108 }
1109
1110 #[test]
1112 fn test_ordering_packed_int_0_to_630() {
1113 for i in 0u32..630 {
1114 let mut a = TupleOutput::new();
1115 a.write_packed_int(i as i32);
1116 let mut b = TupleOutput::new();
1117 b.write_packed_int(i as i32 + 1);
1118 assert!(
1119 a.to_vec() < b.to_vec(),
1120 "packed_int ordering violated: {} should be < {}",
1121 i,
1122 i + 1
1123 );
1124 }
1125 }
1126
1127 #[test]
1129 fn test_ordering_packed_long_0_to_630() {
1130 for i in 0u64..630 {
1131 let mut a = TupleOutput::new();
1132 a.write_packed_long(i as i64);
1133 let mut b = TupleOutput::new();
1134 b.write_packed_long(i as i64 + 1);
1135 assert!(
1136 a.to_vec() < b.to_vec(),
1137 "packed_long ordering violated: {} should be < {}",
1138 i,
1139 i + 1
1140 );
1141 }
1142 }
1143
1144 #[test]
1146 fn test_ordering_sorted_packed_int_full_boundary() {
1147 let data: &[i32] = &[
1148 i32::MIN,
1149 i32::MIN + 1,
1150 i16::MIN as i32,
1151 i16::MIN as i32 + 1,
1152 i8::MIN as i32,
1153 i8::MIN as i32 + 1,
1154 -1,
1155 0,
1156 1,
1157 i8::MAX as i32 - 1,
1158 i8::MAX as i32,
1159 i16::MAX as i32 - 1,
1160 i16::MAX as i32,
1161 i32::MAX - 1,
1162 i32::MAX,
1163 ];
1164 for i in 0..data.len() - 1 {
1165 let mut a = TupleOutput::new();
1166 a.write_sorted_packed_int(data[i]);
1167 let mut b = TupleOutput::new();
1168 b.write_sorted_packed_int(data[i + 1]);
1169 assert!(
1170 a.to_vec() < b.to_vec(),
1171 "sorted_packed_int ordering violated: {} should be < {}",
1172 data[i],
1173 data[i + 1]
1174 );
1175 }
1176 }
1177
1178 #[test]
1180 fn test_ordering_sorted_packed_long_full_boundary() {
1181 let data: &[i64] = &[
1182 i64::MIN,
1183 i64::MIN + 1,
1184 i32::MIN as i64,
1185 i32::MIN as i64 + 1,
1186 i16::MIN as i64,
1187 i16::MIN as i64 + 1,
1188 i8::MIN as i64,
1189 i8::MIN as i64 + 1,
1190 -1,
1191 0,
1192 1,
1193 i8::MAX as i64 - 1,
1194 i8::MAX as i64,
1195 i16::MAX as i64 - 1,
1196 i16::MAX as i64,
1197 i32::MAX as i64 - 1,
1198 i32::MAX as i64,
1199 i64::MAX - 1,
1200 i64::MAX,
1201 ];
1202 for i in 0..data.len() - 1 {
1203 let mut a = TupleOutput::new();
1204 a.write_sorted_packed_long(data[i]);
1205 let mut b = TupleOutput::new();
1206 b.write_sorted_packed_long(data[i + 1]);
1207 assert!(
1208 a.to_vec() < b.to_vec(),
1209 "sorted_packed_long ordering violated: {} should be < {}",
1210 data[i],
1211 data[i + 1]
1212 );
1213 }
1214 }
1215
1216 #[test]
1218 fn test_format_packed_int_sizes() {
1219 let mut out = TupleOutput::new();
1221 out.write_packed_int(119);
1222 assert_eq!(out.len(), 1, "119 should be 1 byte");
1223
1224 let mut out = TupleOutput::new();
1226 out.write_packed_int(0xFFFF + 119);
1227 assert_eq!(out.len(), 3, "0xFFFF+119 should be 3 bytes");
1228
1229 let mut out = TupleOutput::new();
1231 out.write_packed_int(i32::MAX);
1232 assert_eq!(out.len(), 5, "i32::MAX should be 5 bytes");
1233 }
1234
1235 #[test]
1237 fn test_format_packed_long_sizes() {
1238 let mut out = TupleOutput::new();
1240 out.write_packed_long(119);
1241 assert_eq!(out.len(), 1, "119 should be 1 byte");
1242
1243 let mut out = TupleOutput::new();
1245 out.write_packed_long(0xFFFF_FFFF_i64 + 119);
1246 assert_eq!(out.len(), 5, "0xFFFFFFFF+119 should be 5 bytes");
1247
1248 let mut out = TupleOutput::new();
1250 out.write_packed_long(i64::MAX);
1251 assert_eq!(out.len(), 9, "i64::MAX should be 9 bytes");
1252 }
1253
1254 #[test]
1256 fn test_format_sorted_packed_int_sizes() {
1257 for v in [-1i32, 0, 1, -119, 120] {
1259 let mut out = TupleOutput::new();
1260 out.write_sorted_packed_int(v);
1261 assert_eq!(out.len(), 1, "{} should be 1 byte", v);
1262 }
1263 for v in [121i32, -120] {
1265 let mut out = TupleOutput::new();
1266 out.write_sorted_packed_int(v);
1267 assert_eq!(out.len(), 2, "{} should be 2 bytes", v);
1268 }
1269 for v in [i32::MAX, i32::MIN] {
1271 let mut out = TupleOutput::new();
1272 out.write_sorted_packed_int(v);
1273 assert_eq!(out.len(), 5, "{} should be 5 bytes", v);
1274 }
1275 }
1276
1277 #[test]
1279 fn test_format_sorted_packed_long_sizes() {
1280 for v in [-1i64, 0, 1, -119, 120] {
1281 let mut out = TupleOutput::new();
1282 out.write_sorted_packed_long(v);
1283 assert_eq!(out.len(), 1, "{} should be 1 byte", v);
1284 }
1285 for v in [121i64, -120] {
1286 let mut out = TupleOutput::new();
1287 out.write_sorted_packed_long(v);
1288 assert_eq!(out.len(), 2, "{} should be 2 bytes", v);
1289 }
1290 for v in [i64::MAX, i64::MIN] {
1291 let mut out = TupleOutput::new();
1292 out.write_sorted_packed_long(v);
1293 assert_eq!(out.len(), 9, "{} should be 9 bytes", v);
1294 }
1295 }
1296
1297 #[test]
1300 fn test_ordering_string_multi_segment() {
1301 fn encode_strings(strs: &[&str]) -> Vec<u8> {
1303 let mut out = TupleOutput::new();
1304 for s in strs {
1305 out.write_string(s);
1306 }
1307 out.to_vec()
1308 }
1309 let a = encode_strings(&["a"]);
1310 let a_empty = encode_strings(&["a", ""]);
1311 let a_empty_a = encode_strings(&["a", "", "a"]);
1312 let a_b = encode_strings(&["a", "b"]);
1313 let aa = encode_strings(&["aa"]);
1314 let b = encode_strings(&["b"]);
1315
1316 assert!(a < a_empty, "\"a\" should sort before \"a\"+\"\"");
1317 assert!(
1318 a_empty < a_empty_a,
1319 "\"a\"+\"\" should sort before \"a\"+\"\"+\"a\""
1320 );
1321 assert!(
1322 a_empty_a < a_b,
1323 "\"a\"+\"\"+\"a\" should sort before \"a\"+\"b\""
1324 );
1325 assert!(a_b < aa, "\"a\"+\"b\" should sort before \"aa\"");
1326 assert!(aa < b, "\"aa\" should sort before \"b\"");
1327 }
1328}