1+ #![ allow( unused_variables) ]
12use std:: sync:: Arc ;
23
3- use optd_persistent:: CostModelStorageLayer ;
4+ use optd_persistent:: {
5+ cost_model:: interface:: { Attr , StatType } ,
6+ CostModelStorageLayer ,
7+ } ;
8+
9+ use crate :: {
10+ common:: types:: TableId ,
11+ stats:: { counter:: Counter , AttributeCombValueStats , Distribution , MostCommonValues } ,
12+ CostModelResult ,
13+ } ;
414
515/// TODO: documentation
616pub struct CostModelStorageManager < S : CostModelStorageLayer > {
@@ -9,8 +19,113 @@ pub struct CostModelStorageManager<S: CostModelStorageLayer> {
919}
1020
1121impl < S : CostModelStorageLayer > CostModelStorageManager < S > {
12- /// TODO: documentation
1322 pub fn new ( backend_manager : Arc < S > ) -> Self {
1423 Self { backend_manager }
1524 }
25+
26+ /// Gets the attribute information for a given table and attribute base index.
27+ ///
28+ /// TODO: if we have memory cache,
29+ /// we should add the reference. (&Attr)
30+ pub async fn get_attribute_info (
31+ & self ,
32+ table_id : TableId ,
33+ attr_base_index : i32 ,
34+ ) -> CostModelResult < Option < Attr > > {
35+ Ok ( self
36+ . backend_manager
37+ . get_attribute ( table_id. into ( ) , attr_base_index)
38+ . await ?)
39+ }
40+
41+ /// Gets the latest statistics for a given table.
42+ ///
43+ /// TODO: Currently, in `AttributeCombValueStats`, only `Distribution` is optional.
44+ /// This poses a question about the behavior of the system if there is no corresponding
45+ /// `MostCommonValues`, `ndistinct`, or other statistics. We should have a clear
46+ /// specification about the behavior of the system in the presence of missing statistics.
47+ ///
48+ /// TODO: if we have memory cache,
49+ /// we should add the reference. (&AttributeCombValueStats)
50+ ///
51+ /// TODO: Shall we pass in an epoch here to make sure that the statistics are from the same
52+ /// epoch?
53+ pub async fn get_attributes_comb_statistics (
54+ & self ,
55+ table_id : TableId ,
56+ attr_base_indices : & [ i32 ] ,
57+ ) -> CostModelResult < Option < AttributeCombValueStats > > {
58+ let dist: Option < Distribution > = self
59+ . backend_manager
60+ . get_stats_for_attr_indices_based (
61+ table_id. into ( ) ,
62+ attr_base_indices. to_vec ( ) ,
63+ StatType :: Distribution ,
64+ None ,
65+ )
66+ . await ?
67+ . map ( |json| serde_json:: from_value ( json) . unwrap ( ) ) ;
68+
69+ let mcvs = self
70+ . backend_manager
71+ . get_stats_for_attr_indices_based (
72+ table_id. into ( ) ,
73+ attr_base_indices. to_vec ( ) ,
74+ StatType :: MostCommonValues ,
75+ None ,
76+ )
77+ . await ?
78+ . map ( |json| serde_json:: from_value ( json) . unwrap ( ) )
79+ . unwrap_or_else ( || MostCommonValues :: Counter ( Counter :: default ( ) ) ) ;
80+
81+ let ndistinct = self
82+ . backend_manager
83+ . get_stats_for_attr_indices_based (
84+ table_id. into ( ) ,
85+ attr_base_indices. to_vec ( ) ,
86+ StatType :: Cardinality ,
87+ None ,
88+ )
89+ . await ?
90+ . map ( |json| serde_json:: from_value ( json) . unwrap ( ) )
91+ . unwrap_or ( 0 ) ;
92+
93+ let table_row_count = self
94+ . backend_manager
95+ . get_stats_for_attr_indices_based (
96+ table_id. into ( ) ,
97+ attr_base_indices. to_vec ( ) ,
98+ StatType :: TableRowCount ,
99+ None ,
100+ )
101+ . await ?
102+ . map ( |json| serde_json:: from_value ( json) . unwrap ( ) )
103+ . unwrap_or ( 0 ) ;
104+ let non_null_count = self
105+ . backend_manager
106+ . get_stats_for_attr_indices_based (
107+ table_id. into ( ) ,
108+ attr_base_indices. to_vec ( ) ,
109+ StatType :: NonNullCount ,
110+ None ,
111+ )
112+ . await ?
113+ . map ( |json| serde_json:: from_value ( json) . unwrap ( ) )
114+ . unwrap_or ( 0 ) ;
115+
116+ // FIXME: Only minimal checks for invalid values is conducted here. We should have
117+ // much clear specification about the behavior of the system in the presence of
118+ // invalid statistics.
119+ let null_frac = if table_row_count == 0 {
120+ 0.0
121+ } else {
122+ 1.0 - ( non_null_count as f64 / table_row_count as f64 )
123+ } ;
124+
125+ Ok ( Some ( AttributeCombValueStats :: new (
126+ mcvs, ndistinct, null_frac, dist,
127+ ) ) )
128+ }
16129}
130+
131+ // TODO: add some tests, especially cover the error cases.
0 commit comments