@@ -25,7 +25,7 @@ pub enum WildcardAccessLevel {
2525 Write ,
2626}
2727
28- /// Were relative to the node the access happened from .
28+ /// Where the access happened relative to the current node .
2929#[ derive( Clone , Copy , Debug , PartialEq , Eq ) ]
3030pub enum WildcardAccessRelatedness {
3131 /// The access definitively happened through a local node.
@@ -59,8 +59,8 @@ pub struct WildcardState {
5959 /// The maximum access level that could happen from an exposed node
6060 /// that is foreign to this node.
6161 ///
62- /// This is calculated as the `max()` of parents `max_foreign_access`,
63- /// `exposed_as` and its siblings `max_local_access()`.
62+ /// This is calculated as the `max()` of the parent's `max_foreign_access`,
63+ /// `exposed_as` and the siblings' `max_local_access()`.
6464 max_foreign_access : WildcardAccessLevel ,
6565 /// At what access level this node itself is exposed.
6666 exposed_as : WildcardAccessLevel ,
@@ -76,8 +76,8 @@ impl Debug for WildcardState {
7676}
7777impl WildcardState {
7878 /// The maximum access level that could happen from an exposed
79- /// node that is a local to this node.
80- pub fn max_local_access ( & self ) -> WildcardAccessLevel {
79+ /// node that is local to this node.
80+ fn max_local_access ( & self ) -> WildcardAccessLevel {
8181 use WildcardAccessLevel :: * ;
8282 max (
8383 self . exposed_as ,
@@ -100,7 +100,7 @@ impl WildcardState {
100100 }
101101
102102 /// From where relative to the node with this wildcard info a read access could happen.
103- pub fn read_access_relatedness ( & self ) -> Option < WildcardAccessRelatedness > {
103+ fn read_access_relatedness ( & self ) -> Option < WildcardAccessRelatedness > {
104104 let has_foreign = self . max_foreign_access >= WildcardAccessLevel :: Read ;
105105 let has_local = self . max_local_access ( ) >= WildcardAccessLevel :: Read ;
106106 use WildcardAccessRelatedness as E ;
@@ -113,7 +113,7 @@ impl WildcardState {
113113 }
114114
115115 /// From where relative to the node with this wildcard info a write access could happen.
116- pub fn write_access_relatedness ( & self ) -> Option < WildcardAccessRelatedness > {
116+ fn write_access_relatedness ( & self ) -> Option < WildcardAccessRelatedness > {
117117 let has_foreign = self . max_foreign_access == WildcardAccessLevel :: Write ;
118118 let has_local = self . max_local_access ( ) == WildcardAccessLevel :: Write ;
119119 use WildcardAccessRelatedness as E ;
@@ -129,7 +129,7 @@ impl WildcardState {
129129 /// wildcard info.
130130 /// The new node doesn't have any child reads/writes, but calculates max_foreign_access
131131 /// from its parent.
132- pub fn get_new_child ( & self ) -> Self {
132+ pub fn for_new_child ( & self ) -> Self {
133133 Self {
134134 max_foreign_access : max ( self . max_foreign_access , self . max_local_access ( ) ) ,
135135 ..Default :: default ( )
@@ -147,9 +147,10 @@ impl WildcardState {
147147 /// of at least `read`/`write`
148148 ///
149149 /// * `new_foreign_access`, `old_foreign_access`:
150- /// The max possible access level, that is foreign to all `children`.
150+ /// The max possible access level that is foreign to all `children`
151+ /// (i.e., it is not local to *any* of them).
151152 /// This can be calculated as the max of the parent's `exposed_as()`, `max_foreign_access`
152- /// and of all `max_local_access()` of any nodes with the same parent, that are
153+ /// and of all `max_local_access()` of any nodes with the same parent that are
153154 /// not listed in `children`.
154155 ///
155156 /// This access level changed from `old` to `new`, which is why we need to
@@ -172,9 +173,9 @@ impl WildcardState {
172173 }
173174
174175 // We need to consider that the children's `max_local_access()` affect each
175- // others `max_foreign_access`, but do not affect their own `max_foreign_access`.
176+ // other's `max_foreign_access`, but do not affect their own `max_foreign_access`.
176177
177- // The new `max_foreign_acces` for children with `max_locala_access ()==Write`.
178+ // The new `max_foreign_acces` for children with `max_local_access ()==Write`.
178179 let write_foreign_access = max (
179180 new_foreign_access,
180181 if child_writes > 1 {
@@ -263,8 +264,6 @@ impl WildcardState {
263264 if old_exposed_as == new_exposed_as {
264265 return ;
265266 }
266- // Whether we are upgrading or downgrading the allowed access rights.
267- let is_upgrade = old_exposed_as < new_exposed_as;
268267
269268 let src_old_local_access = src_state. max_local_access ( ) ;
270269
@@ -273,15 +272,20 @@ impl WildcardState {
273272 let src_new_local_access = src_state. max_local_access ( ) ;
274273
275274 // Stack of nodes for which the max_foreign_access field needs to be updated.
275+ // Will be filled with the children of this node and its parents children before
276+ // we begin downwards traversal.
276277 let mut stack: Vec < ( UniIndex , WildcardAccessLevel ) > = Vec :: new ( ) ;
277278
278- // Update the direct children of this node.
279+ // Add the direct children of this node to the stack .
279280 {
280281 let node = nodes. get ( id) . unwrap ( ) ;
281282 Self :: push_relevant_children (
282283 & mut stack,
284+ // new_foreign_access
283285 max ( src_state. max_foreign_access , new_exposed_as) ,
286+ // old_foreign_access
284287 max ( src_state. max_foreign_access , old_exposed_as) ,
288+ // Consider all children.
285289 src_state. child_reads ,
286290 src_state. child_writes ,
287291 node. children . iter ( ) . copied ( ) ,
@@ -291,7 +295,7 @@ impl WildcardState {
291295 // We need to propagate the tracking info up the tree, for this we traverse up the parents.
292296 // We can skip propagating info to the parent and siblings of a node if its access didn't change.
293297 {
294- // The child from which we came from .
298+ // The child from which we came.
295299 let mut child = id;
296300 // This is the `max_local_access()` of the child we came from, before this update...
297301 let mut old_child_access = src_old_local_access;
@@ -305,28 +309,15 @@ impl WildcardState {
305309 let old_parent_state = parent_state. clone ( ) ;
306310 use WildcardAccessLevel :: * ;
307311 // Updating this node's tracking state for its children.
308- if is_upgrade {
309- if new_child_access == Write {
310- // None -> Write
311- // Read -> Write
312- parent_state. child_writes += 1 ;
313- }
314- if old_child_access == None {
315- // None -> Read
316- // None -> Write
317- parent_state. child_reads += 1 ;
318- }
319- } else {
320- if old_child_access == Write {
321- // Write -> None
322- // Write -> Read
323- parent_state. child_writes -= 1 ;
324- }
325- if new_child_access == None {
326- // Read -> None
327- // Write -> None
328- parent_state. child_reads -= 1 ;
329- }
312+ match ( old_child_access, new_child_access) {
313+ ( None | Read , Write ) => parent_state. child_writes += 1 ,
314+ ( Write , None | Read ) => parent_state. child_writes -= 1 ,
315+ _ => { }
316+ }
317+ match ( old_child_access, new_child_access) {
318+ ( None , Read | Write ) => parent_state. child_reads += 1 ,
319+ ( Read | Write , None ) => parent_state. child_reads -= 1 ,
320+ _ => { }
330321 }
331322
332323 let old_parent_local_access = old_parent_state. max_local_access ( ) ;
@@ -341,19 +332,22 @@ impl WildcardState {
341332 // it as part of the foreign access.
342333
343334 // it doesnt matter wether we read these from old or new
344- let constant_factors =
335+ let parent_access =
345336 max ( parent_state. exposed_as , parent_state. max_foreign_access ) ;
346337
347- // `state` contains the correct child_writes/reads counts for just the
348- // siblings excluding `child`.
349- let state = if is_upgrade { & old_parent_state } else { parent_state } ;
350-
338+ let sibling_reads =
339+ parent_state . child_reads - if new_child_access >= Read { 1 } else { 0 } ;
340+ let sibling_writes =
341+ parent_state . child_writes - if new_child_access == Write { 1 } else { 0 } ;
351342 Self :: push_relevant_children (
352343 & mut stack,
353- max ( constant_factors, new_child_access) ,
354- max ( constant_factors, old_child_access) ,
355- state. child_reads ,
356- state. child_writes ,
344+ // new_foreign_access
345+ max ( parent_access, new_child_access) ,
346+ // old_foreign_access
347+ max ( parent_access, old_child_access) ,
348+ // Consider only siblings of child.
349+ sibling_reads,
350+ sibling_writes,
357351 parent_node. children . iter ( ) . copied ( ) . filter ( |id| child != * id) ,
358352 wildcard_accesses,
359353 ) ;
@@ -368,7 +362,7 @@ impl WildcardState {
368362 child = parent_id;
369363 }
370364 }
371- // Traverses up the tree to update max_foreign_access fields of children and cousins who need to be updated.
365+ // Traverses down the tree to update max_foreign_access fields of children and cousins who need to be updated.
372366 while let Some ( ( id, new_access) ) = stack. pop ( ) {
373367 let node = nodes. get ( id) . unwrap ( ) ;
374368 let mut entry = wildcard_accesses. entry ( id) ;
@@ -379,8 +373,11 @@ impl WildcardState {
379373
380374 Self :: push_relevant_children (
381375 & mut stack,
376+ // new_foreign_access
382377 max ( state. exposed_as , new_access) ,
378+ // old_foreign_access
383379 max ( state. exposed_as , old_access) ,
380+ // Consider all children.
384381 state. child_reads ,
385382 state. child_writes ,
386383 node. children . iter ( ) . copied ( ) ,
@@ -406,9 +403,13 @@ impl Tree {
406403 let protected = protected_tags. contains_key ( & tag) ;
407404 // TODO: Only initialize neccessary ranges.
408405 for ( _, loc) in self . locations . iter_mut_all ( ) {
409- let perm = * loc. perms . entry ( id) . or_insert ( node. default_location_state ( ) ) ;
406+ let perm = loc
407+ . perms
408+ . get ( id)
409+ . map ( |p| p. permission ( ) )
410+ . unwrap_or_else ( || node. default_location_state ( ) . permission ( ) ) ;
410411
411- let access_type = perm. permission ( ) . strongest_allowed_child_access ( protected) ;
412+ let access_type = perm. strongest_allowed_child_access ( protected) ;
412413 WildcardState :: update_exposure (
413414 id,
414415 access_type,
@@ -417,7 +418,9 @@ impl Tree {
417418 ) ;
418419 }
419420 }
420- pub ( super ) fn visit_wildcards ( & self , visit : & mut VisitWith < ' _ > ) {
421+ /// Visit all tags through which a wilcard access could happen.
422+ /// Used for GC.
423+ pub ( super ) fn gc_visit_wildcards ( & self , visit : & mut VisitWith < ' _ > ) {
421424 for ( _, loc) in self . locations . iter_all ( ) {
422425 let mut stack = vec ! [ self . root] ;
423426 let mut has_exposed = false ;
@@ -427,8 +430,7 @@ impl Tree {
427430 if node. is_exposed
428431 && let Some ( perm) = loc. perms . get ( id)
429432 {
430- // If the node is already protected, then it gets already visited
431- // through the protector. So we can assume `protected=false`.
433+ // The protector doesn't matter for this check, as it never reduces access level to None.
432434 let access_level = perm. permission ( ) . strongest_allowed_child_access ( false ) ;
433435 if access_level != WildcardAccessLevel :: None {
434436 visit ( None , Some ( node. tag ) )
@@ -486,7 +488,7 @@ impl WildcardState {
486488 }
487489
488490 // Checks if accesses is empty.
489- if ! wildcard_accesses. is_initialized ( ) {
491+ if wildcard_accesses. is_empty ( ) {
490492 return ;
491493 }
492494
@@ -497,6 +499,8 @@ impl WildcardState {
497499
498500 let access = wildcard_accesses. get ( id) . unwrap ( ) ;
499501
502+ // The foreign wildcard accesses possible at a node are determined by which accesses
503+ // can originate from their siblings, their parent, and from above their parent.
500504 let expected_max_foreign_access = if let Some ( parent) = node. parent {
501505 let parent_node = nodes. get ( parent) . unwrap ( ) ;
502506 let parent_state = wildcard_accesses. get ( parent) . unwrap ( ) ;
@@ -517,6 +521,8 @@ impl WildcardState {
517521 WildcardAccessLevel :: None
518522 } ;
519523
524+ // Count how many children can be the source of wildcard reads or writes
525+ // (either directly, or via their children).
520526 let child_accesses = node. children . iter ( ) . copied ( ) . map ( |child| {
521527 let state = wildcard_accesses. get ( child) . unwrap ( ) ;
522528 state. max_local_access ( )
0 commit comments