krabka_client_streams/dsl/global_table.rs
1//! `GlobalKTable<K,V>`: a fully-replicated lookup table.
2//!
3//! It is a join target only. It supports no aggregations and no `to_stream`.
4//! [`StreamsBuilder::global_table`] builds it, and
5//! [`KStream::join_global`] and [`KStream::left_join_global`] consume it.
6//!
7//! A `GlobalKTable` is invisible in the wire topology. It has no source topic, no
8//! changelog, and no subtopology of its own. Its source node only occupies a
9//! node-group index during grouping, so the other subtopology ids shift. The DSL
10//! registers the store with [`Topology::add_global_store`].
11//!
12//! [`StreamsBuilder::global_table`]: crate::dsl::builder::StreamsBuilder::global_table
13//! [`KStream::join_global`]: crate::dsl::kstream::KStream::join_global
14//! [`KStream::left_join_global`]: crate::dsl::kstream::KStream::left_join_global
15//! [`Topology::add_global_store`]: crate::topology::Topology::add_global_store
16use std::{cell::RefCell, marker::PhantomData, rc::Rc};
17
18use crate::{
19 dsl::{builder::InternalStreamsBuilder, graph::NodeId},
20 processor::serde::DefaultSerde,
21};
22
23/// A handle to a fully-replicated `GlobalKTable`. It works only as a join
24/// target.
25///
26/// `store_name` is the materialized store that `KStream::join_global` and
27/// `left_join_global` wire the join processor's lookup against. `source_topic`
28/// is the broker topic that fully replicates the global store.
29pub struct GlobalKTable<K, V, KS = <K as DefaultSerde>::Serde, VS = <V as DefaultSerde>::Serde> {
30 // Keeps the shared builder alive while this handle is live.
31 #[allow(dead_code)]
32 pub(crate) builder: Rc<RefCell<InternalStreamsBuilder>>,
33 // Logical graph node for the global source.
34 #[allow(dead_code)]
35 pub(crate) node: NodeId,
36 pub(crate) store_name: String,
37 // Source topic feeding the fully replicated store.
38 #[allow(dead_code)]
39 pub(crate) source_topic: String,
40 pub(crate) key_serde: KS,
41 pub(crate) value_serde: VS,
42 _pd: PhantomData<fn() -> (K, V)>,
43}
44
45impl<K, V, KS, VS> GlobalKTable<K, V, KS, VS> {
46 pub(crate) fn new(
47 builder: Rc<RefCell<InternalStreamsBuilder>>,
48 node: NodeId,
49 store_name: String,
50 source_topic: String,
51 key_serde: KS,
52 value_serde: VS,
53 ) -> Self {
54 Self {
55 builder,
56 node,
57 store_name,
58 source_topic,
59 key_serde,
60 value_serde,
61 _pd: PhantomData,
62 }
63 }
64
65 /// The name of the materialized state store that backs this global table.
66 ///
67 /// [`KStream::join_global`](crate::dsl::kstream::KStream::join_global) and
68 /// `left_join_global` read it to wire the join processor's global-store
69 /// lookup.
70 pub(crate) fn store_name(&self) -> &str {
71 &self.store_name
72 }
73
74 pub fn with_key_serde<NewKS>(self, serde: NewKS) -> GlobalKTable<K, V, NewKS, VS> {
75 GlobalKTable {
76 builder: self.builder,
77 node: self.node,
78 store_name: self.store_name,
79 source_topic: self.source_topic,
80 key_serde: serde,
81 value_serde: self.value_serde,
82 _pd: PhantomData,
83 }
84 }
85
86 pub fn with_value_serde<NewVS>(self, serde: NewVS) -> GlobalKTable<K, V, KS, NewVS> {
87 GlobalKTable {
88 builder: self.builder,
89 node: self.node,
90 store_name: self.store_name,
91 source_topic: self.source_topic,
92 key_serde: self.key_serde,
93 value_serde: serde,
94 _pd: PhantomData,
95 }
96 }
97}