1use crate::circuit::metadata::OperatorMeta;
30use crate::dynamic::{ClonableTrait, DynDataTyped, DynUnit, Weight};
31use crate::storage::buffer_cache::CacheStats;
32use crate::storage::file::SerializerInner;
33use crate::storage::file::TouchedWindowCount;
34pub use crate::storage::file::{DbspSerializer, Deserializable, Deserializer, Rkyv};
35use crate::storage::file::{FilterKind, FilterStats};
36use crate::trace::cursor::{
37 DefaultPushCursor, FilteredMergeCursor, FilteredMergeCursorWithSnapshot, PushCursor,
38 UnfilteredMergeCursor,
39};
40use crate::utils::{IsNone, SupportsRoaring};
41use crate::{dynamic::ArchivedDBData, storage::buffer_cache::FBuf};
42use cursor::CursorFactory;
43use enum_map::Enum;
44use feldera_storage::fbuf::FBufSerializer;
45use feldera_storage::{FileCommitter, FileReader, StoragePath};
46use rand::{Rng, thread_rng};
47use rkyv::ser::Serializer as _;
48use size_of::SizeOf;
49use std::any::TypeId;
50use std::future::Future;
51use std::sync::Arc;
52use std::{fmt::Debug, hash::Hash};
53
54pub mod cursor;
55pub mod filter;
56pub mod layers;
57pub mod ord;
58mod sampling;
59pub mod spine_async;
60pub(crate) use sampling::sample_keys_from_batches;
61pub use spine_async::{BatchReaderWithSnapshot, ListMerger, Spine, SpineSnapshot, WithSnapshot};
62
63#[cfg(test)]
64pub mod test;
65
66pub use ord::{
67 FallbackIndexedWSet, FallbackIndexedWSetBuilder, FallbackIndexedWSetFactories,
68 FallbackKeyBatch, FallbackKeyBatchFactories, FallbackValBatch, FallbackValBatchFactories,
69 FallbackWSet, FallbackWSetBuilder, FallbackWSetFactories, FileIndexedWSet,
70 FileIndexedWSetFactories, FileKeyBatch, FileKeyBatchFactories, FileValBatch,
71 FileValBatchFactories, FileWSet, FileWSetFactories, OrdIndexedWSet, OrdIndexedWSetBuilder,
72 OrdIndexedWSetFactories, OrdKeyBatch, OrdKeyBatchFactories, OrdValBatch, OrdValBatchFactories,
73 OrdWSet, OrdWSetBuilder, OrdWSetFactories, VecIndexedWSet, VecIndexedWSetFactories,
74 VecKeyBatch, VecKeyBatchFactories, VecValBatch, VecValBatchFactories, VecWSet,
75 VecWSetFactories,
76};
77
78use rkyv::bytecheck;
79use rkyv::{Deserialize, archived_root};
80
81use crate::{
82 Error, NumEntries, Timestamp,
83 algebra::MonoidValue,
84 dynamic::{DataTrait, DynPair, DynVec, DynWeightedPairs, Erase, Factory, WeightTrait},
85 storage::file::reader::Error as ReaderError,
86};
87pub use cursor::{Cursor, MergeCursor};
88pub use filter::{BatchFilterStats, BatchFilters, Filter, GroupFilter};
89pub use layers::Trie;
90
91pub trait DBData:
99 Default
100 + Clone
101 + Eq
102 + Ord
103 + Hash
104 + SizeOf
105 + Send
106 + Sync
107 + Debug
108 + ArchivedDBData
109 + IsNone<Inner: ArchivedDBData>
110 + SupportsRoaring
111 + 'static
112{
113}
114
115impl<T> DBData for T where
117 T: Default
118 + Clone
119 + Eq
120 + Ord
121 + Hash
122 + SizeOf
123 + Send
124 + Sync
125 + Debug
126 + ArchivedDBData
127 + IsNone<Inner: ArchivedDBData>
128 + SupportsRoaring
129 + 'static
130{
131}
132
133#[derive(rkyv::Serialize, rkyv::Deserialize, rkyv::Archive)]
135#[archive_attr(derive(rkyv::CheckBytes))]
136pub(crate) struct CommittedSpine {
137 pub batches: Vec<String>,
138 pub merged: Vec<(String, String)>,
139 pub effort: u64,
140 pub dirty: bool,
141}
142
143pub fn unaligned_deserialize<T: Deserializable>(bytes: &[u8]) -> T {
146 let mut aligned_bytes = FBuf::new();
147 aligned_bytes.extend_from_slice(bytes);
148 aligned_deserialize(&aligned_bytes)
149}
150
151pub fn aligned_deserialize<T: Deserializable>(bytes: &[u8]) -> T {
154 unsafe { archived_root::<T>(bytes) }
155 .deserialize(&mut Deserializer::default())
156 .unwrap()
157}
158
159pub trait DBWeight: DBData + MonoidValue {}
178impl<T> DBWeight for T where T: DBData + MonoidValue {}
179
180pub trait BatchReaderFactories<
181 K: DataTrait + ?Sized,
182 V: DataTrait + ?Sized,
183 T,
184 R: WeightTrait + ?Sized,
185>: Clone + Send + Sync
186{
187 fn new<KType, VType, RType>() -> Self
189 where
190 KType: DBData + Erase<K>,
191 VType: DBData + Erase<V>,
192 RType: DBWeight + Erase<R>;
193
194 fn key_factory(&self) -> &'static dyn Factory<K>;
195 fn keys_factory(&self) -> &'static dyn Factory<DynVec<K>>;
196 fn val_factory(&self) -> &'static dyn Factory<V>;
197 fn weight_factory(&self) -> &'static dyn Factory<R>;
198}
199
200pub type WeightedItem<K, V, R> = DynPair<DynPair<K, V>, R>;
202
203pub trait BatchFactories<K: DataTrait + ?Sized, V: DataTrait + ?Sized, T, R: WeightTrait + ?Sized>:
204 BatchReaderFactories<K, V, T, R>
205{
206 fn item_factory(&self) -> &'static dyn Factory<DynPair<K, V>>;
207
208 fn weighted_items_factory(&self) -> &'static dyn Factory<DynWeightedPairs<DynPair<K, V>, R>>;
209 fn weighted_vals_factory(&self) -> &'static dyn Factory<DynWeightedPairs<V, R>>;
210 fn weighted_item_factory(&self) -> &'static dyn Factory<WeightedItem<K, V, R>>;
211
212 fn time_diffs_factory(
214 &self,
215 ) -> Option<&'static dyn Factory<DynWeightedPairs<DynDataTyped<T>, R>>>;
216}
217
218pub trait Trace: BatchReader {
226 type Batch: Batch<
228 Key = Self::Key,
229 Val = Self::Val,
230 Time = Self::Time,
231 R = Self::R,
232 Factories = Self::Factories,
233 >;
234
235 fn new(factories: &Self::Factories, name: Arc<String>) -> Self;
238
239 fn set_name(&mut self, name: Arc<String>);
241
242 fn set_frontier(&mut self, frontier: &Self::Time);
251
252 fn exert(&mut self, effort: &mut isize);
254
255 fn consolidate(self) -> Option<Self::Batch>;
257
258 fn insert(&mut self, batch: impl Into<Arc<Self::Batch>>) -> impl Future<Output = ()>;
263
264 fn insert_without_blocking(&mut self, batch: impl Into<Arc<Self::Batch>>) -> bool;
273
274 fn backpressure_wait(&self) -> impl Future<Output = ()>;
277
278 fn clear_dirty_flag(&mut self);
286
287 fn dirty(&self) -> bool;
289
290 fn retain_keys(&mut self, filter: Filter<Self::Key>);
307
308 fn retain_values(&mut self, filter: GroupFilter<Self::Val>);
316
317 fn key_filter(&self) -> &Option<Filter<Self::Key>>;
318 fn value_filter(&self) -> &Option<GroupFilter<Self::Val>>;
319
320 fn save(
324 &mut self,
325 base: &StoragePath,
326 pid: &str,
327 files: &mut Vec<Arc<dyn FileCommitter>>,
328 ) -> Result<(), Error>;
329
330 fn restore(&mut self, base: &StoragePath, pid: &str) -> Result<(), Error>;
333
334 fn metadata(&self, _meta: &mut OperatorMeta) {}
336
337 fn initiate_compaction(&self);
338
339 fn is_compaction_complete(&self) -> bool;
343}
344
345#[derive(Copy, Clone, Debug, PartialEq, Eq, Enum)]
347pub enum BatchLocation {
348 Memory,
350
351 Storage,
353}
354
355pub trait BatchReader: Debug + NumEntries + Rkyv + SizeOf + 'static
380where
381 Self: Sized,
382{
383 type Factories: BatchFactories<Self::Key, Self::Val, Self::Time, Self::R>;
384
385 type Key: DataTrait + ?Sized;
387
388 type Val: DataTrait + ?Sized;
390
391 type Time: Timestamp;
393
394 type R: WeightTrait + ?Sized;
396
397 type Cursor<'s>: Cursor<Self::Key, Self::Val, Self::Time, Self::R> + Clone + Send
399 where
400 Self: 's;
401
402 fn factories(&self) -> Self::Factories;
405
406 fn cursor(&self) -> Self::Cursor<'_>;
408
409 fn push_cursor(
411 &self,
412 ) -> Box<dyn PushCursor<Self::Key, Self::Val, Self::Time, Self::R> + Send + '_> {
413 Box::new(DefaultPushCursor::new(self.cursor()))
414 }
415
416 fn merge_cursor(
418 &self,
419 key_filter: Option<Filter<Self::Key>>,
420 value_filter: Option<GroupFilter<Self::Val>>,
421 ) -> Box<dyn MergeCursor<Self::Key, Self::Val, Self::Time, Self::R> + Send + '_> {
422 if key_filter.is_none() && value_filter.is_none() {
423 Box::new(UnfilteredMergeCursor::new(self.cursor()))
424 } else if let Some(GroupFilter::Simple(filter)) = value_filter {
425 Box::new(FilteredMergeCursor::new(
426 self.cursor(),
427 key_filter,
428 Some(filter),
429 ))
430 } else {
431 Box::new(FilteredMergeCursor::new(self.cursor(), key_filter, None))
434 }
435 }
436
437 fn merge_cursor_with_snapshot<'a, S>(
440 &'a self,
441 key_filter: Option<Filter<Self::Key>>,
442 value_filter: Option<GroupFilter<Self::Val>>,
443 snapshot: &'a Option<Arc<S>>,
444 ) -> Box<dyn MergeCursor<Self::Key, Self::Val, Self::Time, Self::R> + Send + 'a>
445 where
446 S: BatchReader<Key = Self::Key, Val = Self::Val, Time = Self::Time, R = Self::R>,
447 {
448 let Some(snapshot) = snapshot else {
449 return self.merge_cursor(key_filter, value_filter);
450 };
451 if key_filter.is_none() && value_filter.is_none() {
452 Box::new(UnfilteredMergeCursor::new(self.cursor()))
453 } else if value_filter.is_none() {
454 Box::new(FilteredMergeCursor::new(self.cursor(), key_filter, None))
455 } else if let Some(GroupFilter::Simple(filter)) = value_filter {
456 Box::new(FilteredMergeCursor::new(
457 self.cursor(),
458 key_filter,
459 Some(filter),
460 ))
461 } else {
462 Box::new(FilteredMergeCursorWithSnapshot::new(
463 self.cursor(),
464 key_filter,
465 value_filter.unwrap(),
466 snapshot,
467 ))
468 }
469 }
470
471 fn consuming_cursor(
473 &mut self,
474 key_filter: Option<Filter<Self::Key>>,
475 value_filter: Option<GroupFilter<Self::Val>>,
476 ) -> Box<dyn MergeCursor<Self::Key, Self::Val, Self::Time, Self::R> + Send + '_> {
477 self.merge_cursor(key_filter, value_filter)
478 }
479 fn key_count(&self) -> usize;
487
488 fn len(&self) -> usize;
490
491 fn approximate_byte_size(&self) -> usize;
503
504 fn membership_filter_stats(&self) -> FilterStats {
510 FilterStats::default()
511 }
512
513 fn membership_filter_kind(&self) -> FilterKind {
516 FilterKind::None
517 }
518
519 fn range_filter_stats(&self) -> FilterStats {
525 FilterStats::default()
526 }
527
528 fn location(&self) -> BatchLocation {
530 BatchLocation::Memory
531 }
532
533 fn cache_stats(&self) -> CacheStats {
537 CacheStats::default()
538 }
539
540 fn is_empty(&self) -> bool {
542 self.len() == 0
543 }
544
545 fn sample_keys<RG>(&self, rng: &mut RG, sample_size: usize, sample: &mut DynVec<Self::Key>)
577 where
578 RG: Rng;
579
580 fn partition_keys(&self, num_partitions: usize, bounds: &mut DynVec<Self::Key>)
591 where
592 Self::Time: PartialEq<()>,
593 {
594 bounds.clear();
595 if num_partitions <= 1 {
596 return;
597 }
598
599 let sample_size = num_partitions * num_partitions;
600
601 let mut sample = self.factories().keys_factory().default_box();
602 self.sample_keys(&mut thread_rng(), sample_size, sample.as_mut());
603
604 let sample_len = sample.len();
606 if sample_len == 0 {
607 return;
608 }
609
610 if sample_len >= num_partitions {
611 for i in 0..num_partitions - 1 {
614 let idx = ((i + 1) * sample_len) / num_partitions;
615 let idx = idx.min(sample_len - 1);
616 bounds.push_ref(sample.index(idx));
617 }
618 } else {
619 for i in 0..sample_len {
621 bounds.push_ref(sample.index(i));
622 }
623 }
624 }
625
626 #[allow(async_fn_in_trait)]
652 async fn fetch<B>(
653 &self,
654 keys: &B,
655 ) -> Option<Box<dyn CursorFactory<Self::Key, Self::Val, Self::Time, Self::R>>>
656 where
657 B: BatchReader<Key = Self::Key, Time = ()>,
658 {
659 let _ = keys;
660 None
661 }
662
663 fn keys(&self) -> Option<&DynVec<Self::Key>> {
664 None
665 }
666}
667
668impl<B> BatchReader for Arc<B>
669where
670 B: BatchReader,
671{
672 type Factories = B::Factories;
673 type Key = B::Key;
674 type Val = B::Val;
675 type Time = B::Time;
676 type R = B::R;
677 type Cursor<'s> = B::Cursor<'s>;
678 fn factories(&self) -> Self::Factories {
679 (**self).factories()
680 }
681 fn cursor(&self) -> Self::Cursor<'_> {
682 (**self).cursor()
683 }
684 fn merge_cursor(
685 &self,
686 key_filter: Option<Filter<Self::Key>>,
687 value_filter: Option<GroupFilter<Self::Val>>,
688 ) -> Box<dyn MergeCursor<Self::Key, Self::Val, Self::Time, Self::R> + Send + '_> {
689 (**self).merge_cursor(key_filter, value_filter)
690 }
691 fn key_count(&self) -> usize {
692 (**self).key_count()
693 }
694 fn len(&self) -> usize {
695 (**self).len()
696 }
697 fn approximate_byte_size(&self) -> usize {
698 (**self).approximate_byte_size()
699 }
700 fn membership_filter_stats(&self) -> FilterStats {
701 (**self).membership_filter_stats()
702 }
703 fn membership_filter_kind(&self) -> FilterKind {
704 (**self).membership_filter_kind()
705 }
706 fn range_filter_stats(&self) -> FilterStats {
707 (**self).range_filter_stats()
708 }
709 fn location(&self) -> BatchLocation {
710 (**self).location()
711 }
712 fn cache_stats(&self) -> CacheStats {
713 (**self).cache_stats()
714 }
715 fn is_empty(&self) -> bool {
716 (**self).is_empty()
717 }
718 fn sample_keys<RG>(&self, rng: &mut RG, sample_size: usize, sample: &mut DynVec<Self::Key>)
719 where
720 RG: Rng,
721 {
722 (**self).sample_keys(rng, sample_size, sample)
723 }
724 fn consuming_cursor(
725 &mut self,
726 key_filter: Option<Filter<Self::Key>>,
727 value_filter: Option<GroupFilter<Self::Val>>,
728 ) -> Box<dyn MergeCursor<Self::Key, Self::Val, Self::Time, Self::R> + Send + '_> {
729 (**self).merge_cursor(key_filter, value_filter)
730 }
731 async fn fetch<KB>(
732 &self,
733 keys: &KB,
734 ) -> Option<Box<dyn CursorFactory<Self::Key, Self::Val, Self::Time, Self::R>>>
735 where
736 KB: BatchReader<Key = Self::Key, Time = ()>,
737 {
738 (**self).fetch(keys).await
739 }
740 fn keys(&self) -> Option<&DynVec<Self::Key>> {
741 (**self).keys()
742 }
743}
744
745pub trait Batch: BatchReader + Clone + Send + Sync
755where
756 Self: Sized,
757{
758 type Timed<T: Timestamp>: Batch<
760 Key = <Self as BatchReader>::Key,
761 Val = <Self as BatchReader>::Val,
762 Time = T,
763 R = <Self as BatchReader>::R,
764 >;
765
766 type Batcher: Batcher<Self>;
768
769 type Builder: Builder<Self>;
771
772 #[allow(clippy::type_complexity)]
774 fn dyn_from_tuples(
775 factories: &Self::Factories,
776 time: Self::Time,
777 tuples: &mut Box<DynWeightedPairs<DynPair<Self::Key, Self::Val>, Self::R>>,
778 ) -> Self {
779 let mut batcher = Self::Batcher::new_batcher(factories, time);
780 batcher.push_batch(tuples);
781 batcher.seal()
782 }
783
784 fn from_batch<BI>(batch: &BI, timestamp: &Self::Time, factories: &Self::Factories) -> Self
797 where
798 BI: BatchReader<Key = Self::Key, Val = Self::Val, Time = (), R = Self::R>,
799 {
800 if TypeId::of::<BI>() == TypeId::of::<Self>() {
804 unsafe { std::mem::transmute::<&BI, &Self>(batch).clone() }
805 } else {
806 Self::from_cursor(
807 batch.cursor(),
808 timestamp,
809 factories,
810 batch.key_count(),
811 batch.len(),
812 )
813 }
814 }
815
816 fn from_arc_batch<BI>(
818 batch: &Arc<BI>,
819 timestamp: &Self::Time,
820 factories: &Self::Factories,
821 ) -> Arc<Self>
822 where
823 BI: BatchReader<Key = Self::Key, Val = Self::Val, Time = (), R = Self::R>,
824 {
825 if TypeId::of::<BI>() == TypeId::of::<Self>() {
829 unsafe { std::mem::transmute::<&Arc<BI>, &Arc<Self>>(batch).clone() }
830 } else {
831 Arc::new(Self::from_cursor(
832 batch.cursor(),
833 timestamp,
834 factories,
835 batch.key_count(),
836 batch.len(),
837 ))
838 }
839 }
840
841 fn from_cursor<C>(
844 mut cursor: C,
845 timestamp: &Self::Time,
846 factories: &Self::Factories,
847 key_capacity: usize,
848 value_capacity: usize,
849 ) -> Self
850 where
851 C: Cursor<Self::Key, Self::Val, (), Self::R>,
852 {
853 let mut builder = Self::Builder::with_capacity(factories, key_capacity, value_capacity);
854 while cursor.key_valid() {
855 let mut any_values = false;
856 while cursor.val_valid() {
857 let weight = cursor.weight();
858 debug_assert!(!weight.is_zero());
859 builder.push_time_diff(timestamp, weight);
860 builder.push_val(cursor.val());
861 any_values = true;
862 cursor.step_val();
863 }
864 if any_values {
865 builder.push_key(cursor.key());
866 }
867 cursor.step_key();
868 }
869 builder.done()
870 }
871
872 fn dyn_empty(factories: &Self::Factories) -> Self {
874 Self::Builder::new_builder(factories).done()
875 }
876
877 fn filter(&self, predicate: &dyn Fn(&Self::Key, &Self::Val) -> bool) -> Self
879 where
880 Self::Time: PartialEq<()> + From<()>,
881 {
882 let factories = self.factories();
883 let mut builder = Self::Builder::new_builder(&factories);
884 let mut cursor = self.cursor();
885
886 while cursor.key_valid() {
887 let mut any_values = false;
888 while cursor.val_valid() {
889 if predicate(cursor.key(), cursor.val()) {
890 builder.push_diff(cursor.weight());
891 builder.push_val(cursor.val());
892 any_values = true;
893 }
894 cursor.step_val();
895 }
896 if any_values {
897 builder.push_key(cursor.key());
898 }
899 cursor.step_key();
900 }
901
902 builder.done()
903 }
904
905 fn persisted(&self) -> Option<Self> {
908 None
909 }
910
911 fn file_reader(&self) -> Option<Arc<dyn FileReader>> {
916 None
917 }
918
919 fn from_path(_factories: &Self::Factories, _path: &StoragePath) -> Result<Self, ReaderError> {
920 Err(ReaderError::Unsupported)
921 }
922
923 fn key_bounds(&self) -> Option<(&Self::Key, &Self::Key)>;
932
933 fn touched_window_count(&self) -> TouchedWindowCount;
945
946 fn negative_weight_count(&self) -> Option<u64>;
957}
958
959pub trait Batcher<Output>: SizeOf
961where
962 Output: Batch,
963{
964 fn new_batcher(vtables: &Output::Factories, time: Output::Time) -> Self;
967
968 fn push_batch(
970 &mut self,
971 batch: &mut Box<DynWeightedPairs<DynPair<Output::Key, Output::Val>, Output::R>>,
972 );
973
974 fn push_consolidated_batch(
979 &mut self,
980 batch: &mut Box<DynWeightedPairs<DynPair<Output::Key, Output::Val>, Output::R>>,
981 );
982
983 fn tuples(&self) -> usize;
985
986 fn seal(self) -> Output;
988}
989
990pub trait Builder<Output>: Send + SizeOf
1039where
1040 Self: Sized,
1041 Output: Batch,
1042{
1043 fn new_builder(factories: &Output::Factories) -> Self {
1045 Self::with_capacity(factories, 0, 0)
1046 }
1047
1048 fn with_capacity_in_location(
1056 factories: &Output::Factories,
1057 key_capacity: usize,
1058 value_capacity: usize,
1059 location: Option<BatchLocation>,
1060 ) -> Self;
1061
1062 fn with_capacity(
1066 factories: &Output::Factories,
1067 key_capacity: usize,
1068 value_capacity: usize,
1069 ) -> Self {
1070 Self::with_capacity_in_location(factories, key_capacity, value_capacity, None)
1071 }
1072
1073 fn for_merge<'a, B, I>(
1077 factories: &Output::Factories,
1078 batches: I,
1079 location: Option<BatchLocation>,
1080 ) -> Self
1081 where
1082 B: Batch<Key = Output::Key, Val = Output::Val, Time = Output::Time, R = Output::R>,
1083 I: IntoIterator<Item = &'a B> + Clone,
1084 {
1085 let key_capacity = batches.clone().into_iter().map(|b| b.key_count()).sum();
1086 let value_capacity = batches.into_iter().map(|b| b.len()).sum();
1087 Self::with_capacity_in_location(factories, key_capacity, value_capacity, location)
1088 }
1089
1090 fn push_time_diff(&mut self, time: &Output::Time, weight: &Output::R);
1092
1093 fn push_time_diff_mut(&mut self, time: &mut Output::Time, weight: &mut Output::R) {
1095 self.push_time_diff(time, weight);
1096 }
1097
1098 fn push_val(&mut self, val: &Output::Val);
1100
1101 fn push_val_mut(&mut self, val: &mut Output::Val) {
1103 self.push_val(val);
1104 }
1105
1106 fn push_key(&mut self, key: &Output::Key);
1108
1109 fn push_key_mut(&mut self, key: &mut Output::Key) {
1111 self.push_key(key);
1112 }
1113
1114 fn push_diff(&mut self, weight: &Output::R)
1116 where
1117 Output::Time: PartialEq<()>,
1118 {
1119 self.push_time_diff(&Output::Time::default(), weight);
1120 }
1121
1122 fn push_diff_mut(&mut self, weight: &mut Output::R)
1124 where
1125 Output::Time: PartialEq<()>,
1126 {
1127 self.push_diff(weight);
1128 }
1129
1130 fn push_val_diff(&mut self, val: &Output::Val, weight: &Output::R)
1132 where
1133 Output::Time: PartialEq<()>,
1134 {
1135 self.push_time_diff(&Output::Time::default(), weight);
1136 self.push_val(val);
1137 }
1138
1139 fn push_val_diff_mut(&mut self, val: &mut Output::Val, weight: &mut Output::R)
1141 where
1142 Output::Time: PartialEq<()>,
1143 {
1144 self.push_val_diff(val, weight);
1145 }
1146
1147 fn reserve(&mut self, additional: usize) {
1149 let _ = additional;
1150 }
1151
1152 fn num_keys(&self) -> usize;
1153 fn num_tuples(&self) -> usize;
1154
1155 fn done(self) -> Output;
1157}
1158
1159pub struct TupleBuilder<B, Output>
1163where
1164 B: Builder<Output>,
1165 Output: Batch,
1166{
1167 builder: B,
1168 kv: Box<DynPair<Output::Key, Output::Val>>,
1169 has_kv: bool,
1170}
1171
1172impl<B, Output> TupleBuilder<B, Output>
1173where
1174 B: Builder<Output>,
1175 Output: Batch,
1176{
1177 pub fn new(factories: &Output::Factories, builder: B) -> Self {
1178 Self {
1179 builder,
1180 kv: factories.item_factory().default_box(),
1181 has_kv: false,
1182 }
1183 }
1184
1185 pub fn num_keys(&self) -> usize {
1186 self.builder.num_keys()
1187 }
1188
1189 pub fn num_tuples(&self) -> usize {
1190 self.builder.num_tuples()
1191 }
1192
1193 pub fn push(&mut self, element: &mut DynPair<DynPair<Output::Key, Output::Val>, Output::R>)
1195 where
1196 Output::Time: PartialEq<()>,
1197 {
1198 let (kv, w) = element.split_mut();
1199 let (k, v) = kv.split_mut();
1200 self.push_vals(k, v, &mut Output::Time::default(), w);
1201 }
1202
1203 pub fn push_refs(
1205 &mut self,
1206 key: &Output::Key,
1207 val: &Output::Val,
1208 time: &Output::Time,
1209 weight: &Output::R,
1210 ) {
1211 if self.has_kv {
1212 let (k, v) = self.kv.split_mut();
1213 if k != key {
1214 self.builder.push_val_mut(v);
1215 self.builder.push_key_mut(k);
1216 self.kv.from_refs(key, val);
1217 } else if v != val {
1218 self.builder.push_val_mut(v);
1219 val.clone_to(v);
1220 }
1221 } else {
1222 self.has_kv = true;
1223 self.kv.from_refs(key, val);
1224 }
1225 self.builder.push_time_diff(time, weight);
1226 }
1227
1228 pub fn push_vals(
1230 &mut self,
1231 key: &mut Output::Key,
1232 val: &mut Output::Val,
1233 time: &mut Output::Time,
1234 weight: &mut Output::R,
1235 ) {
1236 if self.has_kv {
1237 let (k, v) = self.kv.split_mut();
1238 if k != key {
1239 self.builder.push_val_mut(v);
1240 self.builder.push_key_mut(k);
1241 self.kv.from_vals(key, val);
1242 } else if v != val {
1243 self.builder.push_val_mut(v);
1244 val.move_to(v);
1245 }
1246 } else {
1247 self.has_kv = true;
1248 self.kv.from_vals(key, val);
1249 }
1250 self.builder.push_time_diff_mut(time, weight);
1251 }
1252
1253 pub fn reserve(&mut self, additional: usize) {
1254 self.builder.reserve(additional)
1255 }
1256
1257 pub fn extend<'a, I>(&mut self, iter: I)
1259 where
1260 Output::Time: PartialEq<()>,
1261 I: Iterator<Item = &'a mut WeightedItem<Output::Key, Output::Val, Output::R>>,
1262 {
1263 let (lower, upper) = iter.size_hint();
1264 self.reserve(upper.unwrap_or(lower));
1265
1266 for item in iter {
1267 let (kv, w) = item.split_mut();
1268 let (k, v) = kv.split_mut();
1269
1270 self.push_vals(k, v, &mut Output::Time::default(), w);
1271 }
1272 }
1273
1274 pub fn done(mut self) -> Output {
1276 if self.has_kv {
1277 let (k, v) = self.kv.split_mut();
1278 self.builder.push_val_mut(v);
1279 self.builder.push_key_mut(k);
1280 }
1281 self.builder.done()
1282 }
1283}
1284
1285pub fn merge_batches<B, T>(
1293 factories: &B::Factories,
1294 batches: T,
1295 key_filter: &Option<Filter<B::Key>>,
1296 value_filter: &Option<GroupFilter<B::Val>>,
1297) -> B
1298where
1299 T: IntoIterator<Item = B>,
1300 B: Batch,
1301{
1302 let mut batches = batches
1304 .into_iter()
1305 .filter(|b| !b.is_empty())
1306 .collect::<Vec<_>>();
1307
1308 while batches.len() > 1 {
1313 let mut inputs = batches.split_off(batches.len().saturating_sub(64));
1314 let result: B = ListMerger::merge(
1315 factories,
1316 B::Builder::for_merge(factories, &inputs, Some(BatchLocation::Memory)),
1317 inputs
1318 .iter_mut()
1319 .map(|b| b.consuming_cursor(key_filter.clone(), value_filter.clone()))
1320 .collect(),
1321 );
1322 if !result.is_empty() {
1323 batches.push(result);
1324 }
1325 }
1326
1327 batches.pop().unwrap_or_else(|| B::dyn_empty(factories))
1330}
1331
1332pub fn merge_batches_by_reference<'a, B, T>(
1337 factories: &B::Factories,
1338 batches: T,
1339 key_filter: &Option<Filter<B::Key>>,
1340 value_filter: &Option<GroupFilter<B::Val>>,
1341) -> B
1342where
1343 T: IntoIterator<Item = &'a B>,
1344 B: Batch,
1345{
1346 let mut batches = batches
1348 .into_iter()
1349 .filter(|b| !b.is_empty())
1350 .collect::<Vec<_>>();
1351
1352 let mut outputs = Vec::with_capacity(batches.len().div_ceil(64));
1358 while !batches.is_empty() {
1359 let inputs = batches.split_off(batches.len().saturating_sub(64));
1360 let result: B = ListMerger::merge(
1361 factories,
1362 B::Builder::for_merge(
1363 factories,
1364 inputs.iter().cloned(),
1365 Some(BatchLocation::Memory),
1366 ),
1367 inputs
1368 .into_iter()
1369 .map(|b| b.merge_cursor(key_filter.clone(), value_filter.clone()))
1370 .collect(),
1371 );
1372 if !result.is_empty() {
1373 outputs.push(result);
1374 }
1375 }
1376
1377 merge_batches(factories, outputs, key_filter, value_filter)
1379}
1380
1381pub fn eq_batch<A, B, KA, VA, RA, KB, VB, RB>(a: &A, b: &B) -> bool
1389where
1390 A: BatchReader<Key = KA, Val = VA, Time = (), R = RA>,
1391 B: BatchReader<Key = KB, Val = VB, Time = (), R = RB>,
1392 KA: PartialEq<KB> + ?Sized,
1393 VA: PartialEq<VB> + ?Sized,
1394 RA: PartialEq<RB> + ?Sized,
1395 KB: ?Sized,
1396 VB: ?Sized,
1397 RB: ?Sized,
1398{
1399 let mut c1 = a.cursor();
1400 let mut c2 = b.cursor();
1401 while c1.key_valid() && c2.key_valid() {
1402 if c1.key() != c2.key() {
1403 return false;
1404 }
1405 while c1.val_valid() && c2.val_valid() {
1406 if c1.val() != c2.val() || c1.weight() != c2.weight() {
1407 return false;
1408 }
1409 c1.step_val();
1410 c2.step_val();
1411 }
1412 if c1.val_valid() || c2.val_valid() {
1413 return false;
1414 }
1415 c1.step_key();
1416 c2.step_key();
1417 }
1418 !c1.key_valid() && !c2.key_valid()
1419}
1420
1421fn serialize_wset<B, K, R>(batch: &B) -> Vec<u8>
1422where
1423 B: BatchReader<Key = K, Val = DynUnit, Time = (), R = R>,
1424 K: DataTrait + ?Sized,
1425 R: WeightTrait + ?Sized,
1426{
1427 SerializerInner::to_fbuf_with_thread_local(|s| {
1428 let mut offsets = Vec::with_capacity(2 * batch.len());
1429 let mut cursor = batch.cursor();
1430 while cursor.key_valid() {
1431 offsets.push(cursor.key().serialize(s)?);
1432 offsets.push(cursor.weight().serialize(s)?);
1433 cursor.step_key();
1434 }
1435 s.serialize_value(&offsets)
1436 })
1437 .into_vec()
1438}
1439
1440fn deserialize_wset<B, K, R>(factories: &B::Factories, data: &[u8]) -> B
1441where
1442 B: Batch<Key = K, Val = DynUnit, Time = (), R = R>,
1443 K: DataTrait + ?Sized,
1444 R: WeightTrait + ?Sized,
1445{
1446 let offsets = unsafe { archived_root::<Vec<usize>>(data) };
1447 assert!(offsets.len() % 2 == 0);
1448 let n = offsets.len() / 2;
1449 let mut builder = B::Builder::with_capacity(factories, n, n);
1450 let mut key = factories.key_factory().default_box();
1451 let mut diff = factories.weight_factory().default_box();
1452 for i in 0..n {
1453 unsafe { key.deserialize_from_bytes(data, offsets[i * 2] as usize) };
1454 unsafe { diff.deserialize_from_bytes(data, offsets[i * 2 + 1] as usize) };
1455 builder.push_val_diff(&(), &diff);
1456 builder.push_key(&key);
1457 }
1458 builder.done()
1459}
1460
1461const SEPARATOR: u64 = u64::MAX;
1463
1464#[cfg(debug_assertions)]
1465#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1466enum State {
1467 Key,
1468 Val,
1469 Diff,
1470}
1471
1472pub struct IndexedWSetSerializer {
1473 fbuf: FBuf,
1474 offsets: Vec<usize>,
1475 n_keys: usize,
1476 n_values: usize,
1477 #[cfg(debug_assertions)]
1478 state: State,
1479}
1480
1481impl IndexedWSetSerializer {
1482 pub fn with_capacity(estimated_keys: usize, estimated_values: usize) -> Self {
1483 let mut offsets = Vec::with_capacity(2 + 2 * estimated_keys + 2 * estimated_values);
1484 offsets.push(0);
1485 offsets.push(0);
1486 Self {
1487 fbuf: FBuf::new(),
1488 offsets,
1489 n_keys: 0,
1490 n_values: 0,
1491 #[cfg(debug_assertions)]
1492 state: State::Key,
1493 }
1494 }
1495
1496 pub fn push_diff<R: WeightTrait + ?Sized>(
1497 &mut self,
1498 weight: &R,
1499 serializer_inner: &mut SerializerInner,
1500 ) {
1501 #[cfg(debug_assertions)]
1502 {
1503 debug_assert_ne!(self.state, State::Diff);
1504 self.state = State::Diff;
1505 }
1506
1507 serializer_inner.with(FBufSerializer::new(&mut self.fbuf), |s| {
1508 self.offsets.push(weight.serialize(s).unwrap())
1509 });
1510 }
1511
1512 pub fn push_val<V: DataTrait + ?Sized>(
1513 &mut self,
1514 val: &V,
1515 serializer_inner: &mut SerializerInner,
1516 ) {
1517 #[cfg(debug_assertions)]
1518 {
1519 debug_assert_eq!(self.state, State::Diff);
1520 self.state = State::Val;
1521 }
1522
1523 self.n_values += 1;
1524 serializer_inner.with(FBufSerializer::new(&mut self.fbuf), |s| {
1525 self.offsets.push(val.serialize(s).unwrap())
1526 });
1527 }
1528
1529 pub fn push_key<K: DataTrait + ?Sized>(
1530 &mut self,
1531 key: &K,
1532 serializer_inner: &mut SerializerInner,
1533 ) {
1534 #[cfg(debug_assertions)]
1535 {
1536 debug_assert_eq!(self.state, State::Val);
1537 self.state = State::Key;
1538 }
1539
1540 self.offsets.push(SEPARATOR as usize);
1541 self.n_keys += 1;
1542 serializer_inner.with(FBufSerializer::new(&mut self.fbuf), |s| {
1543 self.offsets.push(key.serialize(s).unwrap())
1544 });
1545 }
1546
1547 pub fn done(mut self, serializer_inner: &mut SerializerInner) -> FBuf {
1548 #[cfg(debug_assertions)]
1549 debug_assert_eq!(self.state, State::Key);
1550 self.offsets[0] = self.n_keys;
1551 self.offsets[1] = self.n_values;
1552 serializer_inner.with(FBufSerializer::new(&mut self.fbuf), |s| {
1553 s.serialize_value(&self.offsets).unwrap()
1554 });
1555 self.fbuf
1556 }
1557}
1558
1559pub fn serialize_indexed_wset<B, K, V, R>(batch: &B, serializer_inner: &mut SerializerInner) -> FBuf
1560where
1561 B: BatchReader<Key = K, Val = V, Time = (), R = R>,
1562 K: DataTrait + ?Sized,
1563 V: DataTrait + ?Sized,
1564 R: WeightTrait + ?Sized,
1565{
1566 let mut serializer = IndexedWSetSerializer::with_capacity(batch.key_count(), batch.len());
1567 let mut cursor = batch.cursor();
1568
1569 while cursor.key_valid() {
1570 while cursor.val_valid() {
1571 serializer.push_diff(cursor.weight(), serializer_inner);
1572 serializer.push_val(cursor.val(), serializer_inner);
1573 cursor.step_val();
1574 }
1575 serializer.push_key(cursor.key(), serializer_inner);
1576 cursor.step_key();
1577 }
1578 serializer.done(serializer_inner)
1579}
1580
1581pub fn deserialize_indexed_wset<B, K, V, R>(factories: &B::Factories, data: &[u8]) -> B
1582where
1583 B: Batch<Key = K, Val = V, Time = (), R = R>,
1584 K: DataTrait + ?Sized,
1585 V: DataTrait + ?Sized,
1586 R: WeightTrait + ?Sized,
1587{
1588 let offsets = unsafe { archived_root::<Vec<usize>>(data) };
1589 let n_keys = offsets[0] as usize;
1590 let n_values = offsets[1] as usize;
1591
1592 let mut builder = B::Builder::with_capacity(factories, n_keys, n_values);
1593 let mut key = factories.key_factory().default_box();
1594 let mut val = factories.val_factory().default_box();
1595 let mut diff = factories.weight_factory().default_box();
1596
1597 let mut current_offset = 2;
1598
1599 while current_offset < offsets.len() {
1600 while offsets[current_offset] != SEPARATOR {
1601 unsafe { diff.deserialize_from_bytes(data, offsets[current_offset] as usize) };
1602 current_offset += 1;
1603 unsafe { val.deserialize_from_bytes(data, offsets[current_offset] as usize) };
1604 current_offset += 1;
1605
1606 builder.push_val_diff(&val, &diff);
1607 }
1608 current_offset += 1;
1609
1610 unsafe { key.deserialize_from_bytes(data, offsets[current_offset] as usize) };
1611 current_offset += 1;
1612
1613 builder.push_key(&key);
1614 }
1615 builder.done()
1616}
1617
1618#[cfg(test)]
1619mod serialize_test {
1620 use crate::{
1621 DynZWeight, OrdIndexedZSet,
1622 algebra::OrdIndexedZSet as DynOrdIndexedZSet,
1623 dynamic::DynData,
1624 indexed_zset,
1625 storage::file::SerializerInner,
1626 trace::{BatchReader, deserialize_indexed_wset, serialize_indexed_wset},
1627 };
1628
1629 #[test]
1630 fn test_serialize_indexed_wset() {
1631 let test1: OrdIndexedZSet<u64, u64> = indexed_zset! {};
1632 let test2 = indexed_zset! { 1 => { 1 => 1 } };
1633 let test3 =
1634 indexed_zset! { 1 => { 1 => 1, 2 => 2, 3 => 3 }, 2 => { 1 => 1, 2 => 2, 3 => 3 } };
1635
1636 for test in [test1, test2, test3] {
1637 let serialized = serialize_indexed_wset(&*test, &mut SerializerInner::new());
1638 let deserialized = deserialize_indexed_wset::<
1639 DynOrdIndexedZSet<DynData, DynData>,
1640 DynData,
1641 DynData,
1642 DynZWeight,
1643 >(&test.factories(), &serialized);
1644
1645 assert_eq!(&*test, &deserialized);
1646 }
1647 }
1648
1649 #[test]
1650 fn test_serialize_indexed_wset_tup0_key() {
1651 let test1: OrdIndexedZSet<(), u64> = indexed_zset! {};
1652 let test2 = indexed_zset! { () => { 1 => 1 } };
1653
1654 for test in [test1, test2] {
1655 let serialized = serialize_indexed_wset(&*test, &mut SerializerInner::new());
1656 let deserialized = deserialize_indexed_wset::<
1657 DynOrdIndexedZSet<DynData, DynData>,
1658 DynData,
1659 DynData,
1660 DynZWeight,
1661 >(&test.factories(), &serialized);
1662
1663 assert_eq!(&*test, &deserialized);
1664 }
1665 }
1666
1667 #[test]
1668 fn test_serialize_indexed_wset_tup0_val() {
1669 let test1: OrdIndexedZSet<u64, ()> = indexed_zset! {};
1670 let test2 = indexed_zset! { 1 => { () => 1 } };
1671 let test3 = indexed_zset! { 1 => { () => 1 }, 2 => { () => 1 } };
1672
1673 for test in [test1, test2, test3] {
1674 let serialized = serialize_indexed_wset(&*test, &mut SerializerInner::new());
1675 let deserialized = deserialize_indexed_wset::<
1676 DynOrdIndexedZSet<DynData, DynData>,
1677 DynData,
1678 DynData,
1679 DynZWeight,
1680 >(&test.factories(), &serialized);
1681
1682 assert_eq!(&*test, &deserialized);
1683 }
1684 }
1685}