55import copy
66from enum import Enum
77from threading import RLock
8- from typing import Any , Dict , List
8+ from typing import Any , Dict , List , Optional
99
1010from ansys .api .fluent .v0 .variant_pb2 import Variant
1111from ansys .fluent .core .utils .fluent_version import FluentVersion
@@ -206,28 +206,34 @@ def _update_cache_from_variant_state(
206206 source : Dict [str , StateType ],
207207 key : str ,
208208 state : Variant ,
209- updaterFn ,
209+ updater_fn ,
210210 rules_str : str ,
211211 version ,
212212 ):
213- if state .HasField ("bool_state" ):
214- updaterFn (source , key , state .bool_state )
215- elif state .HasField ("int64_state" ):
216- updaterFn (source , key , state .int64_state )
217- elif state .HasField ("double_state" ):
218- updaterFn (source , key , state .double_state )
219- elif state .HasField ("string_state" ):
220- updaterFn (source , key , state .string_state )
221- elif state .HasField ("bool_vector_state" ):
222- updaterFn (source , key , state .bool_vector_state .item )
223- elif state .HasField ("int64_vector_state" ):
224- updaterFn (source , key , state .int64_vector_state .item )
225- elif state .HasField ("double_vector_state" ):
226- updaterFn (source , key , state .double_vector_state .item )
227- elif state .HasField ("string_vector_state" ):
228- updaterFn (source , key , state .string_vector_state .item )
229- elif state .HasField ("variant_vector_state" ):
230- updaterFn (source , key , [])
213+ # Helper function to update the source with the state value
214+ def update_source_with_state (state_field ):
215+ if state .HasField (state_field ):
216+ updater_fn (source , key , getattr (state , state_field ))
217+ return True
218+ return False
219+
220+ # Check for basic state types
221+ for state_type in [
222+ "bool_state" ,
223+ "int64_state" ,
224+ "double_state" ,
225+ "string_state" ,
226+ "bool_vector_state" ,
227+ "int64_vector_state" ,
228+ "double_vector_state" ,
229+ "string_vector_state" ,
230+ ]:
231+ if update_source_with_state (state_type ):
232+ return
233+
234+ # Handle variant vector state
235+ if state .HasField ("variant_vector_state" ):
236+ updater_fn (source , key , [])
231237 for item in state .variant_vector_state .item :
232238 self ._update_cache_from_variant_state (
233239 rules ,
@@ -238,34 +244,28 @@ def _update_cache_from_variant_state(
238244 rules_str + "/" + key .split (":" , maxsplit = 1 )[0 ],
239245 version ,
240246 )
241- elif state .HasField ("variant_map_state" ):
247+ return
248+
249+ # Handle variant map state
250+ if state .HasField ("variant_map_state" ):
242251 internal_names_as_keys = (
243252 self .get_config (rules , "name_key" ) == NameKey .INTERNAL
244253 )
254+
255+ # Determine the appropriate key
245256 if ":" in key :
246257 type_ , iname = key .split (":" , maxsplit = 1 )
247- for k1 , v1 in source .items ():
248- if (internal_names_as_keys and k1 == key ) or (
249- (not internal_names_as_keys )
250- and isinstance (v1 , dict )
251- and v1 .get (NameKey .INTERNAL .value ) == iname
252- ):
253- key = k1
254- break
255- else : # new named object
256- if internal_names_as_keys :
257- source [key ] = {}
258- else :
259- name = state .variant_map_state .item [
260- NameKey .DISPLAY .value
261- ].string_state
262- key = f"{ type_ } :{ name } "
263- source [key ] = {NameKey .INTERNAL .value : iname }
258+ key = self ._determine_key (
259+ source , internal_names_as_keys , key , state , type_ , iname
260+ )
264261 else :
265262 if key not in source :
266263 source [key ] = {}
264+
267265 if version and _is_dict_parameter_type (version , rules , rules_str ):
268266 source [key ] = {}
267+
268+ # Update the source with items from the variant map state
269269 if state .variant_map_state .item :
270270 source = source [key ]
271271 for k , v in state .variant_map_state .item .items ():
@@ -280,8 +280,40 @@ def _update_cache_from_variant_state(
280280 )
281281 else :
282282 source [key ] = {}
283+
284+ # Default case when no fields are matched
283285 else :
284- updaterFn (source , key , None )
286+ updater_fn (source , key , None )
287+
288+ def _determine_key (
289+ self ,
290+ source : Dict [str , StateType ],
291+ internal_names_as_keys : bool ,
292+ key : str ,
293+ state : Variant ,
294+ type_ : str ,
295+ iname : str ,
296+ ) -> str :
297+ """Determine the appropriate key based on internal naming conventions."""
298+ for k1 , v1 in source .items ():
299+ if (internal_names_as_keys and k1 == key ) or (
300+ (not internal_names_as_keys )
301+ and isinstance (v1 , dict )
302+ and v1 .get (NameKey .INTERNAL .value ) == iname
303+ ):
304+ return k1 # Found a matching key
305+
306+ # If no match found and internal naming is used
307+ if internal_names_as_keys :
308+ source [key ] = {}
309+ return key
310+
311+ # If no match found and external naming is used
312+ name = state .variant_map_state .item [NameKey .DISPLAY .value ].string_state
313+ new_key = f"{ type_ } :{ name } "
314+ source [new_key ] = {NameKey .INTERNAL .value : iname }
315+
316+ return new_key
285317
286318 def update_cache (
287319 self , rules : str , state : Variant , deleted_paths : List [str ], version = None
@@ -300,37 +332,16 @@ def update_cache(
300332 Fluent version
301333 """
302334 cache = self .rules_str_to_cache [rules ]
335+
303336 with self ._with_lock (rules ):
304337 internal_names_as_keys = (
305338 self .get_config (rules , "name_key" ) == NameKey .INTERNAL
306339 )
307- for deleted_path in deleted_paths :
308- comps = [x for x in deleted_path .split ("/" ) if x ]
309- sub_cache = cache
310- for i , comp in enumerate (comps ):
311- if ":" in comp :
312- _ , iname = comp .split (":" , maxsplit = 1 )
313- key_to_del = None
314- for k , v in sub_cache .items ():
315- if (internal_names_as_keys and k == comp ) or (
316- (not internal_names_as_keys )
317- and isinstance (v , dict )
318- and v .get (NameKey .INTERNAL .value ) == iname
319- ):
320- if i == len (comps ) - 1 :
321- key_to_del = k
322- else :
323- sub_cache = v
324- break
325- else :
326- break
327- if key_to_del :
328- del sub_cache [key_to_del ]
329- else :
330- if comp in sub_cache :
331- sub_cache = sub_cache [comp ]
332- else :
333- break
340+
341+ # Process deleted paths
342+ self ._process_deleted_paths (cache , deleted_paths , internal_names_as_keys )
343+
344+ # Update cache with new state items
334345 for k , v in state .variant_map_state .item .items ():
335346 self ._update_cache_from_variant_state (
336347 rules ,
@@ -342,6 +353,56 @@ def update_cache(
342353 version ,
343354 )
344355
356+ def _process_deleted_paths (
357+ self ,
358+ cache : Dict [str , Any ],
359+ deleted_paths : List [str ],
360+ internal_names_as_keys : bool ,
361+ ):
362+ """Process and delete paths from the cache based on the deleted paths list."""
363+ for deleted_path in deleted_paths :
364+ comps = [x for x in deleted_path .split ("/" ) if x ]
365+ self ._delete_from_cache (cache , comps , internal_names_as_keys )
366+
367+ def _delete_from_cache (
368+ self , sub_cache : Dict [str , Any ], comps : List [str ], internal_names_as_keys : bool
369+ ):
370+ """Recursively delete components from the cache."""
371+ for i , comp in enumerate (comps ):
372+ if ":" in comp :
373+ _ , iname = comp .split (":" , maxsplit = 1 )
374+ key_to_del = self ._find_key_to_delete (
375+ sub_cache , comp , iname , i == len (comps ) - 1 , internal_names_as_keys
376+ )
377+ if key_to_del :
378+ del sub_cache [key_to_del ]
379+ return # Exit after deletion
380+ else :
381+ if comp in sub_cache :
382+ sub_cache = sub_cache [comp ]
383+ else :
384+ break
385+
386+ def _find_key_to_delete (
387+ self ,
388+ sub_cache : Dict [str , Any ],
389+ comp : str ,
390+ iname : str ,
391+ is_last_component : bool ,
392+ internal_names_as_keys : bool ,
393+ ) -> Optional [str ]:
394+ """Find the key to delete from the sub-cache."""
395+ for k , v in sub_cache .items ():
396+ if (internal_names_as_keys and k == comp ) or (
397+ (not internal_names_as_keys )
398+ and isinstance (v , dict )
399+ and v .get (NameKey .INTERNAL .value ) == iname
400+ ):
401+ return (
402+ k if is_last_component else None
403+ ) # Return key if it's the last component
404+ return None # No key found to delete
405+
345406 @staticmethod
346407 def _dm_path_comp (comp ):
347408 return ":" .join (comp ) if comp [1 ] else comp [0 ]
0 commit comments