@@ -74,66 +74,76 @@ pub struct DebugData {
7474 #[ serde( rename = "removedCombos" ) ]
7575 removed_combos : Vec < DebugCombo > ,
7676 #[ serde( rename = "appliedRules" ) ]
77- applied_rules : Option < Vec < String > > ,
77+ applied_rules : Vec < String > ,
7878}
7979
80- impl DebugData {
81- pub fn prepare ( graph : & CubeEGraph ) -> DebugData {
82- DebugData {
83- applied_rules : None ,
84- nodes : graph
85- . classes ( )
86- . flat_map ( |class| {
87- let mut result = class
88- . nodes
89- . iter ( )
90- . map ( |n| {
91- let node_id = format ! ( "{}-{:?}" , class. id, n) ;
92- DebugNode {
93- id : node_id. to_string ( ) ,
94- label : format ! ( "{:?}" , n) ,
95- combo_id : format ! ( "c{}" , class. id) ,
96- }
97- } )
98- . collect :: < Vec < _ > > ( ) ;
99- result. push ( DebugNode {
100- id : class. id . to_string ( ) ,
101- label : class. id . to_string ( ) ,
102- combo_id : format ! ( "c{}" , class. id) ,
103- } ) ;
104- result
105- } )
106- . collect ( ) ,
107- edges : graph
108- . classes ( )
109- . flat_map ( |class| {
110- class
111- . nodes
112- . iter ( )
113- . map ( |n| DebugEdge {
114- source : class. id . to_string ( ) ,
115- target : format ! ( "{}-{:?}" , class. id, n, ) ,
116- } )
117- . chain ( class. nodes . iter ( ) . flat_map ( |n| {
118- n. children ( ) . iter ( ) . map ( move |c| DebugEdge {
119- source : format ! ( "{}-{:?}" , class. id, n) ,
120- target : c. to_string ( ) ,
121- } )
122- } ) )
123- . collect :: < Vec < _ > > ( )
124- } )
125- . collect ( ) ,
126- combos : graph
127- . classes ( )
128- . map ( |class| DebugCombo {
129- id : format ! ( "c{}" , class. id) ,
130- label : format ! ( "#{}" , class. id) ,
131- } )
132- . collect ( ) ,
133- removed_nodes : Vec :: new ( ) ,
134- removed_edges : Vec :: new ( ) ,
135- removed_combos : Vec :: new ( ) ,
136- }
80+ #[ derive( Clone ) ]
81+ struct DebugENodeId ( String ) ;
82+
83+ impl DebugENodeId {
84+ pub fn as_str ( & self ) -> & str {
85+ self . 0 . as_str ( )
86+ }
87+ }
88+
89+ impl From < & LogicalPlanLanguage > for DebugENodeId {
90+ fn from ( value : & LogicalPlanLanguage ) -> Self {
91+ Self ( format ! ( "{value:?}" ) )
92+ }
93+ }
94+
95+ #[ derive( Clone ) ]
96+ pub struct EClassDebugData {
97+ id : Id ,
98+ #[ allow( dead_code) ]
99+ canon : Id ,
100+ }
101+
102+ #[ derive( Clone ) ]
103+ pub struct ENodeDebugData {
104+ enode : DebugENodeId ,
105+ eclass : Id ,
106+ children : Vec < Id > ,
107+ }
108+
109+ /// Representation is optimised for storing in JSON, to transfer to UI
110+ #[ derive( Clone ) ]
111+ pub struct EGraphDebugState {
112+ eclasses : Vec < EClassDebugData > ,
113+ enodes : Vec < ENodeDebugData > ,
114+ }
115+
116+ impl EGraphDebugState {
117+ pub fn new ( graph : & EGraph < LogicalPlanLanguage , LogicalPlanAnalysis > ) -> Self {
118+ let current_eclasses = graph. classes ( ) . map ( |ec| ec. id ) ;
119+ let previous_debug_eclasses = graph
120+ . analysis
121+ . debug_states
122+ . iter ( )
123+ . flat_map ( |state| state. eclasses . iter ( ) . map ( |ecd| ecd. id ) ) ;
124+ let all_known_eclasses = current_eclasses. chain ( previous_debug_eclasses) ;
125+
126+ let all_known_eclasses = all_known_eclasses. collect :: < HashSet < _ > > ( ) ;
127+
128+ let eclasses = all_known_eclasses
129+ . into_iter ( )
130+ . map ( |ec| EClassDebugData {
131+ id : ec,
132+ canon : graph. find ( ec) ,
133+ } )
134+ . collect :: < Vec < _ > > ( ) ;
135+
136+ let enodes = graph
137+ . classes ( )
138+ . flat_map ( |ec| ec. nodes . iter ( ) . map ( move |node| ( ec. id , node) ) )
139+ . map ( |( ec, node) | ENodeDebugData {
140+ enode : node. into ( ) ,
141+ eclass : ec,
142+ children : node. children ( ) . to_vec ( ) ,
143+ } )
144+ . collect ( ) ;
145+
146+ EGraphDebugState { eclasses, enodes }
137147 }
138148}
139149
@@ -191,7 +201,7 @@ fn write_debug_states(runner: &CubeRunner, stage: &str) -> Result<(), CubeError>
191201 ) ?;
192202
193203 let mut states = Vec :: new ( ) ;
194- let mut last_debug_data : Option < DebugData > = None ;
204+ let mut previous_debug_data : Option < ( Vec < DebugNode > , Vec < DebugEdge > , Vec < DebugCombo > ) > = None ;
195205
196206 let debug_data = runner. egraph . analysis . debug_states . as_slice ( ) ;
197207 debug_assert_eq ! ( debug_data. len( ) , runner. iterations. len( ) + 1 ) ;
@@ -204,47 +214,95 @@ fn write_debug_states(runner: &CubeRunner, stage: &str) -> Result<(), CubeError>
204214 . zip ( runner. iterations . iter ( ) . map ( |i| Some ( & i. applied ) ) ) ;
205215 let states_data = std:: iter:: once ( ( & debug_data[ 0 ] , None ) ) . chain ( states_data) ;
206216
217+ // TODO move this even later, to UI side
207218 for ( debug_data, applied) in states_data {
208- let mut debug_data = debug_data. clone ( ) ;
209- let debug_data_clone = debug_data. clone ( ) ;
210-
211- if let Some ( last) = last_debug_data {
212- debug_data
213- . nodes
214- . retain ( |n| !last. nodes . iter ( ) . any ( |ln| ln. id == n. id ) ) ;
215- debug_data. edges . retain ( |n| {
216- !last
217- . edges
219+ let mut nodes = debug_data
220+ . enodes
221+ . iter ( )
222+ . map ( |node| {
223+ let node_id = format ! ( "{}-{}" , node. eclass, node. enode. as_str( ) ) ;
224+ DebugNode {
225+ id : node_id,
226+ label : node. enode . 0 . clone ( ) ,
227+ combo_id : format ! ( "c{}" , node. eclass) ,
228+ }
229+ } )
230+ . chain ( debug_data. eclasses . iter ( ) . map ( |eclass| DebugNode {
231+ id : eclass. id . to_string ( ) ,
232+ label : eclass. id . to_string ( ) ,
233+ combo_id : format ! ( "c{}" , eclass. id) ,
234+ } ) )
235+ . collect :: < Vec < _ > > ( ) ;
236+
237+ let mut edges = debug_data
238+ . enodes
239+ . iter ( )
240+ . flat_map ( |node| {
241+ std:: iter:: once ( DebugEdge {
242+ source : node. eclass . to_string ( ) ,
243+ target : format ! ( "{}-{}" , node. eclass, node. enode. as_str( ) ) ,
244+ } )
245+ . chain ( node. children . iter ( ) . map ( move |child| DebugEdge {
246+ source : format ! ( "{}-{}" , node. eclass, node. enode. as_str( ) ) ,
247+ target : child. to_string ( ) ,
248+ } ) )
249+ } )
250+ . collect :: < Vec < _ > > ( ) ;
251+
252+ let mut combos = debug_data
253+ . eclasses
254+ . iter ( )
255+ . map ( |eclass| DebugCombo {
256+ id : format ! ( "c{}" , eclass. id) ,
257+ label : format ! ( "#{}" , eclass. id) ,
258+ } )
259+ . collect :: < Vec < _ > > ( ) ;
260+
261+ let nodes_clone = nodes. clone ( ) ;
262+ let edges_clone = edges. clone ( ) ;
263+ let combos_clone = combos. clone ( ) ;
264+
265+ let mut removed_nodes = vec ! [ ] ;
266+ let mut removed_edges = vec ! [ ] ;
267+ let mut removed_combos = vec ! [ ] ;
268+
269+ if let Some ( ( prev_nodes, prev_edges, prev_combos) ) = previous_debug_data {
270+ nodes. retain ( |n| !prev_nodes. iter ( ) . any ( |ln| ln. id == n. id ) ) ;
271+ edges. retain ( |n| {
272+ !prev_edges
218273 . iter ( )
219274 . any ( |ln| ln. source == n. source && ln. target == n. target )
220275 } ) ;
221- debug_data
222- . combos
223- . retain ( |n| !last. combos . iter ( ) . any ( |ln| ln. id == n. id ) ) ;
224-
225- debug_data. removed_nodes = last. nodes . clone ( ) ;
226- debug_data
227- . removed_nodes
228- . retain ( |n| !debug_data_clone. nodes . iter ( ) . any ( |ln| ln. id == n. id ) ) ;
229- debug_data. removed_edges = last. edges . clone ( ) ;
230- debug_data. removed_edges . retain ( |n| {
231- !debug_data_clone
232- . edges
276+ combos. retain ( |n| !prev_combos. iter ( ) . any ( |ln| ln. id == n. id ) ) ;
277+
278+ removed_nodes = prev_nodes. clone ( ) ;
279+ removed_nodes. retain ( |n| !nodes_clone. iter ( ) . any ( |ln| ln. id == n. id ) ) ;
280+ removed_edges = prev_edges. clone ( ) ;
281+ removed_edges. retain ( |n| {
282+ !edges_clone
233283 . iter ( )
234284 . any ( |ln| ln. source == n. source && ln. target == n. target )
235285 } ) ;
236- debug_data. removed_combos = last. combos . clone ( ) ;
237- debug_data
238- . removed_combos
239- . retain ( |n| !debug_data_clone. combos . iter ( ) . any ( |ln| ln. id == n. id ) ) ;
286+ removed_combos = prev_combos. clone ( ) ;
287+ removed_combos. retain ( |n| !combos_clone. iter ( ) . any ( |ln| ln. id == n. id ) ) ;
240288 }
241- debug_data. applied_rules = Some (
242- applied
243- . map ( |applied| applied. iter ( ) . map ( |s| format ! ( "{:?}" , s) ) . collect ( ) )
244- . unwrap_or ( vec ! [ ] ) ,
245- ) ;
246- states. push ( debug_data) ;
247- last_debug_data = Some ( debug_data_clone) ;
289+
290+ let applied_rules = applied
291+ . map ( |applied| applied. iter ( ) . map ( |s| format ! ( "{:?}" , s) ) . collect ( ) )
292+ . unwrap_or ( vec ! [ ] ) ;
293+
294+ let debug_data = DebugData {
295+ nodes,
296+ edges,
297+ combos,
298+ removed_nodes,
299+ removed_edges,
300+ removed_combos,
301+ applied_rules,
302+ } ;
303+
304+ states. push ( debug_data. clone ( ) ) ;
305+ previous_debug_data = Some ( ( nodes_clone, edges_clone, combos_clone) ) ;
248306 }
249307 fs:: write (
250308 format ! ( "{}/src/states.json" , dir) ,
0 commit comments