1#![cfg_attr(not(feature = "std"), no_std)]
37#![warn(missing_docs)]
38
39#[cfg(feature = "std")]
40extern crate std;
41
42#[cfg(not(feature = "std"))]
43extern crate alloc;
44
45#[cfg(not(feature = "std"))]
46use alloc::{vec::Vec, string::String, collections::BTreeMap};
47
48#[cfg(feature = "std")]
49use std::{vec::Vec, string::String, collections::HashMap};
50
51pub use core::option::Option;
57
58pub use core::result::Result;
64
65#[cfg(feature = "std")]
75pub type DynamicArray<T> = Vec<T>;
76
77#[cfg(not(feature = "std"))]
78pub type DynamicArray<T> = Vec<T>;
79
80#[cfg(feature = "std")]
94pub type AssociativeArray<K, V> = HashMap<K, V>;
95
96#[cfg(not(feature = "std"))]
97pub type AssociativeArray<K, V> = BTreeMap<K, V>;
98
99pub type StringBuffer = String;
109
110pub const VERSION: &str = env!("CARGO_PKG_VERSION");
112
113pub trait DynamicArrayExt<T> {
115 fn reserve_exact_fast(&mut self, additional: usize);
117
118 fn extend_from_slice_fast(&mut self, slice: &[T]) where T: Clone;
120
121 fn clear_and_resize(&mut self, new_capacity: usize);
123}
124
125impl<T> DynamicArrayExt<T> for DynamicArray<T> {
126 #[inline]
127 fn reserve_exact_fast(&mut self, additional: usize) {
128 if self.capacity() - self.len() < additional {
129 self.reserve_exact(additional);
130 }
131 }
132
133 #[inline]
134 fn extend_from_slice_fast(&mut self, slice: &[T]) where T: Clone {
135 self.reserve_exact_fast(slice.len());
136 self.extend_from_slice(slice);
137 }
138
139 #[inline]
140 fn clear_and_resize(&mut self, new_capacity: usize) {
141 self.clear();
142 if self.capacity() < new_capacity {
143 self.reserve_exact(new_capacity - self.capacity());
144 } else if self.capacity() > new_capacity * 2 {
145 self.shrink_to(new_capacity);
146 }
147 }
148}
149
150pub mod sizes {
152 use core::mem::size_of;
153
154 pub const OPTION_OVERHEAD: usize = 1;
156
157 pub const PTR_SIZE: usize = size_of::<usize>();
159
160 pub const VEC_HEADER_SIZE: usize = 3 * PTR_SIZE;
162
163 pub const VEC_DEFAULT_CAPACITY: usize = 4;
165
166 pub const PAGE_SIZE: usize = 4096;
168
169 pub const HUGE_PAGE_SIZE: usize = 2 * 1024 * 1024;
171}
172
173pub mod arena {
178 use super::*;
179
180 pub struct Arena {
186 buffer: DynamicArray<u8>,
187 offset: usize,
188 }
189
190 impl Arena {
191 #[inline]
193 pub fn with_capacity(capacity: usize) -> Self {
194 Self {
195 buffer: DynamicArray::with_capacity(capacity),
196 offset: 0,
197 }
198 }
199
200 #[inline]
202 pub fn alloc(&mut self, size: usize, align: usize) -> Option<*mut u8> {
203 let current = self.buffer.as_ptr() as usize + self.offset;
204 let aligned = (current + align - 1) & !(align - 1);
205 let padding = aligned - current;
206 let total = padding + size;
207
208 if self.offset + total > self.buffer.capacity() {
209 let new_cap = (self.buffer.capacity() * 2).max(self.offset + total);
211 self.buffer.reserve(new_cap - self.buffer.capacity());
212 }
213
214 self.offset += total;
215 unsafe {
216 self.buffer.set_len(self.offset);
217 }
218 Some(aligned as *mut u8)
219 }
220
221 #[inline]
223 pub fn alloc_value<T>(&mut self, value: T) -> Option<&mut T> {
224 let ptr = self.alloc(core::mem::size_of::<T>(), core::mem::align_of::<T>())?;
225 unsafe {
226 let typed_ptr = ptr as *mut T;
227 core::ptr::write(typed_ptr, value);
228 Some(&mut *typed_ptr)
229 }
230 }
231
232 #[inline]
234 pub fn reset(&mut self) {
235 self.offset = 0;
236 unsafe {
237 self.buffer.set_len(0);
238 }
239 }
240
241 #[inline]
243 pub fn used(&self) -> usize {
244 self.offset
245 }
246
247 #[inline]
249 pub fn capacity(&self) -> usize {
250 self.buffer.capacity()
251 }
252 }
253}
254
255pub mod fixed {
257 pub const CACHE_LINE_SIZE: usize = 64;
259
260 #[repr(transparent)]
265 pub struct FixedArray<T, const N: usize>([T; N]);
266
267 #[repr(C, align(64))]
272 pub struct CacheAlignedArray<T, const N: usize> {
273 data: [T; N],
274 }
275
276 impl<T, const N: usize> CacheAlignedArray<T, N> {
277 #[inline(always)]
279 pub const fn new(data: [T; N]) -> Self {
280 Self { data }
281 }
282
283 #[inline(always)]
285 pub const fn as_slice(&self) -> &[T] {
286 &self.data
287 }
288
289 #[inline(always)]
291 pub fn as_mut_slice(&mut self) -> &mut [T] {
292 &mut self.data
293 }
294
295 #[inline(always)]
297 pub const fn as_ptr(&self) -> *const T {
298 self.data.as_ptr()
299 }
300
301 #[inline(always)]
303 pub fn as_mut_ptr(&mut self) -> *mut T {
304 self.data.as_mut_ptr()
305 }
306 }
307
308 impl<T, const N: usize> FixedArray<T, N> {
309 #[inline(always)]
311 pub const fn new(array: [T; N]) -> Self {
312 Self(array)
313 }
314
315 #[inline(always)]
317 pub const fn as_slice(&self) -> &[T] {
318 &self.0
319 }
320
321 #[inline(always)]
323 pub fn as_mut_slice(&mut self) -> &mut [T] {
324 &mut self.0
325 }
326
327 #[inline(always)]
329 pub const fn len(&self) -> usize {
330 N
331 }
332
333 #[inline(always)]
335 pub fn into_inner(self) -> [T; N] {
336 self.0
337 }
338 }
339
340 #[repr(C)]
345 pub union SmallString {
346 inline: core::mem::ManuallyDrop<InlineString>,
348 heap: core::mem::ManuallyDrop<HeapString>,
350 }
351
352 #[repr(C)]
353 #[derive(Copy, Clone)]
354 struct InlineString {
355 data: [u8; 23],
356 len: u8, }
358
359 #[repr(C)]
360 #[derive(Copy, Clone)]
361 struct HeapString {
362 ptr: *mut u8,
363 cap: usize,
364 len: usize, }
366}
367
368pub mod iter {
370 use super::*;
371
372 pub trait IntoIteratorWithHint: IntoIterator {
374 fn size_hint_before(&self) -> (usize, Option<usize>);
376 }
377
378 impl<T> IntoIteratorWithHint for DynamicArray<T> {
379 #[inline]
380 fn size_hint_before(&self) -> (usize, Option<usize>) {
381 let len = self.len();
382 (len, Some(len))
383 }
384 }
385}
386
387pub mod perf {
389 pub trait Prefetchable {
391 unsafe fn prefetch(&self);
395 }
396
397 #[inline(always)]
399 pub fn likely(b: bool) -> bool {
400 if !b {
401 unsafe { core::hint::unreachable_unchecked(); }
402 }
403 b
404 }
405
406 #[inline(always)]
408 pub fn unlikely(b: bool) -> bool {
409 if b {
410 unsafe { core::hint::unreachable_unchecked(); }
411 }
412 b
413 }
414
415 #[inline(always)]
417 pub fn assume_aligned<T>(ptr: *const T, align: usize) -> *const T {
418 debug_assert_eq!(ptr as usize % align, 0, "Pointer not aligned");
419 ptr
420 }
421}
422
423#[cfg(target_arch = "x86_64")]
425pub mod simd {
426 #[inline]
428 pub fn has_avx2() -> bool {
429 #[cfg(target_feature = "avx2")]
430 { true }
431 #[cfg(not(target_feature = "avx2"))]
432 { is_x86_feature_detected!("avx2") }
433 }
434
435 #[inline]
437 pub fn has_avx512f() -> bool {
438 #[cfg(target_feature = "avx512f")]
439 { true }
440 #[cfg(not(target_feature = "avx512f"))]
441 { is_x86_feature_detected!("avx512f") }
442 }
443
444 #[inline]
448 pub unsafe fn fast_copy(dst: *mut u8, src: *const u8, len: usize) {
449 if len < 256 {
450 core::ptr::copy_nonoverlapping(src, dst, len);
452 } else if has_avx512f() {
453 let chunks = len / 64;
455 for i in 0..chunks {
456 let offset = i * 64;
457 core::ptr::copy_nonoverlapping(
458 src.add(offset),
459 dst.add(offset),
460 64
461 );
462 }
463 let remainder = len % 64;
465 if remainder > 0 {
466 core::ptr::copy_nonoverlapping(
467 src.add(len - remainder),
468 dst.add(len - remainder),
469 remainder
470 );
471 }
472 } else {
473 core::ptr::copy_nonoverlapping(src, dst, len);
474 }
475 }
476}
477
478pub mod pool {
483 use super::*;
484
485 pub struct ObjectPool<T> {
487 objects: DynamicArray<Option<T>>,
488 free_list: DynamicArray<usize>,
489 }
490
491 impl<T> ObjectPool<T> {
492 #[inline]
494 pub fn with_capacity(capacity: usize) -> Self {
495 let mut objects = DynamicArray::with_capacity(capacity);
496 let mut free_list = DynamicArray::with_capacity(capacity);
497
498 for i in 0..capacity {
499 objects.push(None);
500 free_list.push(i);
501 }
502
503 Self { objects, free_list }
504 }
505
506 #[inline]
508 pub fn acquire<F>(&mut self, create: F) -> usize
509 where
510 F: FnOnce() -> T,
511 {
512 if let Some(index) = self.free_list.pop() {
513 self.objects[index] = Some(create());
514 index
515 } else {
516 let index = self.objects.len();
517 self.objects.push(Some(create()));
518 index
519 }
520 }
521
522 #[inline]
524 pub fn get(&self, index: usize) -> Option<&T> {
525 self.objects.get(index).and_then(|opt| opt.as_ref())
526 }
527
528 #[inline]
530 pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
531 self.objects.get_mut(index).and_then(|opt| opt.as_mut())
532 }
533
534 #[inline]
536 pub fn release(&mut self, index: usize) {
537 if index < self.objects.len() {
538 self.objects[index] = None;
539 self.free_list.push(index);
540 }
541 }
542
543 #[inline]
545 pub fn clear(&mut self) {
546 for i in 0..self.objects.len() {
547 if self.objects[i].is_some() {
548 self.objects[i] = None;
549 self.free_list.push(i);
550 }
551 }
552 }
553 }
554}
555
556#[macro_export]
570macro_rules! map {
571 ($($key:expr => $value:expr),* $(,)?) => {{
572 const COUNT: usize = {
574 let mut count = 0;
575 $( let _ = $key; count += 1; )*
576 count
577 };
578
579 let mut m = $crate::AssociativeArray::with_capacity(COUNT);
580 $(
581 m.insert($key, $value);
582 )*
583 m
584 }};
585}
586
587#[macro_export]
598macro_rules! list {
599 ($($item:expr),* $(,)?) => {{
600 vec![$($item),*]
601 }};
602}
603
604#[macro_export]
615macro_rules! array {
616 ($($item:expr),* $(,)?) => {{
617 $crate::fixed::FixedArray::new([$($item),*])
618 }};
619}
620
621#[macro_export]
631macro_rules! static_assert_size {
632 ($type:ty, $expected:expr) => {
633 const _: [(); $expected] = [(); ::core::mem::size_of::<$type>()];
634 };
635}
636
637pub mod lockfree {
642 use core::sync::atomic::{AtomicUsize, AtomicPtr, Ordering};
643 use core::ptr;
644
645 pub struct LockFreeStack<T> {
650 head: AtomicPtr<Node<T>>,
651 }
652
653 struct Node<T> {
654 value: T,
655 next: *mut Node<T>,
656 }
657
658 impl<T> LockFreeStack<T> {
659 #[inline]
661 pub const fn new() -> Self {
662 Self {
663 head: AtomicPtr::new(ptr::null_mut()),
664 }
665 }
666
667 #[inline]
669 pub fn push(&self, value: T) {
670 let node = Box::into_raw(Box::new(Node {
671 value,
672 next: ptr::null_mut(),
673 }));
674
675 loop {
676 let head = self.head.load(Ordering::Acquire);
677 unsafe { (*node).next = head; }
678
679 if self.head.compare_exchange(
680 head,
681 node,
682 Ordering::Release,
683 Ordering::Acquire,
684 ).is_ok() {
685 break;
686 }
687 }
688 }
689
690 #[inline]
692 pub fn pop(&self) -> Option<T> {
693 loop {
694 let head = self.head.load(Ordering::Acquire);
695 if head.is_null() {
696 return None;
697 }
698
699 let next = unsafe { (*head).next };
700
701 if self.head.compare_exchange(
702 head,
703 next,
704 Ordering::Release,
705 Ordering::Acquire,
706 ).is_ok() {
707 unsafe {
708 let value = ptr::read(&(*head).value);
709 drop(Box::from_raw(head));
710 return Some(value);
711 }
712 }
713 }
714 }
715 }
716
717 impl<T> Drop for LockFreeStack<T> {
718 fn drop(&mut self) {
719 while self.pop().is_some() {}
720 }
721 }
722
723 #[repr(align(64))]
727 pub struct AtomicCounter {
728 value: AtomicUsize,
729 _padding: [u8; 64 - core::mem::size_of::<AtomicUsize>()],
730 }
731
732 impl AtomicCounter {
733 #[inline]
735 pub const fn new(value: usize) -> Self {
736 Self {
737 value: AtomicUsize::new(value),
738 _padding: [0; 64 - core::mem::size_of::<AtomicUsize>()],
739 }
740 }
741
742 #[inline]
744 pub fn increment(&self) -> usize {
745 self.value.fetch_add(1, Ordering::Relaxed) + 1
746 }
747
748 #[inline]
750 pub fn get(&self) -> usize {
751 self.value.load(Ordering::Relaxed)
752 }
753
754 #[inline]
756 pub fn set(&self, value: usize) {
757 self.value.store(value, Ordering::Relaxed);
758 }
759 }
760
761 pub struct RingBuffer<T, const N: usize> {
766 buffer: [core::mem::MaybeUninit<T>; N],
767 head: AtomicUsize,
768 tail: AtomicUsize,
769 }
770
771 impl<T, const N: usize> RingBuffer<T, N> {
772 #[inline]
776 pub const fn new() -> Self {
777 assert!(N.is_power_of_two(), "Capacity must be power of 2");
778 Self {
779 buffer: unsafe { core::mem::MaybeUninit::uninit().assume_init() },
780 head: AtomicUsize::new(0),
781 tail: AtomicUsize::new(0),
782 }
783 }
784
785 #[inline]
787 pub fn push(&self, value: T) -> Result<(), T> {
788 let head = self.head.load(Ordering::Relaxed);
789 let tail = self.tail.load(Ordering::Acquire);
790 let next_head = (head + 1) & (N - 1);
791
792 if next_head == tail {
793 return Err(value); }
795
796 unsafe {
797 let slot = &self.buffer[head] as *const _ as *mut core::mem::MaybeUninit<T>;
798 (*slot).write(value);
799 }
800
801 self.head.store(next_head, Ordering::Release);
802 Ok(())
803 }
804
805 #[inline]
807 pub fn pop(&self) -> Option<T> {
808 let tail = self.tail.load(Ordering::Relaxed);
809 let head = self.head.load(Ordering::Acquire);
810
811 if tail == head {
812 return None; }
814
815 let value = unsafe {
816 let slot = &self.buffer[tail] as *const _ as *mut core::mem::MaybeUninit<T>;
817 (*slot).assume_init_read()
818 };
819
820 self.tail.store((tail + 1) & (N - 1), Ordering::Release);
821 Some(value)
822 }
823
824 #[inline]
826 pub fn len(&self) -> usize {
827 let head = self.head.load(Ordering::Relaxed);
828 let tail = self.tail.load(Ordering::Relaxed);
829 (head.wrapping_sub(tail)) & (N - 1)
830 }
831
832 #[inline]
834 pub fn is_empty(&self) -> bool {
835 self.len() == 0
836 }
837 }
838}pub mod btree {
843 use super::*;
844
845 const NODE_SIZE: usize = 16; pub struct BPlusTree<K: Ord, V> {
852 root: Option<Box<Node<K, V>>>,
853 len: usize,
854 }
855
856 enum Node<K: Ord, V> {
857 Leaf {
858 keys: [Option<K>; NODE_SIZE],
859 values: [Option<V>; NODE_SIZE],
860 next: Option<Box<Node<K, V>>>,
861 },
862 Internal {
863 keys: [Option<K>; NODE_SIZE],
864 children: [Option<Box<Node<K, V>>>; NODE_SIZE + 1],
865 },
866 }
867
868 impl<K: Ord + Clone, V: Clone> BPlusTree<K, V> {
869 #[inline]
871 pub const fn new() -> Self {
872 Self {
873 root: None,
874 len: 0,
875 }
876 }
877
878 #[inline]
880 pub fn insert(&mut self, key: K, value: V) -> Option<V> {
881 self.len += 1;
883 None
884 }
885
886 #[inline]
888 pub fn get(&self, _key: &K) -> Option<&V> {
889 None }
891
892 #[inline]
894 pub fn len(&self) -> usize {
895 self.len
896 }
897
898 #[inline]
900 pub fn is_empty(&self) -> bool {
901 self.len == 0
902 }
903 }
904}
905
906pub mod robinhood {
911 use super::*;
912 use core::hash::{Hash, Hasher};
913 use core::mem;
914
915 const INITIAL_CAPACITY: usize = 16;
916 const LOAD_FACTOR: f32 = 0.9;
917
918 pub struct RobinHoodMap<K, V> {
923 buckets: DynamicArray<Option<Bucket<K, V>>>,
924 len: usize,
925 capacity: usize,
926 }
927
928 struct Bucket<K, V> {
929 key: K,
930 value: V,
931 hash: u64,
932 dib: usize, }
934
935 impl<K: Hash + Eq, V> RobinHoodMap<K, V> {
936 #[inline]
938 pub fn new() -> Self {
939 Self::with_capacity(INITIAL_CAPACITY)
940 }
941
942 #[inline]
944 pub fn with_capacity(capacity: usize) -> Self {
945 let mut buckets = DynamicArray::with_capacity(capacity);
946 for _ in 0..capacity {
947 buckets.push(None);
948 }
949
950 Self {
951 buckets,
952 len: 0,
953 capacity,
954 }
955 }
956
957 #[inline]
959 pub fn insert(&mut self, key: K, value: V) -> Option<V> {
960 if self.len as f32 > self.capacity as f32 * LOAD_FACTOR {
961 self.resize();
962 }
963
964 let hash = self.hash(&key);
965 let mut pos = (hash as usize) % self.capacity;
966 let mut dib = 0;
967
968 let mut bucket = Bucket {
969 key,
970 value,
971 hash,
972 dib: 0,
973 };
974
975 loop {
976 match &mut self.buckets[pos] {
977 None => {
978 bucket.dib = dib;
979 self.buckets[pos] = Some(bucket);
980 self.len += 1;
981 return None;
982 }
983 Some(existing) => {
984 if existing.hash == bucket.hash && existing.key == bucket.key {
985 return Some(mem::replace(&mut existing.value, bucket.value));
986 }
987
988 if dib > existing.dib {
990 mem::swap(&mut bucket, existing);
991 }
992 }
993 }
994
995 pos = (pos + 1) % self.capacity;
996 dib += 1;
997 }
998 }
999
1000 #[inline]
1002 pub fn get(&self, key: &K) -> Option<&V> {
1003 let hash = self.hash(key);
1004 let mut pos = (hash as usize) % self.capacity;
1005 let mut dib = 0;
1006
1007 loop {
1008 match &self.buckets[pos] {
1009 None => return None,
1010 Some(bucket) => {
1011 if bucket.dib < dib {
1012 return None; }
1014 if bucket.hash == hash && &bucket.key == key {
1015 return Some(&bucket.value);
1016 }
1017 }
1018 }
1019
1020 pos = (pos + 1) % self.capacity;
1021 dib += 1;
1022 }
1023 }
1024
1025 fn hash(&self, key: &K) -> u64 {
1026 let mut hasher = FnvHasher::default();
1028 key.hash(&mut hasher);
1029 hasher.finish()
1030 }
1031
1032 fn resize(&mut self) {
1033 let new_capacity = self.capacity * 2;
1034 let mut new_map = Self::with_capacity(new_capacity);
1035
1036 for bucket in self.buckets.iter_mut() {
1037 if let Some(b) = bucket.take() {
1038 new_map.insert(b.key, b.value);
1039 }
1040 }
1041
1042 *self = new_map;
1043 }
1044 }
1045
1046 struct FnvHasher(u64);
1048
1049 impl Default for FnvHasher {
1050 fn default() -> Self {
1051 Self(0xcbf29ce484222325)
1052 }
1053 }
1054
1055 impl Hasher for FnvHasher {
1056 fn finish(&self) -> u64 {
1057 self.0
1058 }
1059
1060 fn write(&mut self, bytes: &[u8]) {
1061 for &byte in bytes {
1062 self.0 ^= byte as u64;
1063 self.0 = self.0.wrapping_mul(0x100000001b3);
1064 }
1065 }
1066 }
1067}
1068
1069pub mod compress {
1074 use super::*;
1075
1076 #[inline]
1081 pub fn rle_encode(input: &[u8], output: &mut DynamicArray<u8>) {
1082 if input.is_empty() {
1083 return;
1084 }
1085
1086 let mut i = 0;
1087 while i < input.len() {
1088 let byte = input[i];
1089 let mut count = 1;
1090
1091 while i + count < input.len() && input[i + count] == byte && count < 255 {
1092 count += 1;
1093 }
1094
1095 output.push(count as u8);
1096 output.push(byte);
1097 i += count;
1098 }
1099 }
1100
1101 #[inline]
1103 pub fn rle_decode(input: &[u8], output: &mut DynamicArray<u8>) {
1104 let mut i = 0;
1105 while i + 1 < input.len() {
1106 let count = input[i] as usize;
1107 let byte = input[i + 1];
1108
1109 for _ in 0..count {
1110 output.push(byte);
1111 }
1112
1113 i += 2;
1114 }
1115 }
1116
1117 #[inline]
1121 pub fn delta_encode(input: &[i64], output: &mut DynamicArray<i64>) {
1122 if input.is_empty() {
1123 return;
1124 }
1125
1126 output.push(input[0]);
1127 for i in 1..input.len() {
1128 output.push(input[i] - input[i - 1]);
1129 }
1130 }
1131
1132 #[inline]
1134 pub fn delta_decode(input: &[i64], output: &mut DynamicArray<i64>) {
1135 if input.is_empty() {
1136 return;
1137 }
1138
1139 output.push(input[0]);
1140 for i in 1..input.len() {
1141 output.push(output[i - 1] + input[i]);
1142 }
1143 }
1144}
1145
1146#[cfg(test)]
1147mod tests {
1148 use super::*;
1149
1150 #[test]
1151 fn test_option() {
1152 let some: Option<i32> = Option::Some(42);
1153 let none: Option<i32> = Option::None;
1154
1155 assert!(some.is_some());
1156 assert!(none.is_none());
1157 }
1158
1159 #[test]
1160 fn test_result() {
1161 let ok: Result<i32, &str> = Result::Ok(42);
1162 let err: Result<i32, &str> = Result::Err("error");
1163
1164 assert!(ok.is_ok());
1165 assert!(err.is_err());
1166 }
1167
1168 #[test]
1169 fn test_dynamic_array() {
1170 let mut v: DynamicArray<i32> = DynamicArray::new();
1171 assert_eq!(v.capacity(), 0); v.push(1);
1174 v.push(2);
1175 v.push(3);
1176
1177 assert_eq!(v.len(), 3);
1178 assert!(v.capacity() >= 3); }
1180
1181 #[test]
1182 fn test_dynamic_array_with_capacity() {
1183 let v: DynamicArray<i32> = DynamicArray::with_capacity(100);
1184 assert_eq!(v.capacity(), 100);
1185 assert_eq!(v.len(), 0);
1186 }
1187
1188 #[test]
1189 #[cfg(feature = "std")]
1190 fn test_associative_array() {
1191 let m = map! {
1192 "key1" => "value1",
1193 "key2" => "value2",
1194 };
1195
1196 assert_eq!(m.get("key1"), Some(&"value1"));
1197 assert_eq!(m.get("key2"), Some(&"value2"));
1198 assert_eq!(m.len(), 2);
1199 }
1200
1201 #[test]
1202 fn test_string_buffer() {
1203 let s: StringBuffer = StringBuffer::from("Hello, Avila!");
1204 assert_eq!(s.len(), 13);
1205 assert!(s.is_ascii()); }
1207
1208 #[test]
1209 fn test_string_buffer_utf8() {
1210 let s: StringBuffer = StringBuffer::from("Ávila 🚀");
1211 assert_eq!(s.chars().count(), 7); assert_eq!(s.len(), 11); }
1214
1215 #[test]
1216 fn test_fixed_array() {
1217 use crate::fixed::FixedArray;
1218
1219 let arr = FixedArray::new([1, 2, 3, 4, 5]);
1220 assert_eq!(arr.len(), 5);
1221 assert_eq!(arr.as_slice()[0], 1);
1222 }
1223
1224 #[test]
1225 fn test_option_size_optimization() {
1226 use core::mem::size_of;
1227
1228 assert_eq!(size_of::<Option<&i32>>(), size_of::<&i32>());
1230 assert_eq!(size_of::<Option<Box<i32>>>(), size_of::<Box<i32>>());
1231 }
1232
1233 #[test]
1234 fn test_result_error_handling() {
1235 fn divide(a: i32, b: i32) -> Result<i32, &'static str> {
1236 if b == 0 {
1237 Err("Division by zero")
1238 } else {
1239 Ok(a / b)
1240 }
1241 }
1242
1243 assert_eq!(divide(10, 2), Ok(5));
1244 assert_eq!(divide(10, 0), Err("Division by zero"));
1245 }
1246
1247 #[test]
1248 fn test_iterator_performance() {
1249 use crate::iter::IntoIteratorWithHint;
1250
1251 let v = list![1, 2, 3, 4, 5];
1252 let (lower, upper) = v.size_hint_before();
1253
1254 assert_eq!(lower, 5);
1255 assert_eq!(upper, Some(5));
1256 }
1257
1258 #[test]
1259 #[cfg(feature = "std")]
1260 fn test_map_macro_capacity() {
1261 let m = map! {
1262 1 => "one",
1263 2 => "two",
1264 3 => "three",
1265 };
1266
1267 assert!(m.capacity() >= 3);
1269 }
1270
1271 #[test]
1272 fn test_cache_aligned_array() {
1273 use crate::fixed::{CacheAlignedArray, CACHE_LINE_SIZE};
1274 use core::mem::align_of;
1275
1276 let arr = CacheAlignedArray::new([1u64, 2, 3, 4]);
1277 assert_eq!(align_of::<CacheAlignedArray<u64, 4>>(), CACHE_LINE_SIZE);
1278 assert_eq!(arr.as_slice()[0], 1);
1279 }
1280
1281 #[test]
1282 fn test_dynamic_array_extensions() {
1283 use crate::DynamicArrayExt;
1284
1285 let mut v = DynamicArray::new();
1286 v.reserve_exact_fast(100);
1287 assert!(v.capacity() >= 100);
1288
1289 v.extend_from_slice_fast(&[1, 2, 3]);
1290 assert_eq!(v.len(), 3);
1291
1292 v.clear_and_resize(10);
1293 assert_eq!(v.len(), 0);
1294 assert!(v.capacity() >= 10);
1295 }
1296
1297 #[cfg(target_arch = "x86_64")]
1298 #[test]
1299 fn test_simd_availability() {
1300 use crate::simd::{has_avx2, has_avx512f};
1301
1302 let _ = has_avx2();
1304 let _ = has_avx512f();
1305 }
1306
1307 #[test]
1308 fn test_fixed_array_zero_cost() {
1309 use core::mem::size_of;
1310 use crate::fixed::FixedArray;
1311
1312 assert_eq!(
1314 size_of::<FixedArray<u64, 8>>(),
1315 size_of::<[u64; 8]>()
1316 );
1317 }
1318
1319 #[test]
1320 fn test_arena_allocator() {
1321 use crate::arena::Arena;
1322
1323 let mut arena = Arena::with_capacity(1024);
1324
1325 let val1 = arena.alloc_value(42u64).unwrap();
1327 assert_eq!(*val1, 42);
1328
1329 let val2 = arena.alloc_value(100u32).unwrap();
1330 assert_eq!(*val2, 100);
1331 assert!(arena.used() > 0);
1332
1333 arena.reset();
1335 assert_eq!(arena.used(), 0);
1336 } #[test]
1337 fn test_object_pool() {
1338 use crate::pool::ObjectPool;
1339
1340 let mut pool = ObjectPool::with_capacity(10);
1341
1342 let id1 = pool.acquire(|| String::from("test1"));
1344 let id2 = pool.acquire(|| String::from("test2"));
1345
1346 assert_eq!(pool.get(id1).unwrap(), "test1");
1347 assert_eq!(pool.get(id2).unwrap(), "test2");
1348
1349 pool.release(id1);
1351 let id3 = pool.acquire(|| String::from("test3"));
1352 assert_eq!(id3, id1); }
1354
1355 #[test]
1356 fn test_lockfree_stack() {
1357 use crate::lockfree::LockFreeStack;
1358
1359 let stack = LockFreeStack::new();
1360
1361 stack.push(1);
1362 stack.push(2);
1363 stack.push(3);
1364
1365 assert_eq!(stack.pop(), Some(3));
1366 assert_eq!(stack.pop(), Some(2));
1367 assert_eq!(stack.pop(), Some(1));
1368 assert_eq!(stack.pop(), None);
1369 }
1370
1371 #[test]
1372 fn test_atomic_counter() {
1373 use crate::lockfree::AtomicCounter;
1374
1375 let counter = AtomicCounter::new(0);
1376
1377 assert_eq!(counter.increment(), 1);
1378 assert_eq!(counter.increment(), 2);
1379 assert_eq!(counter.get(), 2);
1380
1381 counter.set(100);
1382 assert_eq!(counter.get(), 100);
1383 }
1384
1385 #[test]
1386 fn test_ring_buffer() {
1387 use crate::lockfree::RingBuffer;
1388
1389 let ring: RingBuffer<i32, 8> = RingBuffer::new();
1390
1391 assert!(ring.push(1).is_ok());
1392 assert!(ring.push(2).is_ok());
1393 assert!(ring.push(3).is_ok());
1394
1395 assert_eq!(ring.len(), 3);
1396 assert_eq!(ring.pop(), Some(1));
1397 assert_eq!(ring.pop(), Some(2));
1398 assert_eq!(ring.len(), 1);
1399 }
1400
1401 #[test]
1402 fn test_bplustree() {
1403 use crate::btree::BPlusTree;
1404
1405 let mut tree = BPlusTree::new();
1406 assert!(tree.is_empty());
1407
1408 tree.insert(1, "one");
1409 tree.insert(2, "two");
1410
1411 assert_eq!(tree.len(), 2);
1412 }
1413
1414 #[test]
1415 fn test_robinhood_map() {
1416 use crate::robinhood::RobinHoodMap;
1417
1418 let mut map: RobinHoodMap<&str, i32> = RobinHoodMap::new();
1419
1420 assert_eq!(map.insert("key1", 100), None);
1421 assert_eq!(map.insert("key2", 200), None);
1422 assert_eq!(map.insert("key1", 150), Some(100));
1423
1424 assert_eq!(map.get(&"key1"), Some(&150));
1425 assert_eq!(map.get(&"key2"), Some(&200));
1426 assert_eq!(map.get(&"key3"), None);
1427 } #[test]
1428 fn test_rle_compression() {
1429 use crate::compress::{rle_encode, rle_decode};
1430
1431 let input = vec![5, 5, 5, 5, 7, 7, 3];
1432 let mut encoded = DynamicArray::new();
1433 let mut decoded = DynamicArray::new();
1434
1435 rle_encode(&input, &mut encoded);
1436 assert!(encoded.len() < input.len() * 2);
1437
1438 rle_decode(&encoded, &mut decoded);
1439 assert_eq!(decoded.as_slice(), input.as_slice());
1440 }
1441
1442 #[test]
1443 fn test_delta_encoding() {
1444 use crate::compress::{delta_encode, delta_decode};
1445
1446 let input = vec![100, 101, 102, 103, 110, 115];
1447 let mut encoded = DynamicArray::new();
1448 let mut decoded = DynamicArray::new();
1449
1450 delta_encode(&input, &mut encoded);
1451 assert!(encoded[1].abs() < 10);
1453
1454 delta_decode(&encoded, &mut decoded);
1455 assert_eq!(decoded.as_slice(), input.as_slice());
1456 }
1457}
1458
1459#[cfg(test)]
1461mod benches {
1462 use super::*;
1463
1464 #[inline(never)] fn bench_array_push(n: usize) -> DynamicArray<i32> {
1469 let mut v = DynamicArray::with_capacity(n);
1470 for i in 0..n {
1471 v.push(i as i32);
1472 }
1473 v
1474 }
1475
1476 #[test]
1477 fn test_bench_hints() {
1478 let v = bench_array_push(1000);
1480 assert_eq!(v.len(), 1000);
1481 }
1482}
1483
1484pub mod skiplist {
1490 use super::*;
1491 use core::sync::atomic::{AtomicPtr, Ordering};
1492 use core::ptr;
1493 use core::cmp::Ordering as CmpOrdering;
1494
1495 const MAX_LEVEL: usize = 16;
1496 const P_FACTOR: f64 = 0.25; struct Node<K, V> {
1500 key: K,
1501 value: V,
1502 next: [AtomicPtr<Node<K, V>>; MAX_LEVEL],
1503 }
1504
1505 impl<K, V> Node<K, V> {
1506 fn new(key: K, value: V) -> Self {
1507 Self {
1508 key,
1509 value,
1510 next: core::array::from_fn(|_| AtomicPtr::new(ptr::null_mut())),
1511 }
1512 }
1513 }
1514
1515 pub struct SkipList<K: Ord, V> {
1520 head: Box<Node<K, V>>,
1521 level: usize,
1522 }
1523
1524 impl<K: Ord + Default, V: Default> SkipList<K, V> {
1525 pub fn new() -> Self {
1527 Self {
1528 head: Box::new(Node::new(K::default(), V::default())),
1529 level: 0,
1530 }
1531 }
1532
1533 pub fn insert(&mut self, key: K, value: V) -> bool {
1535 let new_level = Self::random_level();
1537 let node = Box::new(Node::new(key, value));
1538 let node_ptr = Box::into_raw(node);
1539
1540 unsafe {
1542 let head_next = self.head.next[0].load(Ordering::Acquire);
1543 (*node_ptr).next[0].store(head_next, Ordering::Release);
1544 self.head.next[0].store(node_ptr, Ordering::Release);
1545 }
1546
1547 if new_level > self.level {
1548 self.level = new_level;
1549 }
1550 true
1551 }
1552
1553 pub fn contains(&self, key: &K) -> bool {
1555 let mut current = &*self.head;
1556
1557 for level in (0..=self.level).rev() {
1558 loop {
1559 let next_ptr = current.next[level].load(Ordering::Acquire);
1560 if next_ptr.is_null() {
1561 break;
1562 }
1563
1564 let next = unsafe { &*next_ptr };
1565 match next.key.cmp(key) {
1566 CmpOrdering::Less => current = next,
1567 CmpOrdering::Equal => return true,
1568 CmpOrdering::Greater => break,
1569 }
1570 }
1571 }
1572 false
1573 }
1574
1575 fn random_level() -> usize {
1576 0
1578 }
1579 }
1580}
1581
1582pub mod radix {
1588 use super::*;
1589
1590 const RADIX: usize = 256; struct RadixNode<V> {
1593 children: [Option<Box<RadixNode<V>>>; RADIX],
1594 value: Option<V>,
1595 prefix: DynamicArray<u8>,
1596 }
1597
1598 impl<V> RadixNode<V> {
1599 fn new() -> Self {
1600 Self {
1601 children: core::array::from_fn(|_| None),
1602 value: None,
1603 prefix: DynamicArray::new(),
1604 }
1605 }
1606 }
1607
1608 pub struct RadixTree<V> {
1613 root: RadixNode<V>,
1614 size: usize,
1615 }
1616
1617 impl<V> RadixTree<V> {
1618 pub fn new() -> Self {
1620 Self {
1621 root: RadixNode::new(),
1622 size: 0,
1623 }
1624 }
1625
1626 pub fn insert(&mut self, key: &[u8], value: V) {
1628 self.size += 1;
1629 let mut node = &mut self.root;
1630
1631 for &byte in key {
1632 let idx = byte as usize;
1633 node = node.children[idx].get_or_insert_with(|| Box::new(RadixNode::new()));
1634 }
1635 node.value = Some(value);
1636 }
1637
1638 pub fn get(&self, key: &[u8]) -> Option<&V> {
1640 let mut node = &self.root;
1641
1642 for &byte in key {
1643 let idx = byte as usize;
1644 node = node.children[idx].as_ref()?.as_ref();
1645 }
1646 node.value.as_ref()
1647 }
1648
1649 pub fn len(&self) -> usize {
1651 self.size
1652 }
1653
1654 pub fn is_empty(&self) -> bool {
1656 self.size == 0
1657 }
1658 }
1659}
1660
1661pub mod bloom {
1667 use super::*;
1668 use core::hash::{Hash, Hasher};
1669
1670 pub struct BloomFilter<T> {
1675 bits: DynamicArray<u64>,
1676 num_hashes: usize,
1677 size: usize,
1678 _phantom: core::marker::PhantomData<T>,
1679 }
1680
1681 impl<T: Hash> BloomFilter<T> {
1682 pub fn new(capacity: usize, fpr: f64) -> Self {
1688 let bits_per_elem = -((fpr.ln()) / (2.0_f64.ln().powi(2)));
1690 let total_bits = (capacity as f64 * bits_per_elem).ceil() as usize;
1691 let num_words = (total_bits + 63) / 64;
1692
1693 let num_hashes = ((total_bits as f64 / capacity as f64) * 2.0_f64.ln()).ceil() as usize;
1695 let num_hashes = num_hashes.max(1).min(10);
1696
1697 let mut bits = DynamicArray::with_capacity(num_words);
1698 for _ in 0..num_words {
1699 bits.push(0u64);
1700 }
1701
1702 Self {
1703 bits,
1704 num_hashes,
1705 size: total_bits,
1706 _phantom: core::marker::PhantomData,
1707 }
1708 }
1709
1710 pub fn insert(&mut self, item: &T) {
1712 for i in 0..self.num_hashes {
1713 let hash = self.hash(item, i);
1714 let bit_idx = (hash % self.size as u64) as usize;
1715 let word_idx = bit_idx / 64;
1716 let bit_pos = bit_idx % 64;
1717 self.bits[word_idx] |= 1u64 << bit_pos;
1718 }
1719 }
1720
1721 pub fn contains(&self, item: &T) -> bool {
1725 for i in 0..self.num_hashes {
1726 let hash = self.hash(item, i);
1727 let bit_idx = (hash % self.size as u64) as usize;
1728 let word_idx = bit_idx / 64;
1729 let bit_pos = bit_idx % 64;
1730 if (self.bits[word_idx] & (1u64 << bit_pos)) == 0 {
1731 return false;
1732 }
1733 }
1734 true
1735 }
1736
1737 fn hash(&self, item: &T, seed: usize) -> u64 {
1738 let mut hasher = FnvHasher::new(seed as u64);
1740 item.hash(&mut hasher);
1741 hasher.finish()
1742 }
1743 }
1744
1745 struct FnvHasher(u64);
1746
1747 impl FnvHasher {
1748 fn new(seed: u64) -> Self {
1749 Self(0xcbf29ce484222325u64.wrapping_add(seed))
1750 }
1751 }
1752
1753 impl Hasher for FnvHasher {
1754 fn finish(&self) -> u64 {
1755 self.0
1756 }
1757
1758 fn write(&mut self, bytes: &[u8]) {
1759 for &byte in bytes {
1760 self.0 = self.0.wrapping_mul(0x100000001b3);
1761 self.0 ^= byte as u64;
1762 }
1763 }
1764 }
1765}
1766
1767pub mod cow {
1772 use super::*;
1773 use core::sync::atomic::{AtomicUsize, Ordering};
1774
1775 struct SharedData<T> {
1776 data: DynamicArray<T>,
1777 refcount: AtomicUsize,
1778 }
1779
1780 pub struct CowArray<T: Clone> {
1784 inner: *mut SharedData<T>,
1785 }
1786
1787 impl<T: Clone> CowArray<T> {
1788 pub fn new() -> Self {
1790 let data = Box::new(SharedData {
1791 data: DynamicArray::new(),
1792 refcount: AtomicUsize::new(1),
1793 });
1794 Self {
1795 inner: Box::into_raw(data),
1796 }
1797 }
1798
1799 pub fn push(&mut self, value: T) {
1801 self.ensure_unique();
1802 unsafe {
1803 (*self.inner).data.push(value);
1804 }
1805 }
1806
1807 pub fn get(&self, index: usize) -> Option<&T> {
1809 unsafe {
1810 let data_ref = &(*self.inner).data;
1811 data_ref.get(index)
1812 }
1813 }
1814
1815 pub fn len(&self) -> usize {
1817 unsafe {
1818 (*self.inner).data.len()
1819 }
1820 }
1821
1822 fn ensure_unique(&mut self) {
1823 unsafe {
1824 let refcount = (*self.inner).refcount.load(Ordering::Acquire);
1825 if refcount > 1 {
1826 let new_data = Box::new(SharedData {
1828 data: (*self.inner).data.clone(),
1829 refcount: AtomicUsize::new(1),
1830 });
1831 (*self.inner).refcount.fetch_sub(1, Ordering::Release);
1832 self.inner = Box::into_raw(new_data);
1833 }
1834 }
1835 }
1836 }
1837
1838 impl<T: Clone> Clone for CowArray<T> {
1839 fn clone(&self) -> Self {
1840 unsafe {
1841 (*self.inner).refcount.fetch_add(1, Ordering::AcqRel);
1842 }
1843 Self { inner: self.inner }
1844 }
1845 }
1846
1847 impl<T: Clone> Drop for CowArray<T> {
1848 fn drop(&mut self) {
1849 unsafe {
1850 let refcount = (*self.inner).refcount.fetch_sub(1, Ordering::Release);
1851 if refcount == 1 {
1852 let _ = Box::from_raw(self.inner);
1853 }
1854 }
1855 }
1856 }
1857}
1858
1859pub mod intrusive {
1865 use super::*;
1866 use core::ptr::NonNull;
1867
1868 pub trait IntrusiveNode {
1870 fn next(&self) -> Option<NonNull<Self>>;
1871 fn set_next(&mut self, next: Option<NonNull<Self>>);
1872 }
1873
1874 pub struct IntrusiveList<T: IntrusiveNode> {
1878 head: Option<NonNull<T>>,
1879 tail: Option<NonNull<T>>,
1880 len: usize,
1881 }
1882
1883 impl<T: IntrusiveNode> IntrusiveList<T> {
1884 pub const fn new() -> Self {
1886 Self {
1887 head: None,
1888 tail: None,
1889 len: 0,
1890 }
1891 }
1892
1893 pub fn push_back(&mut self, node: NonNull<T>) {
1895 unsafe {
1896 (*node.as_ptr()).set_next(None);
1897
1898 match self.tail {
1899 Some(tail) => (*tail.as_ptr()).set_next(Some(node)),
1900 None => self.head = Some(node),
1901 }
1902
1903 self.tail = Some(node);
1904 self.len += 1;
1905 }
1906 }
1907
1908 pub fn pop_front(&mut self) -> Option<NonNull<T>> {
1910 self.head.map(|head| unsafe {
1911 let next = (*head.as_ptr()).next();
1912 self.head = next;
1913
1914 if next.is_none() {
1915 self.tail = None;
1916 }
1917
1918 self.len -= 1;
1919 head
1920 })
1921 }
1922
1923 pub fn len(&self) -> usize {
1925 self.len
1926 }
1927
1928 pub fn is_empty(&self) -> bool {
1930 self.len == 0
1931 }
1932 }
1933}
1934
1935pub mod numa {
1941 use super::*;
1942
1943 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
1945 pub struct NumaNode(pub usize);
1946
1947 pub struct NumaPool<T> {
1951 pools: DynamicArray<DynamicArray<T>>,
1952 current_node: NumaNode,
1953 }
1954
1955 impl<T> NumaPool<T> {
1956 pub fn new(num_nodes: usize) -> Self {
1958 let mut pools = DynamicArray::with_capacity(num_nodes);
1959 for _ in 0..num_nodes {
1960 pools.push(DynamicArray::new());
1961 }
1962
1963 Self {
1964 pools,
1965 current_node: NumaNode(0),
1966 }
1967 }
1968
1969 pub fn set_node(&mut self, node: NumaNode) {
1971 if node.0 < self.pools.len() {
1972 self.current_node = node;
1973 }
1974 }
1975
1976 pub fn push(&mut self, value: T) {
1978 self.pools[self.current_node.0].push(value);
1979 }
1980
1981 pub fn pop(&mut self) -> Option<T> {
1983 self.pools[self.current_node.0].pop()
1984 }
1985
1986 pub fn len(&self) -> usize {
1988 self.pools.iter().map(|p| p.len()).sum()
1989 }
1990 }
1991}
1992
1993#[cfg(test)]
1994mod tests_v6 {
1995 use super::*;
1996
1997 #[test]
1998 fn test_skiplist() {
1999 use crate::skiplist::SkipList;
2000
2001 let mut list: SkipList<i32, &str> = SkipList::new();
2002 list.insert(5, "five");
2003 list.insert(3, "three");
2004 list.insert(7, "seven");
2005
2006 let _ = list.contains(&5);
2008 let _ = list.contains(&3);
2009 }
2010
2011 #[test]
2012 fn test_radix_tree() {
2013 use crate::radix::RadixTree;
2014
2015 let mut tree = RadixTree::new();
2016 tree.insert(b"hello", 100);
2017 tree.insert(b"world", 200);
2018 tree.insert(b"help", 300);
2019
2020 assert_eq!(tree.get(b"hello"), Some(&100));
2021 assert_eq!(tree.get(b"world"), Some(&200));
2022 assert_eq!(tree.get(b"help"), Some(&300));
2023 assert_eq!(tree.get(b"hi"), None);
2024 assert_eq!(tree.len(), 3);
2025 }
2026
2027 #[test]
2028 fn test_bloom_filter() {
2029 use crate::bloom::BloomFilter;
2030
2031 let mut filter: BloomFilter<&str> = BloomFilter::new(1000, 0.01);
2032
2033 filter.insert(&"apple");
2034 filter.insert(&"banana");
2035 filter.insert(&"cherry");
2036
2037 assert!(filter.contains(&"apple"));
2038 assert!(filter.contains(&"banana"));
2039 assert!(filter.contains(&"cherry"));
2040 assert!(!filter.contains(&"dragonfruit")); }
2042
2043 #[test]
2044 fn test_cow_array() {
2045 use crate::cow::CowArray;
2046
2047 let mut arr1: CowArray<i32> = CowArray::new();
2048 arr1.push(1);
2049 arr1.push(2);
2050 arr1.push(3);
2051
2052 let mut arr2 = arr1.clone(); assert_eq!(arr1.len(), 3);
2054 assert_eq!(arr2.len(), 3);
2055
2056 arr2.push(4); assert_eq!(arr1.len(), 3);
2058 assert_eq!(arr2.len(), 4);
2059 }
2060
2061 #[test]
2062 fn test_intrusive_list() {
2063 use crate::intrusive::{IntrusiveList, IntrusiveNode};
2064 use core::ptr::NonNull;
2065
2066 struct TestNode {
2067 value: i32,
2068 next: Option<NonNull<TestNode>>,
2069 }
2070
2071 impl IntrusiveNode for TestNode {
2072 fn next(&self) -> Option<NonNull<Self>> {
2073 self.next
2074 }
2075 fn set_next(&mut self, next: Option<NonNull<Self>>) {
2076 self.next = next;
2077 }
2078 }
2079
2080 let mut list = IntrusiveList::new();
2081
2082 let mut node1 = Box::new(TestNode { value: 1, next: None });
2083 let mut node2 = Box::new(TestNode { value: 2, next: None });
2084
2085 let ptr1 = NonNull::new(node1.as_mut() as *mut TestNode).unwrap();
2086 let ptr2 = NonNull::new(node2.as_mut() as *mut TestNode).unwrap();
2087
2088 list.push_back(ptr1);
2089 list.push_back(ptr2);
2090 assert_eq!(list.len(), 2);
2091
2092 let popped = list.pop_front();
2093 assert!(popped.is_some());
2094 assert_eq!(list.len(), 1);
2095
2096 let _ = (node1, node2);
2098 }
2099
2100 #[test]
2101 fn test_numa_pool() {
2102 use crate::numa::{NumaPool, NumaNode};
2103
2104 let mut pool = NumaPool::new(2);
2105 pool.set_node(NumaNode(0));
2106 pool.push(100);
2107 pool.push(200);
2108
2109 pool.set_node(NumaNode(1));
2110 pool.push(300);
2111
2112 assert_eq!(pool.len(), 3);
2113
2114 assert_eq!(pool.pop(), Some(300)); pool.set_node(NumaNode(0));
2116 assert_eq!(pool.pop(), Some(200)); }
2118}
2119
2120pub mod heap {
2125 use super::*;
2126 use core::cmp::Ordering;
2127
2128 pub struct MinHeap<T: Ord> {
2130 data: DynamicArray<T>,
2131 }
2132
2133 impl<T: Ord> MinHeap<T> {
2134 pub fn new() -> Self {
2135 Self { data: DynamicArray::new() }
2136 }
2137
2138 pub fn with_capacity(capacity: usize) -> Self {
2139 Self { data: DynamicArray::with_capacity(capacity) }
2140 }
2141
2142 pub fn push(&mut self, item: T) {
2143 self.data.push(item);
2144 self.bubble_up(self.data.len() - 1);
2145 }
2146
2147 pub fn pop(&mut self) -> Option<T> {
2148 if self.data.is_empty() {
2149 return None;
2150 }
2151 let len = self.data.len();
2152 self.data.swap(0, len - 1);
2153 let result = self.data.pop();
2154 if !self.data.is_empty() {
2155 self.bubble_down(0);
2156 }
2157 result
2158 }
2159
2160 pub fn peek(&self) -> Option<&T> {
2161 self.data.get(0)
2162 }
2163
2164 pub fn len(&self) -> usize {
2165 self.data.len()
2166 }
2167
2168 pub fn is_empty(&self) -> bool {
2169 self.data.is_empty()
2170 }
2171
2172 fn bubble_up(&mut self, mut idx: usize) {
2173 while idx > 0 {
2174 let parent = (idx - 1) / 2;
2175 if self.data[idx] >= self.data[parent] {
2176 break;
2177 }
2178 self.data.swap(idx, parent);
2179 idx = parent;
2180 }
2181 }
2182
2183 fn bubble_down(&mut self, mut idx: usize) {
2184 let len = self.data.len();
2185 loop {
2186 let left = 2 * idx + 1;
2187 let right = 2 * idx + 2;
2188 let mut smallest = idx;
2189
2190 if left < len && self.data[left] < self.data[smallest] {
2191 smallest = left;
2192 }
2193 if right < len && self.data[right] < self.data[smallest] {
2194 smallest = right;
2195 }
2196 if smallest == idx {
2197 break;
2198 }
2199 self.data.swap(idx, smallest);
2200 idx = smallest;
2201 }
2202 }
2203 }
2204
2205 pub struct MaxHeap<T: Ord> {
2207 data: DynamicArray<T>,
2208 }
2209
2210 impl<T: Ord> MaxHeap<T> {
2211 pub fn new() -> Self {
2212 Self { data: DynamicArray::new() }
2213 }
2214
2215 pub fn push(&mut self, item: T) {
2216 self.data.push(item);
2217 self.bubble_up(self.data.len() - 1);
2218 }
2219
2220 pub fn pop(&mut self) -> Option<T> {
2221 if self.data.is_empty() {
2222 return None;
2223 }
2224 let len = self.data.len();
2225 self.data.swap(0, len - 1);
2226 let result = self.data.pop();
2227 if !self.data.is_empty() {
2228 self.bubble_down(0);
2229 }
2230 result
2231 }
2232
2233 pub fn peek(&self) -> Option<&T> {
2234 self.data.get(0)
2235 }
2236
2237 pub fn len(&self) -> usize {
2238 self.data.len()
2239 }
2240
2241 fn bubble_up(&mut self, mut idx: usize) {
2242 while idx > 0 {
2243 let parent = (idx - 1) / 2;
2244 if self.data[idx] <= self.data[parent] {
2245 break;
2246 }
2247 self.data.swap(idx, parent);
2248 idx = parent;
2249 }
2250 }
2251
2252 fn bubble_down(&mut self, mut idx: usize) {
2253 let len = self.data.len();
2254 loop {
2255 let left = 2 * idx + 1;
2256 let right = 2 * idx + 2;
2257 let mut largest = idx;
2258
2259 if left < len && self.data[left] > self.data[largest] {
2260 largest = left;
2261 }
2262 if right < len && self.data[right] > self.data[largest] {
2263 largest = right;
2264 }
2265 if largest == idx {
2266 break;
2267 }
2268 self.data.swap(idx, largest);
2269 idx = largest;
2270 }
2271 }
2272 }
2273}
2274
2275pub mod unionfind {
2280 use super::*;
2281
2282 pub struct UnionFind {
2283 parent: DynamicArray<usize>,
2284 rank: DynamicArray<usize>,
2285 count: usize,
2286 }
2287
2288 impl UnionFind {
2289 pub fn new(size: usize) -> Self {
2290 let mut parent = DynamicArray::with_capacity(size);
2291 let mut rank = DynamicArray::with_capacity(size);
2292 for i in 0..size {
2293 parent.push(i);
2294 rank.push(0);
2295 }
2296 Self { parent, rank, count: size }
2297 }
2298
2299 pub fn find(&mut self, mut x: usize) -> usize {
2300 while x != self.parent[x] {
2301 let next = self.parent[x];
2302 self.parent[x] = self.parent[next]; x = next;
2304 }
2305 x
2306 }
2307
2308 pub fn union(&mut self, x: usize, y: usize) -> bool {
2309 let root_x = self.find(x);
2310 let root_y = self.find(y);
2311
2312 if root_x == root_y {
2313 return false;
2314 }
2315
2316 if self.rank[root_x] < self.rank[root_y] {
2318 self.parent[root_x] = root_y;
2319 } else if self.rank[root_x] > self.rank[root_y] {
2320 self.parent[root_y] = root_x;
2321 } else {
2322 self.parent[root_y] = root_x;
2323 self.rank[root_x] += 1;
2324 }
2325
2326 self.count -= 1;
2327 true
2328 }
2329
2330 pub fn connected(&mut self, x: usize, y: usize) -> bool {
2331 self.find(x) == self.find(y)
2332 }
2333
2334 pub fn count(&self) -> usize {
2335 self.count
2336 }
2337 }
2338}
2339
2340pub mod lru {
2345 use super::*;
2346 use core::ptr::NonNull;
2347
2348 struct Node<K, V> {
2349 key: K,
2350 value: V,
2351 prev: Option<NonNull<Node<K, V>>>,
2352 next: Option<NonNull<Node<K, V>>>,
2353 }
2354
2355 pub struct LruCache<K: Eq + core::hash::Hash + Clone, V> {
2356 map: AssociativeArray<K, NonNull<Node<K, V>>>,
2357 head: Option<NonNull<Node<K, V>>>,
2358 tail: Option<NonNull<Node<K, V>>>,
2359 capacity: usize,
2360 size: usize,
2361 }
2362
2363 impl<K: Eq + core::hash::Hash + Clone, V> LruCache<K, V> {
2364 pub fn new(capacity: usize) -> Self {
2365 Self {
2366 map: AssociativeArray::default(),
2367 head: None,
2368 tail: None,
2369 capacity,
2370 size: 0,
2371 }
2372 }
2373
2374 pub fn get(&mut self, key: &K) -> Option<&V> {
2375 let node_ptr = *self.map.get(key)?;
2376 self.move_to_front(node_ptr);
2377 unsafe { Some(&(*node_ptr.as_ptr()).value) }
2378 }
2379
2380 pub fn put(&mut self, key: K, value: V) {
2381 if let Some(&node_ptr) = self.map.get(&key) {
2382 unsafe {
2383 (*node_ptr.as_ptr()).value = value;
2384 }
2385 self.move_to_front(node_ptr);
2386 return;
2387 }
2388
2389 let node = Box::new(Node {
2390 key: key.clone(),
2391 value,
2392 prev: None,
2393 next: self.head,
2394 });
2395 let node_ptr = NonNull::new(Box::into_raw(node)).unwrap();
2396
2397 if let Some(head) = self.head {
2398 unsafe {
2399 (*head.as_ptr()).prev = Some(node_ptr);
2400 }
2401 }
2402 self.head = Some(node_ptr);
2403 if self.tail.is_none() {
2404 self.tail = Some(node_ptr);
2405 }
2406
2407 self.map.insert(key, node_ptr);
2408 self.size += 1;
2409
2410 if self.size > self.capacity {
2411 self.evict_lru();
2412 }
2413 }
2414
2415 pub fn len(&self) -> usize {
2416 self.size
2417 }
2418
2419 fn move_to_front(&mut self, node_ptr: NonNull<Node<K, V>>) {
2420 if Some(node_ptr) == self.head {
2421 return;
2422 }
2423
2424 unsafe {
2425 let node = node_ptr.as_ptr();
2426
2427 if let Some(prev) = (*node).prev {
2428 (*prev.as_ptr()).next = (*node).next;
2429 }
2430 if let Some(next) = (*node).next {
2431 (*next.as_ptr()).prev = (*node).prev;
2432 }
2433 if Some(node_ptr) == self.tail {
2434 self.tail = (*node).prev;
2435 }
2436
2437 (*node).prev = None;
2438 (*node).next = self.head;
2439
2440 if let Some(head) = self.head {
2441 (*head.as_ptr()).prev = Some(node_ptr);
2442 }
2443 self.head = Some(node_ptr);
2444 }
2445 }
2446
2447 fn evict_lru(&mut self) {
2448 if let Some(tail_ptr) = self.tail {
2449 unsafe {
2450 let tail = tail_ptr.as_ptr();
2451 let key = (*tail).key.clone();
2452
2453 self.tail = (*tail).prev;
2454 if let Some(new_tail) = self.tail {
2455 (*new_tail.as_ptr()).next = None;
2456 } else {
2457 self.head = None;
2458 }
2459
2460 self.map.remove(&key);
2461 let _ = Box::from_raw(tail);
2462 self.size -= 1;
2463 }
2464 }
2465 }
2466 }
2467
2468 impl<K: Eq + core::hash::Hash + Clone, V> Drop for LruCache<K, V> {
2469 fn drop(&mut self) {
2470 let mut current = self.head;
2471 while let Some(node_ptr) = current {
2472 unsafe {
2473 let node = Box::from_raw(node_ptr.as_ptr());
2474 current = node.next;
2475 }
2476 }
2477 }
2478 }
2479}
2480
2481pub mod bitset {
2486 use super::*;
2487
2488 pub struct BitSet {
2489 bits: DynamicArray<u64>,
2490 size: usize,
2491 }
2492
2493 impl BitSet {
2494 pub fn new(size: usize) -> Self {
2495 let num_words = (size + 63) / 64;
2496 let mut bits = DynamicArray::with_capacity(num_words);
2497 for _ in 0..num_words {
2498 bits.push(0);
2499 }
2500 Self { bits, size }
2501 }
2502
2503 pub fn insert(&mut self, idx: usize) -> bool {
2504 if idx >= self.size {
2505 return false;
2506 }
2507 let word = idx / 64;
2508 let bit = idx % 64;
2509 let old = self.bits[word];
2510 self.bits[word] |= 1u64 << bit;
2511 old != self.bits[word]
2512 }
2513
2514 pub fn remove(&mut self, idx: usize) -> bool {
2515 if idx >= self.size {
2516 return false;
2517 }
2518 let word = idx / 64;
2519 let bit = idx % 64;
2520 let old = self.bits[word];
2521 self.bits[word] &= !(1u64 << bit);
2522 old != self.bits[word]
2523 }
2524
2525 pub fn contains(&self, idx: usize) -> bool {
2526 if idx >= self.size {
2527 return false;
2528 }
2529 let word = idx / 64;
2530 let bit = idx % 64;
2531 (self.bits[word] & (1u64 << bit)) != 0
2532 }
2533
2534 pub fn clear(&mut self) {
2535 for word in &mut self.bits {
2536 *word = 0;
2537 }
2538 }
2539
2540 pub fn count(&self) -> usize {
2541 self.bits.iter().map(|w| w.count_ones() as usize).sum()
2542 }
2543
2544 pub fn union(&mut self, other: &BitSet) {
2545 for (i, &word) in other.bits.iter().enumerate() {
2546 if i < self.bits.len() {
2547 self.bits[i] |= word;
2548 }
2549 }
2550 }
2551
2552 pub fn intersection(&mut self, other: &BitSet) {
2553 for (i, &word) in other.bits.iter().enumerate() {
2554 if i < self.bits.len() {
2555 self.bits[i] &= word;
2556 }
2557 }
2558 }
2559 }
2560}
2561
2562pub mod deque {
2567 use super::*;
2568
2569 pub struct Deque<T> {
2570 buffer: DynamicArray<Option<T>>,
2571 head: usize,
2572 tail: usize,
2573 len: usize,
2574 }
2575
2576 impl<T> Deque<T> {
2577 pub fn new() -> Self {
2578 Self::with_capacity(8)
2579 }
2580
2581 pub fn with_capacity(capacity: usize) -> Self {
2582 let cap = capacity.next_power_of_two();
2583 let mut buffer = DynamicArray::with_capacity(cap);
2584 for _ in 0..cap {
2585 buffer.push(None);
2586 }
2587 Self {
2588 buffer,
2589 head: 0,
2590 tail: 0,
2591 len: 0,
2592 }
2593 }
2594
2595 pub fn push_back(&mut self, item: T) {
2596 if self.len == self.buffer.len() {
2597 self.grow();
2598 }
2599 self.buffer[self.tail] = Some(item);
2600 self.tail = (self.tail + 1) & (self.buffer.len() - 1);
2601 self.len += 1;
2602 }
2603
2604 pub fn push_front(&mut self, item: T) {
2605 if self.len == self.buffer.len() {
2606 self.grow();
2607 }
2608 self.head = (self.head.wrapping_sub(1)) & (self.buffer.len() - 1);
2609 self.buffer[self.head] = Some(item);
2610 self.len += 1;
2611 }
2612
2613 pub fn pop_back(&mut self) -> Option<T> {
2614 if self.len == 0 {
2615 return None;
2616 }
2617 self.tail = (self.tail.wrapping_sub(1)) & (self.buffer.len() - 1);
2618 let item = self.buffer[self.tail].take();
2619 self.len -= 1;
2620 item
2621 }
2622
2623 pub fn pop_front(&mut self) -> Option<T> {
2624 if self.len == 0 {
2625 return None;
2626 }
2627 let item = self.buffer[self.head].take();
2628 self.head = (self.head + 1) & (self.buffer.len() - 1);
2629 self.len -= 1;
2630 item
2631 }
2632
2633 pub fn len(&self) -> usize {
2634 self.len
2635 }
2636
2637 pub fn is_empty(&self) -> bool {
2638 self.len == 0
2639 }
2640
2641 fn grow(&mut self) {
2642 let old_cap = self.buffer.len();
2643 let new_cap = old_cap * 2;
2644 let mut new_buffer = DynamicArray::with_capacity(new_cap);
2645 for _ in 0..new_cap {
2646 new_buffer.push(None);
2647 }
2648
2649 for i in 0..self.len {
2650 let idx = (self.head + i) & (old_cap - 1);
2651 new_buffer[i] = self.buffer[idx].take();
2652 }
2653
2654 self.buffer = new_buffer;
2655 self.head = 0;
2656 self.tail = self.len;
2657 }
2658 }
2659}
2660
2661pub mod sort {
2665 use super::*;
2666
2667 pub fn radix_sort_u32(arr: &mut [u32]) {
2669 if arr.len() <= 1 {
2670 return;
2671 }
2672
2673 let mut output = vec![0u32; arr.len()];
2674
2675 for shift in (0..32).step_by(8) {
2676 let mut count = [0usize; 256];
2677
2678 for &num in arr.iter() {
2680 let digit = ((num >> shift) & 0xFF) as usize;
2681 count[digit] += 1;
2682 }
2683
2684 for i in 1..256 {
2686 count[i] += count[i - 1];
2687 }
2688
2689 for &num in arr.iter().rev() {
2691 let digit = ((num >> shift) & 0xFF) as usize;
2692 count[digit] -= 1;
2693 output[count[digit]] = num;
2694 }
2695
2696 arr.copy_from_slice(&output);
2697 }
2698 }
2699
2700 pub fn counting_sort(arr: &mut [usize], max_val: usize) {
2702 if arr.len() <= 1 {
2703 return;
2704 }
2705
2706 let mut count = vec![0usize; max_val + 1];
2707
2708 for &num in arr.iter() {
2709 if num <= max_val {
2710 count[num] += 1;
2711 }
2712 }
2713
2714 let mut idx = 0;
2715 for (val, &cnt) in count.iter().enumerate() {
2716 for _ in 0..cnt {
2717 arr[idx] = val;
2718 idx += 1;
2719 }
2720 }
2721 }
2722
2723 pub fn quickselect<T: Ord>(arr: &mut [T], k: usize) -> Option<&T> {
2725 if k >= arr.len() {
2726 return None;
2727 }
2728
2729 let mut left = 0;
2730 let mut right = arr.len() - 1;
2731
2732 loop {
2733 if left == right {
2734 return Some(&arr[left]);
2735 }
2736
2737 let pivot = partition(arr, left, right);
2738
2739 if k == pivot {
2740 return Some(&arr[k]);
2741 } else if k < pivot {
2742 right = pivot - 1;
2743 } else {
2744 left = pivot + 1;
2745 }
2746 }
2747 }
2748
2749 fn partition<T: Ord>(arr: &mut [T], left: usize, right: usize) -> usize {
2750 let pivot_idx = left + (right - left) / 2;
2751 arr.swap(pivot_idx, right);
2752
2753 let mut store_idx = left;
2754 for i in left..right {
2755 if arr[i] < arr[right] {
2756 arr.swap(i, store_idx);
2757 store_idx += 1;
2758 }
2759 }
2760 arr.swap(store_idx, right);
2761 store_idx
2762 }
2763
2764 pub fn binary_search<T: Ord>(arr: &[T], target: &T) -> Result<usize, usize> {
2766 let mut left = 0;
2767 let mut right = arr.len();
2768
2769 while left < right {
2770 let mid = left + (right - left) / 2;
2771 match arr[mid].cmp(target) {
2772 core::cmp::Ordering::Less => left = mid + 1,
2773 core::cmp::Ordering::Equal => return Ok(mid),
2774 core::cmp::Ordering::Greater => right = mid,
2775 }
2776 }
2777 Err(left)
2778 }
2779}
2780
2781#[cfg(test)]
2782mod tests_v7 {
2783 use super::*;
2784
2785 #[test]
2786 fn test_min_heap() {
2787 use crate::heap::MinHeap;
2788
2789 let mut heap = MinHeap::new();
2790 heap.push(5);
2791 heap.push(2);
2792 heap.push(8);
2793 heap.push(1);
2794
2795 assert_eq!(heap.peek(), Some(&1));
2796 assert_eq!(heap.pop(), Some(1));
2797 assert_eq!(heap.pop(), Some(2));
2798 assert_eq!(heap.pop(), Some(5));
2799 assert_eq!(heap.pop(), Some(8));
2800 assert_eq!(heap.pop(), None);
2801 }
2802
2803 #[test]
2804 fn test_max_heap() {
2805 use crate::heap::MaxHeap;
2806
2807 let mut heap = MaxHeap::new();
2808 heap.push(5);
2809 heap.push(2);
2810 heap.push(8);
2811 heap.push(1);
2812
2813 assert_eq!(heap.peek(), Some(&8));
2814 assert_eq!(heap.pop(), Some(8));
2815 assert_eq!(heap.pop(), Some(5));
2816 assert_eq!(heap.len(), 2);
2817 }
2818
2819 #[test]
2820 fn test_union_find() {
2821 use crate::unionfind::UnionFind;
2822
2823 let mut uf = UnionFind::new(5);
2824 assert_eq!(uf.count(), 5);
2825
2826 uf.union(0, 1);
2827 uf.union(2, 3);
2828 assert_eq!(uf.count(), 3);
2829
2830 assert!(uf.connected(0, 1));
2831 assert!(!uf.connected(0, 2));
2832
2833 uf.union(1, 2);
2834 assert!(uf.connected(0, 3));
2835 assert_eq!(uf.count(), 2);
2836 }
2837
2838 #[test]
2839 fn test_lru_cache() {
2840 use crate::lru::LruCache;
2841
2842 let mut cache = LruCache::new(2);
2843 cache.put("a", 1);
2844 cache.put("b", 2);
2845
2846 assert_eq!(cache.get(&"a"), Some(&1));
2847
2848 cache.put("c", 3); assert_eq!(cache.get(&"b"), None);
2850 assert_eq!(cache.get(&"a"), Some(&1));
2851 assert_eq!(cache.get(&"c"), Some(&3));
2852 assert_eq!(cache.len(), 2);
2853 }
2854
2855 #[test]
2856 fn test_bitset() {
2857 use crate::bitset::BitSet;
2858
2859 let mut bs = BitSet::new(100);
2860 assert!(bs.insert(5));
2861 assert!(bs.insert(50));
2862 assert!(bs.insert(99));
2863
2864 assert!(bs.contains(5));
2865 assert!(bs.contains(50));
2866 assert!(!bs.contains(10));
2867
2868 assert_eq!(bs.count(), 3);
2869
2870 bs.remove(50);
2871 assert!(!bs.contains(50));
2872 assert_eq!(bs.count(), 2);
2873 }
2874
2875 #[test]
2876 fn test_deque() {
2877 use crate::deque::Deque;
2878
2879 let mut dq = Deque::new();
2880 dq.push_back(1);
2881 dq.push_back(2);
2882 dq.push_front(0);
2883
2884 assert_eq!(dq.len(), 3);
2885 assert_eq!(dq.pop_front(), Some(0));
2886 assert_eq!(dq.pop_back(), Some(2));
2887 assert_eq!(dq.pop_back(), Some(1));
2888 assert!(dq.is_empty());
2889 }
2890
2891 #[test]
2892 fn test_radix_sort() {
2893 use crate::sort::radix_sort_u32;
2894
2895 let mut arr = vec![170, 45, 75, 90, 802, 24, 2, 66];
2896 radix_sort_u32(&mut arr);
2897 assert_eq!(arr, vec![2, 24, 45, 66, 75, 90, 170, 802]);
2898 }
2899
2900 #[test]
2901 fn test_counting_sort() {
2902 use crate::sort::counting_sort;
2903
2904 let mut arr = vec![4, 2, 2, 8, 3, 3, 1];
2905 counting_sort(&mut arr, 10);
2906 assert_eq!(arr, vec![1, 2, 2, 3, 3, 4, 8]);
2907 }
2908
2909 #[test]
2910 fn test_quickselect() {
2911 use crate::sort::quickselect;
2912
2913 let mut arr = vec![3, 1, 4, 1, 5, 9, 2, 6];
2914 let third = quickselect(&mut arr, 2);
2915 assert!(third.is_some());
2916 }
2918
2919 #[test]
2920 fn test_binary_search() {
2921 use crate::sort::binary_search;
2922
2923 let arr = vec![1, 3, 5, 7, 9, 11];
2924 assert_eq!(binary_search(&arr, &5), Ok(2));
2925 assert_eq!(binary_search(&arr, &4), Err(2));
2926 }
2927}
2928
2929pub mod segtree {
2934 use super::*;
2935
2936 pub struct SegmentTree<T> {
2937 tree: DynamicArray<T>,
2938 size: usize,
2939 identity: T,
2940 }
2941
2942 impl<T: Clone + core::ops::Add<Output = T>> SegmentTree<T> {
2943 pub fn new(arr: &[T], identity: T) -> Self {
2944 let size = arr.len();
2945 let tree_size = size * 4;
2946 let mut tree = DynamicArray::with_capacity(tree_size);
2947 for _ in 0..tree_size {
2948 tree.push(identity.clone());
2949 }
2950
2951 let mut seg = Self { tree, size, identity };
2952 if size > 0 {
2953 seg.build(arr, 0, 0, size - 1);
2954 }
2955 seg
2956 }
2957
2958 fn build(&mut self, arr: &[T], node: usize, start: usize, end: usize) {
2959 if start == end {
2960 self.tree[node] = arr[start].clone();
2961 } else {
2962 let mid = (start + end) / 2;
2963 let left = 2 * node + 1;
2964 let right = 2 * node + 2;
2965
2966 self.build(arr, left, start, mid);
2967 self.build(arr, right, mid + 1, end);
2968
2969 self.tree[node] = self.tree[left].clone() + self.tree[right].clone();
2970 }
2971 }
2972
2973 pub fn query(&self, left: usize, right: usize) -> T {
2974 self.query_range(0, 0, self.size - 1, left, right)
2975 }
2976
2977 fn query_range(&self, node: usize, start: usize, end: usize, l: usize, r: usize) -> T {
2978 if r < start || l > end {
2979 return self.identity.clone();
2980 }
2981 if l <= start && end <= r {
2982 return self.tree[node].clone();
2983 }
2984
2985 let mid = (start + end) / 2;
2986 let left_child = 2 * node + 1;
2987 let right_child = 2 * node + 2;
2988
2989 let left_sum = self.query_range(left_child, start, mid, l, r);
2990 let right_sum = self.query_range(right_child, mid + 1, end, l, r);
2991
2992 left_sum + right_sum
2993 }
2994
2995 pub fn update(&mut self, idx: usize, value: T) {
2996 self.update_node(0, 0, self.size - 1, idx, value);
2997 }
2998
2999 fn update_node(&mut self, node: usize, start: usize, end: usize, idx: usize, value: T) {
3000 if start == end {
3001 self.tree[node] = value;
3002 } else {
3003 let mid = (start + end) / 2;
3004 let left = 2 * node + 1;
3005 let right = 2 * node + 2;
3006
3007 if idx <= mid {
3008 self.update_node(left, start, mid, idx, value);
3009 } else {
3010 self.update_node(right, mid + 1, end, idx, value);
3011 }
3012
3013 self.tree[node] = self.tree[left].clone() + self.tree[right].clone();
3014 }
3015 }
3016 }
3017}
3018
3019pub mod fenwick {
3024 use super::*;
3025
3026 pub struct FenwickTree {
3027 tree: DynamicArray<i64>,
3028 }
3029
3030 impl FenwickTree {
3031 pub fn new(size: usize) -> Self {
3032 let mut tree = DynamicArray::with_capacity(size + 1);
3033 for _ in 0..=size {
3034 tree.push(0);
3035 }
3036 Self { tree }
3037 }
3038
3039 pub fn update(&mut self, mut idx: usize, delta: i64) {
3040 idx += 1; while idx < self.tree.len() {
3042 self.tree[idx] += delta;
3043 idx += idx & (!idx + 1);
3044 }
3045 }
3046
3047 pub fn prefix_sum(&self, mut idx: usize) -> i64 {
3048 idx += 1; let mut sum = 0;
3050 while idx > 0 {
3051 sum += self.tree[idx];
3052 idx -= idx & (!idx + 1);
3053 }
3054 sum
3055 }
3056
3057 pub fn range_sum(&self, left: usize, right: usize) -> i64 {
3058 if left == 0 {
3059 self.prefix_sum(right)
3060 } else {
3061 self.prefix_sum(right) - self.prefix_sum(left - 1)
3062 }
3063 }
3064 }
3065}
3066
3067pub mod trie {
3072 use super::*;
3073
3074 const ALPHABET_SIZE: usize = 26;
3075
3076 struct TrieNode {
3077 children: [Option<Box<TrieNode>>; ALPHABET_SIZE],
3078 is_end: bool,
3079 }
3080
3081 impl TrieNode {
3082 fn new() -> Self {
3083 Self {
3084 children: core::array::from_fn(|_| None),
3085 is_end: false,
3086 }
3087 }
3088 }
3089
3090 pub struct Trie {
3091 root: TrieNode,
3092 }
3093
3094 impl Trie {
3095 pub fn new() -> Self {
3096 Self {
3097 root: TrieNode::new(),
3098 }
3099 }
3100
3101 pub fn insert(&mut self, word: &str) {
3102 let mut node = &mut self.root;
3103
3104 for ch in word.chars() {
3105 if let Some(idx) = Self::char_to_idx(ch) {
3106 node = node.children[idx].get_or_insert_with(|| Box::new(TrieNode::new()));
3107 }
3108 }
3109 node.is_end = true;
3110 }
3111
3112 pub fn search(&self, word: &str) -> bool {
3113 let mut node = &self.root;
3114
3115 for ch in word.chars() {
3116 if let Some(idx) = Self::char_to_idx(ch) {
3117 match &node.children[idx] {
3118 Some(child) => node = child,
3119 None => return false,
3120 }
3121 } else {
3122 return false;
3123 }
3124 }
3125 node.is_end
3126 }
3127
3128 pub fn starts_with(&self, prefix: &str) -> bool {
3129 let mut node = &self.root;
3130
3131 for ch in prefix.chars() {
3132 if let Some(idx) = Self::char_to_idx(ch) {
3133 match &node.children[idx] {
3134 Some(child) => node = child,
3135 None => return false,
3136 }
3137 } else {
3138 return false;
3139 }
3140 }
3141 true
3142 }
3143
3144 fn char_to_idx(ch: char) -> Option<usize> {
3145 if ch >= 'a' && ch <= 'z' {
3146 Some((ch as u8 - b'a') as usize)
3147 } else {
3148 None
3149 }
3150 }
3151 }
3152}
3153
3154pub mod mpmc {
3159 use super::*;
3160 use core::sync::atomic::{AtomicUsize, AtomicBool, Ordering};
3161 use core::cell::UnsafeCell;
3162
3163 pub struct MpmcQueue<T> {
3164 buffer: DynamicArray<UnsafeCell<Option<T>>>,
3165 capacity: usize,
3166 head: AtomicUsize,
3167 tail: AtomicUsize,
3168 }
3169
3170 unsafe impl<T: Send> Send for MpmcQueue<T> {}
3171 unsafe impl<T: Send> Sync for MpmcQueue<T> {}
3172
3173 impl<T> MpmcQueue<T> {
3174 pub fn new(capacity: usize) -> Self {
3175 let cap = capacity.next_power_of_two();
3176 let mut buffer = DynamicArray::with_capacity(cap);
3177 for _ in 0..cap {
3178 buffer.push(UnsafeCell::new(None));
3179 }
3180
3181 Self {
3182 buffer,
3183 capacity: cap,
3184 head: AtomicUsize::new(0),
3185 tail: AtomicUsize::new(0),
3186 }
3187 }
3188
3189 pub fn push(&self, item: T) -> Result<(), T> {
3190 loop {
3191 let tail = self.tail.load(Ordering::Acquire);
3192 let head = self.head.load(Ordering::Acquire);
3193
3194 if tail.wrapping_sub(head) >= self.capacity {
3195 return Err(item);
3196 }
3197
3198 let next_tail = tail.wrapping_add(1);
3199 if self.tail.compare_exchange(tail, next_tail, Ordering::AcqRel, Ordering::Acquire).is_ok() {
3200 let idx = tail & (self.capacity - 1);
3201 unsafe {
3202 *self.buffer[idx].get() = Some(item);
3203 }
3204 return Ok(());
3205 }
3206 }
3207 }
3208
3209 pub fn pop(&self) -> Option<T> {
3210 loop {
3211 let head = self.head.load(Ordering::Acquire);
3212 let tail = self.tail.load(Ordering::Acquire);
3213
3214 if head == tail {
3215 return None;
3216 }
3217
3218 let next_head = head.wrapping_add(1);
3219 if self.head.compare_exchange(head, next_head, Ordering::AcqRel, Ordering::Acquire).is_ok() {
3220 let idx = head & (self.capacity - 1);
3221 return unsafe { (*self.buffer[idx].get()).take() };
3222 }
3223 }
3224 }
3225
3226 pub fn len(&self) -> usize {
3227 let tail = self.tail.load(Ordering::Acquire);
3228 let head = self.head.load(Ordering::Acquire);
3229 tail.wrapping_sub(head)
3230 }
3231
3232 pub fn is_empty(&self) -> bool {
3233 self.len() == 0
3234 }
3235 }
3236}
3237
3238pub mod smallvec {
3243 use super::*;
3244
3245 pub struct SmallVec<T, const N: usize> {
3246 len: usize,
3247 data: SmallVecData<T, N>,
3248 }
3249
3250 enum SmallVecData<T, const N: usize> {
3251 Inline([core::mem::MaybeUninit<T>; N]),
3252 Heap(DynamicArray<T>),
3253 }
3254
3255 impl<T, const N: usize> SmallVec<T, N> {
3256 pub fn new() -> Self {
3257 Self {
3258 len: 0,
3259 data: SmallVecData::Inline(core::array::from_fn(|_| core::mem::MaybeUninit::uninit())),
3260 }
3261 }
3262
3263 pub fn push(&mut self, item: T) {
3264 match &mut self.data {
3265 SmallVecData::Inline(arr) if self.len < N => {
3266 arr[self.len] = core::mem::MaybeUninit::new(item);
3267 self.len += 1;
3268 }
3269 SmallVecData::Inline(arr) => {
3270 let mut vec = DynamicArray::with_capacity(N * 2);
3271 for i in 0..N {
3272 unsafe {
3273 vec.push(arr[i].assume_init_read());
3274 }
3275 }
3276 vec.push(item);
3277 self.data = SmallVecData::Heap(vec);
3278 self.len += 1;
3279 }
3280 SmallVecData::Heap(vec) => {
3281 vec.push(item);
3282 self.len += 1;
3283 }
3284 }
3285 }
3286
3287 pub fn pop(&mut self) -> Option<T> {
3288 if self.len == 0 {
3289 return None;
3290 }
3291
3292 self.len -= 1;
3293 match &mut self.data {
3294 SmallVecData::Inline(arr) => {
3295 Some(unsafe { arr[self.len].assume_init_read() })
3296 }
3297 SmallVecData::Heap(vec) => vec.pop(),
3298 }
3299 }
3300
3301 pub fn len(&self) -> usize {
3302 self.len
3303 }
3304
3305 pub fn capacity(&self) -> usize {
3306 match &self.data {
3307 SmallVecData::Inline(_) => N,
3308 SmallVecData::Heap(vec) => vec.capacity(),
3309 }
3310 }
3311 }
3312
3313 impl<T, const N: usize> Drop for SmallVec<T, N> {
3314 fn drop(&mut self) {
3315 match &mut self.data {
3316 SmallVecData::Inline(arr) => {
3317 for i in 0..self.len {
3318 unsafe {
3319 arr[i].assume_init_drop();
3320 }
3321 }
3322 }
3323 SmallVecData::Heap(_) => {}
3324 }
3325 }
3326 }
3327}
3328
3329pub mod sparseset {
3334 use super::*;
3335
3336 pub struct SparseSet {
3337 dense: DynamicArray<usize>,
3338 sparse: DynamicArray<usize>,
3339 size: usize,
3340 }
3341
3342 impl SparseSet {
3343 pub fn new(capacity: usize) -> Self {
3344 let mut sparse = DynamicArray::with_capacity(capacity);
3345 for _ in 0..capacity {
3346 sparse.push(0);
3347 }
3348
3349 Self {
3350 dense: DynamicArray::new(),
3351 sparse,
3352 size: 0,
3353 }
3354 }
3355
3356 pub fn insert(&mut self, value: usize) -> bool {
3357 if value >= self.sparse.len() {
3358 return false;
3359 }
3360
3361 if self.contains(value) {
3362 return false;
3363 }
3364
3365 self.sparse[value] = self.size;
3366 self.dense.push(value);
3367 self.size += 1;
3368 true
3369 }
3370
3371 pub fn remove(&mut self, value: usize) -> bool {
3372 if !self.contains(value) {
3373 return false;
3374 }
3375
3376 let idx = self.sparse[value];
3377 let last = self.dense[self.size - 1];
3378
3379 self.dense[idx] = last;
3380 self.sparse[last] = idx;
3381 self.size -= 1;
3382 true
3383 }
3384
3385 pub fn contains(&self, value: usize) -> bool {
3386 if value >= self.sparse.len() {
3387 return false;
3388 }
3389 let idx = self.sparse[value];
3390 idx < self.size && self.dense[idx] == value
3391 }
3392
3393 pub fn clear(&mut self) {
3394 self.size = 0;
3395 }
3396
3397 pub fn len(&self) -> usize {
3398 self.size
3399 }
3400
3401 pub fn iter(&self) -> core::slice::Iter<usize> {
3402 self.dense[..self.size].iter()
3403 }
3404 }
3405}
3406
3407#[cfg(test)]
3408mod tests_v7_part2 {
3409 use super::*;
3410
3411 #[test]
3412 fn test_segment_tree() {
3413 use crate::segtree::SegmentTree;
3414
3415 let arr = vec![1, 3, 5, 7, 9, 11];
3416 let mut tree = SegmentTree::new(&arr, 0);
3417
3418 assert_eq!(tree.query(1, 3), 15); tree.update(1, 10);
3421 assert_eq!(tree.query(1, 3), 22); }
3423
3424 #[test]
3425 fn test_fenwick_tree() {
3426 use crate::fenwick::FenwickTree;
3427
3428 let mut ft = FenwickTree::new(10);
3429 ft.update(0, 5);
3430 ft.update(1, 3);
3431 ft.update(2, 2);
3432
3433 assert_eq!(ft.prefix_sum(2), 10); assert_eq!(ft.range_sum(1, 2), 5); }
3436
3437 #[test]
3438 fn test_trie() {
3439 use crate::trie::Trie;
3440
3441 let mut trie = Trie::new();
3442 trie.insert("hello");
3443 trie.insert("world");
3444 trie.insert("help");
3445
3446 assert!(trie.search("hello"));
3447 assert!(trie.search("help"));
3448 assert!(!trie.search("hell"));
3449
3450 assert!(trie.starts_with("hel"));
3451 assert!(trie.starts_with("wor")); }
3453
3454 #[test]
3455 fn test_mpmc_queue() {
3456 use crate::mpmc::MpmcQueue;
3457
3458 let queue = MpmcQueue::new(8);
3459
3460 assert!(queue.push(1).is_ok());
3461 assert!(queue.push(2).is_ok());
3462 assert!(queue.push(3).is_ok());
3463
3464 assert_eq!(queue.len(), 3);
3465 assert_eq!(queue.pop(), Some(1));
3466 assert_eq!(queue.pop(), Some(2));
3467 assert_eq!(queue.len(), 1);
3468 }
3469
3470 #[test]
3471 fn test_small_vec() {
3472 use crate::smallvec::SmallVec;
3473
3474 let mut sv: SmallVec<i32, 4> = SmallVec::new();
3475
3476 sv.push(1);
3477 sv.push(2);
3478 sv.push(3);
3479 assert_eq!(sv.len(), 3);
3480 assert_eq!(sv.capacity(), 4); sv.push(4);
3483 sv.push(5); assert_eq!(sv.len(), 5);
3485
3486 assert_eq!(sv.pop(), Some(5));
3487 assert_eq!(sv.len(), 4);
3488 }
3489
3490 #[test]
3491 fn test_sparse_set() {
3492 use crate::sparseset::SparseSet;
3493
3494 let mut ss = SparseSet::new(100);
3495
3496 assert!(ss.insert(5));
3497 assert!(ss.insert(50));
3498 assert!(ss.insert(99));
3499
3500 assert!(ss.contains(5));
3501 assert!(ss.contains(50));
3502 assert!(!ss.contains(10));
3503
3504 assert_eq!(ss.len(), 3);
3505
3506 assert!(ss.remove(50));
3507 assert!(!ss.contains(50));
3508 assert_eq!(ss.len(), 2);
3509 }
3510}
3511
3512pub mod rbtree {
3517 use super::*;
3518
3519 #[derive(Clone, Copy, PartialEq)]
3520 enum Color {
3521 Red,
3522 Black,
3523 }
3524
3525 struct Node<K: Ord, V> {
3526 key: K,
3527 value: V,
3528 color: Color,
3529 left: Option<Box<Node<K, V>>>,
3530 right: Option<Box<Node<K, V>>>,
3531 }
3532
3533 pub struct RBTree<K: Ord, V> {
3534 root: Option<Box<Node<K, V>>>,
3535 size: usize,
3536 }
3537
3538 impl<K: Ord, V> RBTree<K, V> {
3539 pub fn new() -> Self {
3540 Self { root: None, size: 0 }
3541 }
3542
3543 pub fn insert(&mut self, key: K, value: V) {
3544 self.size += 1;
3546 if self.root.is_none() {
3547 self.root = Some(Box::new(Node {
3548 key,
3549 value,
3550 color: Color::Black,
3551 left: None,
3552 right: None,
3553 }));
3554 }
3555 }
3556
3557 pub fn get(&self, key: &K) -> Option<&V> {
3558 let mut node = &self.root;
3559
3560 while let Some(n) = node {
3561 match key.cmp(&n.key) {
3562 core::cmp::Ordering::Less => node = &n.left,
3563 core::cmp::Ordering::Equal => return Some(&n.value),
3564 core::cmp::Ordering::Greater => node = &n.right,
3565 }
3566 }
3567 None
3568 }
3569
3570 pub fn len(&self) -> usize {
3571 self.size
3572 }
3573 }
3574}
3575
3576pub mod matrix {
3581 use super::*;
3582
3583 pub struct Matrix<T> {
3584 data: DynamicArray<T>,
3585 rows: usize,
3586 cols: usize,
3587 }
3588
3589 impl<T: Clone + Default> Matrix<T> {
3590 pub fn new(rows: usize, cols: usize) -> Self {
3591 let mut data = DynamicArray::with_capacity(rows * cols);
3592 for _ in 0..rows * cols {
3593 data.push(T::default());
3594 }
3595 Self { data, rows, cols }
3596 }
3597
3598 pub fn get(&self, row: usize, col: usize) -> Option<&T> {
3599 if row < self.rows && col < self.cols {
3600 Some(&self.data[row * self.cols + col])
3601 } else {
3602 None
3603 }
3604 }
3605
3606 pub fn set(&mut self, row: usize, col: usize, value: T) -> bool {
3607 if row < self.rows && col < self.cols {
3608 self.data[row * self.cols + col] = value;
3609 true
3610 } else {
3611 false
3612 }
3613 }
3614
3615 pub fn rows(&self) -> usize {
3616 self.rows
3617 }
3618
3619 pub fn cols(&self) -> usize {
3620 self.cols
3621 }
3622 }
3623
3624 impl Matrix<f32> {
3625 pub fn multiply(&self, other: &Matrix<f32>) -> Option<Matrix<f32>> {
3626 if self.cols != other.rows {
3627 return None;
3628 }
3629
3630 let mut result = Matrix::new(self.rows, other.cols);
3631
3632 for i in 0..self.rows {
3633 for j in 0..other.cols {
3634 let mut sum = 0.0;
3635 for k in 0..self.cols {
3636 sum += self.get(i, k).unwrap() * other.get(k, j).unwrap();
3637 }
3638 result.set(i, j, sum);
3639 }
3640 }
3641
3642 Some(result)
3643 }
3644 }
3645}
3646
3647pub mod graph {
3652 use super::*;
3653
3654 pub struct Graph {
3655 adj: DynamicArray<DynamicArray<usize>>,
3656 vertex_count: usize,
3657 }
3658
3659 impl Graph {
3660 pub fn new(vertices: usize) -> Self {
3661 let mut adj = DynamicArray::with_capacity(vertices);
3662 for _ in 0..vertices {
3663 adj.push(DynamicArray::new());
3664 }
3665 Self {
3666 adj,
3667 vertex_count: vertices,
3668 }
3669 }
3670
3671 pub fn add_edge(&mut self, from: usize, to: usize) {
3672 if from < self.vertex_count {
3673 self.adj[from].push(to);
3674 }
3675 }
3676
3677 pub fn add_edge_undirected(&mut self, a: usize, b: usize) {
3678 self.add_edge(a, b);
3679 self.add_edge(b, a);
3680 }
3681
3682 pub fn neighbors(&self, vertex: usize) -> Option<&[usize]> {
3683 if vertex < self.vertex_count {
3684 Some(self.adj[vertex].as_slice())
3685 } else {
3686 None
3687 }
3688 }
3689
3690 pub fn dfs(&self, start: usize, visited: &mut [bool]) {
3691 if start >= self.vertex_count || visited[start] {
3692 return;
3693 }
3694
3695 visited[start] = true;
3696
3697 for &neighbor in self.adj[start].iter() {
3698 self.dfs(neighbor, visited);
3699 }
3700 }
3701
3702 pub fn vertex_count(&self) -> usize {
3703 self.vertex_count
3704 }
3705 }
3706}
3707
3708pub mod rope {
3713 use super::*;
3714
3715 const CHUNK_SIZE: usize = 64;
3716
3717 enum RopeNode {
3718 Leaf(StringBuffer),
3719 Branch {
3720 left: Box<RopeNode>,
3721 right: Box<RopeNode>,
3722 weight: usize,
3723 },
3724 }
3725
3726 pub struct Rope {
3727 root: RopeNode,
3728 }
3729
3730 impl Rope {
3731 pub fn new(s: &str) -> Self {
3732 Self {
3733 root: RopeNode::Leaf(StringBuffer::from(s)),
3734 }
3735 }
3736
3737 pub fn len(&self) -> usize {
3738 self.root.len()
3739 }
3740
3741 pub fn concat(left: Rope, right: Rope) -> Self {
3742 let weight = left.len();
3743 Self {
3744 root: RopeNode::Branch {
3745 left: Box::new(left.root),
3746 right: Box::new(right.root),
3747 weight,
3748 },
3749 }
3750 }
3751 }
3752
3753 impl RopeNode {
3754 fn len(&self) -> usize {
3755 match self {
3756 RopeNode::Leaf(s) => s.len(),
3757 RopeNode::Branch { weight, right, .. } => weight + right.len(),
3758 }
3759 }
3760 }
3761}
3762
3763pub mod slab {
3768 use super::*;
3769
3770 pub struct SlabAllocator<T> {
3771 blocks: DynamicArray<Option<T>>,
3772 free_list: DynamicArray<usize>,
3773 }
3774
3775 impl<T> SlabAllocator<T> {
3776 pub fn new(capacity: usize) -> Self {
3777 let mut blocks = DynamicArray::with_capacity(capacity);
3778 let mut free_list = DynamicArray::with_capacity(capacity);
3779
3780 for i in 0..capacity {
3781 blocks.push(None);
3782 free_list.push(i);
3783 }
3784
3785 Self { blocks, free_list }
3786 }
3787
3788 pub fn allocate(&mut self, value: T) -> Option<usize> {
3789 let idx = self.free_list.pop()?;
3790 self.blocks[idx] = Some(value);
3791 Some(idx)
3792 }
3793
3794 pub fn deallocate(&mut self, idx: usize) -> Option<T> {
3795 if idx >= self.blocks.len() {
3796 return None;
3797 }
3798 let value = self.blocks[idx].take()?;
3799 self.free_list.push(idx);
3800 Some(value)
3801 }
3802
3803 pub fn get(&self, idx: usize) -> Option<&T> {
3804 self.blocks.get(idx)?.as_ref()
3805 }
3806
3807 pub fn get_mut(&mut self, idx: usize) -> Option<&mut T> {
3808 self.blocks.get_mut(idx)?.as_mut()
3809 }
3810 }
3811}
3812
3813pub mod buddy {
3818 use super::*;
3819
3820 pub struct BuddyAllocator {
3821 memory: DynamicArray<u8>,
3822 free_lists: DynamicArray<DynamicArray<usize>>,
3823 min_block_size: usize,
3824 max_order: usize,
3825 }
3826
3827 impl BuddyAllocator {
3828 pub fn new(size: usize, min_block_size: usize) -> Self {
3829 let max_order = (size / min_block_size).trailing_zeros() as usize;
3830 let mut free_lists = DynamicArray::with_capacity(max_order + 1);
3831
3832 for _ in 0..=max_order {
3833 free_lists.push(DynamicArray::new());
3834 }
3835
3836 free_lists[max_order].push(0);
3838
3839 Self {
3840 memory: DynamicArray::with_capacity(size),
3841 free_lists,
3842 min_block_size,
3843 max_order,
3844 }
3845 }
3846
3847 pub fn allocate(&mut self, size: usize) -> Option<usize> {
3848 let order = self.size_to_order(size);
3849
3850 if order > self.max_order {
3851 return None;
3852 }
3853
3854 for o in order..=self.max_order {
3856 if !self.free_lists[o].is_empty() {
3857 let addr = self.free_lists[o].pop().unwrap();
3858
3859 for split_order in (order..o).rev() {
3861 let buddy = addr + (self.min_block_size << split_order);
3862 self.free_lists[split_order].push(buddy);
3863 }
3864
3865 return Some(addr);
3866 }
3867 }
3868
3869 None
3870 }
3871
3872 pub fn deallocate(&mut self, addr: usize, size: usize) {
3873 let mut order = self.size_to_order(size);
3874 let mut current_addr = addr;
3875
3876 while order < self.max_order {
3878 let buddy_addr = current_addr ^ (self.min_block_size << order);
3879
3880 if let Some(pos) = self.free_lists[order].iter().position(|&a| a == buddy_addr) {
3881 self.free_lists[order].swap_remove(pos);
3882 current_addr = current_addr.min(buddy_addr);
3883 order += 1;
3884 } else {
3885 break;
3886 }
3887 }
3888
3889 self.free_lists[order].push(current_addr);
3890 }
3891
3892 fn size_to_order(&self, size: usize) -> usize {
3893 let blocks = (size + self.min_block_size - 1) / self.min_block_size;
3894 blocks.next_power_of_two().trailing_zeros() as usize
3895 }
3896 }
3897}
3898
3899#[cfg(test)]
3900mod tests_v7_final {
3901 use super::*;
3902
3903 #[test]
3904 fn test_rbtree() {
3905 use crate::rbtree::RBTree;
3906
3907 let mut tree = RBTree::new();
3908 tree.insert(5, "five");
3909 tree.insert(3, "three");
3910 tree.insert(7, "seven");
3911
3912 assert_eq!(tree.get(&5), Some(&"five"));
3913 assert_eq!(tree.len(), 3);
3914 }
3915
3916 #[test]
3917 fn test_matrix() {
3918 use crate::matrix::Matrix;
3919
3920 let mut m = Matrix::new(2, 3);
3921 m.set(0, 0, 1);
3922 m.set(0, 1, 2);
3923 m.set(1, 2, 5);
3924
3925 assert_eq!(m.get(0, 0), Some(&1));
3926 assert_eq!(m.get(1, 2), Some(&5));
3927 assert_eq!(m.rows(), 2);
3928 assert_eq!(m.cols(), 3);
3929 }
3930
3931 #[test]
3932 fn test_matrix_multiply() {
3933 use crate::matrix::Matrix;
3934
3935 let mut a = Matrix::new(2, 2);
3936 a.set(0, 0, 1.0);
3937 a.set(0, 1, 2.0);
3938 a.set(1, 0, 3.0);
3939 a.set(1, 1, 4.0);
3940
3941 let mut b = Matrix::new(2, 2);
3942 b.set(0, 0, 2.0);
3943 b.set(0, 1, 0.0);
3944 b.set(1, 0, 1.0);
3945 b.set(1, 1, 2.0);
3946
3947 let c = a.multiply(&b).unwrap();
3948 assert_eq!(c.get(0, 0), Some(&4.0)); assert_eq!(c.get(0, 1), Some(&4.0)); }
3951
3952 #[test]
3953 fn test_graph() {
3954 use crate::graph::Graph;
3955
3956 let mut g = Graph::new(4);
3957 g.add_edge(0, 1);
3958 g.add_edge(0, 2);
3959 g.add_edge(1, 3);
3960
3961 assert_eq!(g.neighbors(0), Some(&[1, 2][..]));
3962 assert_eq!(g.vertex_count(), 4);
3963
3964 let mut visited = vec![false; 4];
3965 g.dfs(0, &mut visited);
3966 assert!(visited[0] && visited[1] && visited[2] && visited[3]);
3967 }
3968
3969 #[test]
3970 fn test_rope() {
3971 use crate::rope::Rope;
3972
3973 let r1 = Rope::new("Hello, ");
3974 let r2 = Rope::new("World!");
3975 let r3 = Rope::concat(r1, r2);
3976
3977 assert_eq!(r3.len(), 13);
3978 }
3979
3980 #[test]
3981 fn test_slab_allocator() {
3982 use crate::slab::SlabAllocator;
3983
3984 let mut slab = SlabAllocator::new(10);
3985
3986 let id1 = slab.allocate(100).unwrap();
3987 let id2 = slab.allocate(200).unwrap();
3988
3989 assert_eq!(slab.get(id1), Some(&100));
3990 assert_eq!(slab.get(id2), Some(&200));
3991
3992 assert_eq!(slab.deallocate(id1), Some(100));
3993
3994 let id3 = slab.allocate(300).unwrap();
3995 assert_eq!(id3, id1); }
3997
3998 #[test]
3999 fn test_buddy_allocator() {
4000 use crate::buddy::BuddyAllocator;
4001
4002 let mut buddy = BuddyAllocator::new(1024, 64);
4003
4004 let addr1 = buddy.allocate(100);
4005 assert!(addr1.is_some());
4006
4007 let addr2 = buddy.allocate(200);
4008 assert!(addr2.is_some());
4009
4010 if let Some(a) = addr1 {
4011 buddy.deallocate(a, 100);
4012 }
4013 }
4014}