@@ -190,6 +190,8 @@ def __init__(self, *args, _from_parent_store=None, **kwargs):
190190
191191 self .subtree_path = "" # Empty string means full tree
192192 self ._inline_handles : list = [] # inline object handles opened from this store
193+ self ._known_object_roots_cache : set [str ] | None = None
194+ self ._effective_object_roots_cache : tuple [str , set [str ]] | None = None
193195
194196 # ------------------------------------------------------------------
195197 # Object registry helpers
@@ -203,12 +205,18 @@ def _objects_registry(self) -> dict:
203205 except Exception :
204206 return {}
205207
208+ def _invalidate_object_roots_cache (self ) -> None :
209+ """Invalidate cached object-root views."""
210+ self ._known_object_roots_cache = None
211+ self ._effective_object_roots_cache = None
212+
206213 def _register_object (self , full_key : str , * , kind : str , version : int , layout : str ) -> None :
207214 """Register *full_key* as an object root in the persistent registry."""
208215 try :
209216 reg = self ._objects_registry ()
210217 reg [full_key ] = {"kind" : kind , "version" : version , "layout" : layout }
211218 self ._estore ._store .vlmeta ["_object_registry" ] = reg
219+ self ._invalidate_object_roots_cache ()
212220 except Exception :
213221 pass # best-effort
214222
@@ -218,6 +226,7 @@ def _unregister_object(self, full_key: str) -> None:
218226 reg = self ._objects_registry ()
219227 reg .pop (full_key , None )
220228 self ._estore ._store .vlmeta ["_object_registry" ] = reg
229+ self ._invalidate_object_roots_cache ()
221230 except Exception :
222231 pass
223232
@@ -247,23 +256,40 @@ def _probed_object_roots(self) -> set:
247256
248257 def _known_object_roots (self ) -> set :
249258 """Return registered plus physically probed object-root full keys."""
250- return self ._object_roots () | self ._probed_object_roots ()
259+ if self ._known_object_roots_cache is not None :
260+ return set (self ._known_object_roots_cache )
261+
262+ registered = self ._object_roots ()
263+ # Fast path: when registry exists, avoid costly full-store probing.
264+ roots = registered if registered else self ._probed_object_roots ()
265+ self ._known_object_roots_cache = roots
266+ return set (roots )
251267
252268 def _effective_object_roots (self ) -> set :
253269 """Object root keys relative to the current view (subtree or root)."""
270+ current_subtree_path = self .subtree_path or ""
271+ if (
272+ self ._effective_object_roots_cache is not None
273+ and self ._effective_object_roots_cache [0 ] == current_subtree_path
274+ ):
275+ return set (self ._effective_object_roots_cache [1 ])
276+
254277 all_roots = self ._known_object_roots ()
255278 if not self .subtree_path :
256- return all_roots
279+ self ._effective_object_roots_cache = (current_subtree_path , all_roots )
280+ return set (all_roots )
257281 result = set ()
258282 for full_key in all_roots :
259283 relative = self ._translate_key_from_full (full_key )
260284 if relative is not None :
261285 result .add (relative )
262- return result
286+ self ._effective_object_roots_cache = (current_subtree_path , result )
287+ return set (result )
263288
264- def _is_object_internal_key (self , key : str ) -> bool :
289+ def _is_object_internal_key (self , key : str , object_roots : set [ str ] | None = None ) -> bool :
265290 """Return ``True`` when *key* (subtree-relative) is inside an object root."""
266- return any (key != root and key .startswith (root + "/" ) for root in self ._effective_object_roots ())
291+ roots = self ._effective_object_roots () if object_roots is None else object_roots
292+ return any (key != root and key .startswith (root + "/" ) for root in roots )
267293
268294 def _probe_object_info (self , full_key : str ) -> dict | None :
269295 """Probe the physical store for a CTable manifest at *full_key*/_meta.
@@ -647,7 +673,8 @@ def __contains__(self, key: str) -> bool:
647673 key = self ._validate_key (key )
648674 if self ._is_vlmeta_key (key ):
649675 return False
650- if self ._is_object_internal_key (key ):
676+ object_roots = self ._effective_object_roots ()
677+ if self ._is_object_internal_key (key , object_roots ):
651678 return False
652679 full_key = self ._translate_key_to_full (key )
653680 return (
@@ -692,11 +719,10 @@ def keys(self):
692719 all_keys = {key for key in all_keys if not self ._is_vlmeta_key (key )}
693720
694721 # Filter out object-internal keys
695- all_keys = {key for key in all_keys if not self ._is_object_internal_key (key )}
696-
697- # Add object roots (they are not stored as DictStore keys themselves)
698722 object_roots = self ._effective_object_roots ()
723+ all_keys = {key for key in all_keys if not self ._is_object_internal_key (key , object_roots )}
699724
725+ # Add object roots (they are not stored as DictStore keys themselves)
700726 # Build structural paths from both data leaves and object root keys
701727 all_with_roots = all_keys | object_roots
702728 structural_keys = set ()
0 commit comments