risingwave_common/types/
sentinel.rs1use enum_as_inner::EnumAsInner;
16use risingwave_common_estimate_size::EstimateSize;
17
18#[derive(Debug, Clone, PartialEq, Eq, EnumAsInner)]
25pub enum Sentinelled<T> {
26 Smallest,
27 Normal(T),
28 Largest,
29}
30
31impl<T> Sentinelled<T> {
32 pub fn as_normal_expect(&self) -> &T {
33 self.as_normal().expect("expect normal key")
34 }
35
36 pub fn is_sentinel(&self) -> bool {
37 matches!(self, Self::Smallest | Self::Largest)
38 }
39
40 pub fn cmp_by(
41 &self,
42 other: &Self,
43 cmp_fn: impl FnOnce(&T, &T) -> std::cmp::Ordering,
44 ) -> std::cmp::Ordering {
45 use Sentinelled::*;
46 match (self, other) {
47 (Smallest, Smallest) => std::cmp::Ordering::Equal,
48 (Smallest, _) => std::cmp::Ordering::Less,
49 (_, Smallest) => std::cmp::Ordering::Greater,
50 (Largest, Largest) => std::cmp::Ordering::Equal,
51 (Largest, _) => std::cmp::Ordering::Greater,
52 (_, Largest) => std::cmp::Ordering::Less,
53 (Normal(a), Normal(b)) => cmp_fn(a, b),
54 }
55 }
56
57 pub fn map<U>(self, map_fn: impl FnOnce(T) -> U) -> Sentinelled<U> {
58 use Sentinelled::*;
59 match self {
60 Smallest => Smallest,
61 Normal(inner) => Normal(map_fn(inner)),
62 Largest => Largest,
63 }
64 }
65}
66
67impl<T> From<T> for Sentinelled<T> {
68 fn from(inner: T) -> Self {
69 Self::Normal(inner)
70 }
71}
72
73impl<T> PartialOrd for Sentinelled<T>
74where
75 T: Ord,
76{
77 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
78 Some(self.cmp(other))
79 }
80}
81
82impl<T> Ord for Sentinelled<T>
83where
84 T: Ord,
85{
86 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
87 self.cmp_by(other, T::cmp)
88 }
89}
90
91impl<T: EstimateSize> EstimateSize for Sentinelled<T> {
92 fn estimated_heap_size(&self) -> usize {
93 match self {
94 Self::Smallest => 0,
95 Self::Normal(inner) => inner.estimated_heap_size(),
96 Self::Largest => 0,
97 }
98 }
99}