1use crate::storage::file::{FilterStats, TouchedWindowCount};
2use crate::trace::BatchLocation;
3use crate::trace::ord::merge_batcher::MergeBatcher;
4use crate::{
5 DBData, DBWeight, NumEntries, Timestamp,
6 dynamic::{
7 DataTrait, DynDataTyped, DynPair, DynUnit, DynVec, DynWeightedPairs, Erase, Factory,
8 LeanVec, WeightTrait, WithFactory,
9 },
10 trace::{
11 Batch, BatchFactories, BatchReader, BatchReaderFactories, Builder, Cursor, DbspSerializer,
12 Deserializer, WeightedItem,
13 cursor::Position,
14 layers::{
15 Cursor as TrieCursor, Layer, LayerCursor, LayerFactories, Leaf, LeafFactories,
16 OrdOffset, Trie,
17 },
18 },
19 utils::{ConsolidatePairedSlices, Tup2},
20};
21use feldera_storage::FileReader;
22use rand::Rng;
23use rkyv::{Archive, Deserialize, Serialize};
24use size_of::SizeOf;
25use std::any::TypeId;
26use std::{
27 fmt::{self, Debug, Display},
28 sync::Arc,
29};
30
31pub struct VecKeyBatchFactories<K, T, R>
32where
33 K: DataTrait + ?Sized,
34 T: Timestamp,
35 R: WeightTrait + ?Sized,
36{
37 layer_factories: LayerFactories<K, LeafFactories<DynDataTyped<T>, R>>,
38 consolidate_weights: &'static dyn ConsolidatePairedSlices<DynDataTyped<T>, R>,
39 item_factory: &'static dyn Factory<DynPair<K, DynUnit>>,
40 weighted_item_factory: &'static dyn Factory<WeightedItem<K, DynUnit, R>>,
41 weighted_items_factory: &'static dyn Factory<DynWeightedPairs<DynPair<K, DynUnit>, R>>,
42 weighted_vals_factory: &'static dyn Factory<DynWeightedPairs<DynUnit, R>>,
43 time_diffs_factory: &'static dyn Factory<DynWeightedPairs<DynDataTyped<T>, R>>,
44}
45
46unsafe impl<K, T, R> Send for VecKeyBatchFactories<K, T, R>
47where
48 K: DataTrait + ?Sized,
49 T: Timestamp,
50 R: WeightTrait + ?Sized,
51{
52}
53
54impl<K, T, R> Clone for VecKeyBatchFactories<K, T, R>
55where
56 K: DataTrait + ?Sized,
57 T: Timestamp,
58 R: WeightTrait + ?Sized,
59{
60 fn clone(&self) -> Self {
61 Self {
62 layer_factories: self.layer_factories.clone(),
63 consolidate_weights: self.consolidate_weights,
64 item_factory: self.item_factory,
65 weighted_item_factory: self.weighted_item_factory,
66 weighted_items_factory: self.weighted_items_factory,
67 weighted_vals_factory: self.weighted_vals_factory,
68 time_diffs_factory: self.time_diffs_factory,
69 }
70 }
71}
72
73impl<K, T, R> BatchReaderFactories<K, DynUnit, T, R> for VecKeyBatchFactories<K, T, R>
74where
75 K: DataTrait + ?Sized,
76 T: Timestamp,
77 R: WeightTrait + ?Sized,
78{
79 fn new<KType, VType, RType>() -> Self
80 where
81 KType: DBData + Erase<K>,
82 VType: DBData + Erase<DynUnit>,
83 RType: DBWeight + Erase<R>,
84 {
85 Self {
86 layer_factories: LayerFactories::new::<KType>(
87 <LeafFactories<DynDataTyped<T>, R>>::new::<T, RType>(),
88 ),
89 consolidate_weights: <dyn ConsolidatePairedSlices<_, _>>::factory::<T, RType>(),
90 item_factory: WithFactory::<Tup2<KType, ()>>::FACTORY,
91 weighted_item_factory: WithFactory::<Tup2<Tup2<KType, ()>, RType>>::FACTORY,
92 weighted_items_factory: WithFactory::<LeanVec<Tup2<Tup2<KType, ()>, RType>>>::FACTORY,
93 weighted_vals_factory: WithFactory::<LeanVec<Tup2<(), RType>>>::FACTORY,
94 time_diffs_factory: WithFactory::<LeanVec<Tup2<T, RType>>>::FACTORY,
95 }
96 }
97
98 fn key_factory(&self) -> &'static dyn Factory<K> {
99 self.layer_factories.key
100 }
101
102 fn keys_factory(&self) -> &'static dyn Factory<DynVec<K>> {
103 self.layer_factories.keys
104 }
105
106 fn val_factory(&self) -> &'static dyn Factory<DynUnit> {
107 WithFactory::<()>::FACTORY
108 }
109
110 fn weight_factory(&self) -> &'static dyn Factory<R> {
111 self.layer_factories.child.diff
112 }
113}
114
115impl<K, R, T> BatchFactories<K, DynUnit, T, R> for VecKeyBatchFactories<K, T, R>
116where
117 K: DataTrait + ?Sized,
118 T: Timestamp,
119 R: WeightTrait + ?Sized,
120{
121 fn item_factory(&self) -> &'static dyn Factory<DynPair<K, DynUnit>> {
124 self.item_factory
125 }
126
127 fn weighted_item_factory(&self) -> &'static dyn Factory<WeightedItem<K, DynUnit, R>> {
128 self.weighted_item_factory
129 }
130
131 fn weighted_items_factory(
132 &self,
133 ) -> &'static dyn Factory<DynWeightedPairs<DynPair<K, DynUnit>, R>> {
134 self.weighted_items_factory
135 }
136
137 fn weighted_vals_factory(&self) -> &'static dyn Factory<DynWeightedPairs<DynUnit, R>> {
138 self.weighted_vals_factory
139 }
140
141 fn time_diffs_factory(
142 &self,
143 ) -> Option<&'static dyn Factory<DynWeightedPairs<DynDataTyped<T>, R>>> {
144 Some(self.time_diffs_factory)
145 }
146}
147
148pub type VecKeyBatchLayer<K, T, R, O> = Layer<K, Leaf<DynDataTyped<T>, R>, O>;
149
150pub struct VecKeyBatch<K, T, R, O = usize>
153where
154 K: DataTrait + ?Sized,
155 T: Timestamp,
156 R: WeightTrait + ?Sized,
157 O: OrdOffset,
158{
159 pub layer: VecKeyBatchLayer<K, T, R, O>,
161 factories: VecKeyBatchFactories<K, T, R>,
162 touched_window_count: TouchedWindowCount,
163}
164
165impl<K, T, R, O> SizeOf for VecKeyBatch<K, T, R, O>
166where
167 K: DataTrait + ?Sized,
168 R: WeightTrait + ?Sized,
169 T: Timestamp,
170 O: OrdOffset,
171{
172 fn size_of_children(&self, context: &mut size_of::Context) {
173 context.add(self.approximate_byte_size());
176 }
177}
178
179impl<K, T, R, O> Debug for VecKeyBatch<K, T, R, O>
180where
181 K: DataTrait + ?Sized,
182 R: WeightTrait + ?Sized,
183 T: Timestamp,
184 O: OrdOffset,
185{
186 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
187 f.debug_struct("VecKeyBatch")
188 .field("layer", &self.layer)
189 .finish()
190 }
191}
192
193impl<K, T, R, O: OrdOffset> Deserialize<VecKeyBatch<K, T, R, O>, Deserializer> for ()
194where
195 K: DataTrait + ?Sized,
196 T: Timestamp,
197 R: WeightTrait + ?Sized,
198 O: OrdOffset,
199{
200 fn deserialize(
201 &self,
202 _deserializer: &mut Deserializer,
203 ) -> Result<VecKeyBatch<K, T, R, O>, <Deserializer as rkyv::Fallible>::Error> {
204 todo!()
205 }
206}
207
208impl<K, T, R, O> Archive for VecKeyBatch<K, T, R, O>
209where
210 K: DataTrait + ?Sized,
211 T: Timestamp,
212 R: WeightTrait + ?Sized,
213 O: OrdOffset,
214{
215 type Archived = ();
216 type Resolver = ();
217
218 unsafe fn resolve(&self, _pos: usize, _resolver: Self::Resolver, _out: *mut Self::Archived) {
219 todo!()
220 }
221}
222impl<K, T, R, O: OrdOffset> Serialize<DbspSerializer<'_>> for VecKeyBatch<K, T, R, O>
223where
224 K: DataTrait + ?Sized,
225 T: Timestamp,
226 R: WeightTrait + ?Sized,
227 O: OrdOffset,
228{
229 fn serialize(
230 &self,
231 _serializer: &mut DbspSerializer,
232 ) -> Result<Self::Resolver, <DbspSerializer<'_> as rkyv::Fallible>::Error> {
233 todo!()
234 }
235}
236
237impl<K, T, R, O> Clone for VecKeyBatch<K, T, R, O>
238where
239 K: DataTrait + ?Sized,
240 T: Timestamp,
241 R: WeightTrait + ?Sized,
242 O: OrdOffset,
243{
244 fn clone(&self) -> Self {
245 Self {
246 layer: self.layer.clone(),
247 factories: self.factories.clone(),
248 touched_window_count: self.touched_window_count,
249 }
250 }
251}
252
253impl<K, T, R, O> Display for VecKeyBatch<K, T, R, O>
254where
255 K: DataTrait + ?Sized,
256 T: Timestamp,
257 R: WeightTrait + ?Sized,
258 O: OrdOffset,
259{
260 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
261 writeln!(
262 f,
263 "layer:\n{}",
264 textwrap::indent(&self.layer.to_string(), " ")
265 )
266 }
267}
268
269impl<K, T, R, O> NumEntries for VecKeyBatch<K, T, R, O>
270where
271 K: DataTrait + ?Sized,
272 T: Timestamp,
273 R: WeightTrait + ?Sized,
274 O: OrdOffset,
275{
276 const CONST_NUM_ENTRIES: Option<usize> = <VecKeyBatchLayer<K, T, R, O>>::CONST_NUM_ENTRIES;
277
278 #[inline]
279 fn num_entries_shallow(&self) -> usize {
280 self.layer.num_entries_shallow()
281 }
282
283 #[inline]
284 fn num_entries_deep(&self) -> usize {
285 self.layer.num_entries_deep()
286 }
287}
288
289impl<K, T, R, O> BatchReader for VecKeyBatch<K, T, R, O>
290where
291 K: DataTrait + ?Sized,
292 T: Timestamp,
293 R: WeightTrait + ?Sized,
294 O: OrdOffset,
295{
296 type Key = K;
297 type Val = DynUnit;
298 type Time = T;
299 type R = R;
300 type Cursor<'s>
301 = ValKeyCursor<'s, K, T, R, O>
302 where
303 O: 's;
304 type Factories = VecKeyBatchFactories<K, T, R>;
305 fn factories(&self) -> Self::Factories {
308 self.factories.clone()
309 }
310
311 fn cursor(&self) -> Self::Cursor<'_> {
312 ValKeyCursor {
313 valid: true,
314 cursor: self.layer.cursor(),
315 }
316 }
317
318 fn key_count(&self) -> usize {
323 <VecKeyBatchLayer<K, T, R, O> as Trie>::keys(&self.layer)
324 }
325
326 fn len(&self) -> usize {
327 <VecKeyBatchLayer<K, T, R, O> as Trie>::tuples(&self.layer)
328 }
329
330 fn approximate_byte_size(&self) -> usize {
331 self.layer.approximate_byte_size()
332 }
333
334 fn membership_filter_stats(&self) -> FilterStats {
335 FilterStats::default()
336 }
337
338 fn sample_keys<RG>(&self, rng: &mut RG, sample_size: usize, sample: &mut DynVec<Self::Key>)
339 where
340 RG: Rng,
341 {
342 self.layer.sample_keys(rng, sample_size, sample);
343 }
344}
345
346impl<K, T, R, O> Batch for VecKeyBatch<K, T, R, O>
347where
348 K: DataTrait + ?Sized,
349 T: Timestamp,
350 R: WeightTrait + ?Sized,
351 O: OrdOffset,
352{
353 type Timed<T2: Timestamp> = VecKeyBatch<K, T2, R, O>;
354 type Batcher = MergeBatcher<Self>;
355 type Builder = VecKeyBuilder<K, T, R, O>;
356 fn file_reader(&self) -> Option<Arc<dyn FileReader>> {
357 unimplemented!()
358 }
359
360 fn key_bounds(&self) -> Option<(&Self::Key, &Self::Key)> {
361 Some((self.layer.keys.first()?, self.layer.keys.last()?))
362 }
363
364 fn negative_weight_count(&self) -> Option<u64> {
365 None
366 }
367
368 fn touched_window_count(&self) -> TouchedWindowCount {
369 self.touched_window_count
370 }
371}
372
373#[derive(Debug, SizeOf)]
375pub struct ValKeyCursor<'s, K, T, R, O = usize>
376where
377 K: DataTrait + ?Sized,
378 T: Timestamp,
379 R: WeightTrait + ?Sized,
380 O: OrdOffset,
381{
382 valid: bool,
383 cursor: LayerCursor<'s, K, Leaf<DynDataTyped<T>, R>, O>,
384}
385
386impl<K, T, R, O> Clone for ValKeyCursor<'_, K, T, R, O>
387where
388 K: DataTrait + ?Sized,
389 T: Timestamp,
390 R: WeightTrait + ?Sized,
391 O: OrdOffset,
392{
393 fn clone(&self) -> Self {
394 Self {
395 valid: self.valid,
396 cursor: self.cursor.clone(),
397 }
398 }
399}
400
401impl<K, T, R, O> Cursor<K, DynUnit, T, R> for ValKeyCursor<'_, K, T, R, O>
402where
403 K: DataTrait + ?Sized,
404 T: Timestamp,
405 R: WeightTrait + ?Sized,
406 O: OrdOffset,
407{
408 fn weight_factory(&self) -> &'static dyn Factory<R> {
417 self.cursor.child.storage.factories.diff
418 }
419
420 fn key(&self) -> &K {
421 self.cursor.item()
422 }
423
424 fn val(&self) -> &DynUnit {
425 &()
426 }
427
428 fn map_times(&mut self, logic: &mut dyn FnMut(&T, &R)) {
429 self.cursor.child.rewind();
430 while self.cursor.child.valid() {
431 logic(
432 self.cursor.child.current_key(),
433 self.cursor.child.current_diff(),
434 );
435 self.cursor.child.step();
436 }
437 }
438
439 fn map_times_through(&mut self, upper: &T, logic: &mut dyn FnMut(&T, &R)) {
440 self.cursor.child.rewind();
441 while self.cursor.child.valid() {
442 if self.cursor.child.item().0.less_equal(upper) {
443 logic(
444 self.cursor.child.current_key(),
445 self.cursor.child.current_diff(),
446 );
447 }
448 self.cursor.child.step();
449 }
450 }
451
452 fn weight(&mut self) -> &R
453 where
454 T: PartialEq<()>,
455 {
456 self.weight_checked()
457 }
458
459 fn weight_checked(&mut self) -> &R {
460 if TypeId::of::<T>() == TypeId::of::<()>() {
461 debug_assert!(&self.cursor.child.valid());
462 self.cursor.child.current_diff()
463 } else {
464 panic!("VecKeyCursor::weight_checked called on non-unit timestamp type");
465 }
466 }
467
468 fn map_values(&mut self, logic: &mut dyn FnMut(&DynUnit, &R))
469 where
470 T: PartialEq<()>,
471 {
472 if self.val_valid() {
473 logic(self.val(), self.cursor.child.current_diff());
474 }
475 }
476
477 fn key_valid(&self) -> bool {
478 self.cursor.valid()
479 }
480
481 fn val_valid(&self) -> bool {
482 self.valid
483 }
484
485 fn step_key(&mut self) {
486 self.cursor.step();
487 self.valid = true;
488 }
489
490 fn step_key_reverse(&mut self) {
491 self.cursor.step_reverse();
492 self.valid = true;
493 }
494
495 fn seek_key(&mut self, key: &K) {
496 self.cursor.seek(key);
497 self.valid = true;
498 }
499
500 fn seek_key_exact(&mut self, key: &K, _hash: Option<u64>) -> bool {
501 self.seek_key(key);
502 self.key_valid() && self.key().eq(key)
503 }
504
505 fn seek_key_with(&mut self, predicate: &dyn Fn(&K) -> bool) {
506 self.cursor.seek_with(predicate);
507 self.valid = true;
508 }
509
510 fn seek_key_with_reverse(&mut self, predicate: &dyn Fn(&K) -> bool) {
511 self.cursor.seek_with_reverse(predicate);
512 self.valid = true;
513 }
514
515 fn seek_key_reverse(&mut self, key: &K) {
516 self.cursor.seek_reverse(key);
517 self.valid = true;
518 }
519
520 fn step_val(&mut self) {
521 self.valid = false;
522 }
523
524 fn seek_val(&mut self, _val: &DynUnit) {}
525
526 fn seek_val_with(&mut self, predicate: &dyn Fn(&DynUnit) -> bool) {
527 if !predicate(&()) {
528 self.valid = false;
529 }
530 }
531
532 fn rewind_keys(&mut self) {
533 self.cursor.rewind();
534 self.valid = true;
535 }
536
537 fn fast_forward_keys(&mut self) {
538 self.cursor.fast_forward();
539 self.valid = true;
540 }
541
542 fn rewind_vals(&mut self) {
543 self.valid = true;
544 }
545
546 fn step_val_reverse(&mut self) {
547 self.valid = false;
548 }
549
550 fn seek_val_reverse(&mut self, _val: &DynUnit) {}
551
552 fn seek_val_with_reverse(&mut self, predicate: &dyn Fn(&DynUnit) -> bool) {
553 if !predicate(&()) {
554 self.valid = false;
555 }
556 }
557
558 fn fast_forward_vals(&mut self) {
559 self.valid = true;
560 }
561
562 fn position(&self) -> Option<Position> {
563 Some(Position {
564 total: TrieCursor::keys(&self.cursor) as u64,
565 offset: self.cursor.pos() as u64,
566 })
567 }
568}
569
570#[derive(SizeOf)]
572pub struct VecKeyBuilder<K, T, R, O = usize>
573where
574 K: DataTrait + ?Sized,
575 T: Timestamp,
576 R: WeightTrait + ?Sized,
577 O: OrdOffset,
578{
579 #[size_of(skip)]
580 factories: VecKeyBatchFactories<K, T, R>,
581 keys: Box<DynVec<K>>,
582 offs: Vec<O>,
583 times: Box<DynVec<DynDataTyped<T>>>,
584 diffs: Box<DynVec<R>>,
585}
586
587impl<K, T, R, O> VecKeyBuilder<K, T, R, O>
588where
589 K: DataTrait + ?Sized,
590 T: Timestamp,
591 R: WeightTrait + ?Sized,
592 O: OrdOffset,
593{
594 fn pushed_key(&mut self) {
595 let off = O::from_usize(self.times.len());
596 debug_assert!(off > *self.offs.last().unwrap());
597 self.offs.push(off);
598 }
599}
600
601impl<K, T, R, O> Builder<VecKeyBatch<K, T, R, O>> for VecKeyBuilder<K, T, R, O>
602where
603 K: DataTrait + ?Sized,
604 T: Timestamp,
605 R: WeightTrait + ?Sized,
606 O: OrdOffset,
607{
608 fn with_capacity_in_location(
609 factories: &VecKeyBatchFactories<K, T, R>,
610 key_capacity: usize,
611 value_capacity: usize,
612 _location: Option<BatchLocation>,
613 ) -> Self {
614 let mut keys = factories.layer_factories.keys.default_box();
615 keys.reserve_exact(key_capacity);
616
617 let mut offs = Vec::with_capacity(key_capacity + 1);
618 offs.push(O::zero());
619
620 let mut times = factories.layer_factories.child.keys.default_box();
621 times.reserve_exact(value_capacity);
622
623 let mut diffs = factories.layer_factories.child.diffs.default_box();
624 diffs.reserve_exact(value_capacity);
625 Self {
626 factories: factories.clone(),
627 keys,
628 offs,
629 times,
630 diffs,
631 }
632 }
633
634 fn reserve(&mut self, additional: usize) {
635 self.keys.reserve(additional);
636 self.offs.reserve(additional);
637 self.times.reserve(additional);
638 self.diffs.reserve(additional);
639 }
640
641 fn push_key(&mut self, key: &K) {
642 self.keys.push_ref(key);
643 self.pushed_key();
644 }
645
646 fn push_key_mut(&mut self, key: &mut K) {
647 self.keys.push_val(key);
648 self.pushed_key();
649 }
650
651 fn push_val(&mut self, _val: &DynUnit) {}
652
653 fn push_time_diff(&mut self, time: &T, weight: &R) {
654 debug_assert!(!weight.is_zero());
655 self.times.push(time.clone());
656 self.diffs.push_ref(weight);
657 }
658
659 fn push_time_diff_mut(&mut self, time: &mut T, weight: &mut R) {
660 debug_assert!(!weight.is_zero());
661 self.times.push(time.clone());
662 self.diffs.push_val(weight);
663 }
664
665 fn done(self) -> VecKeyBatch<K, T, R, O> {
666 VecKeyBatch {
667 layer: Layer::from_parts(
668 &self.factories.layer_factories,
669 self.keys,
670 self.offs,
671 Leaf::from_parts(
672 &self.factories.layer_factories.child,
673 self.times,
674 self.diffs,
675 ),
676 ),
677 factories: self.factories,
678 touched_window_count: TouchedWindowCount::default(),
679 }
680 }
681
682 fn num_keys(&self) -> usize {
683 self.keys.len()
684 }
685
686 fn num_tuples(&self) -> usize {
687 self.diffs.len()
688 }
689}
690
691