@@ -11,7 +11,7 @@ use crate::model::{
1111 } ,
1212 definitions:: { Definition , Mixin , Receiver } ,
1313 graph:: { CLASS_ID , Graph , MODULE_ID , OBJECT_ID } ,
14- identity_maps:: { IdentityHashMap , IdentityHashSet } ,
14+ identity_maps:: { IdentityHashBuilder , IdentityHashMap , IdentityHashSet } ,
1515 ids:: { DeclarationId , DefinitionId , NameId , ReferenceId , StringId } ,
1616 name:: { Name , NameRef , ParentScope } ,
1717} ;
@@ -1517,63 +1517,68 @@ impl<'a> Resolver<'a> {
15171517 /// # Panics
15181518 ///
15191519 /// Will panic if there is inconsistent data in the graph
1520- fn name_depth ( name : & NameRef , names : & IdentityHashMap < NameId , NameRef > ) -> u32 {
1521- if name. parent_scope ( ) . is_top_level ( ) {
1522- return 1 ;
1520+ fn name_depth (
1521+ name_id : NameId ,
1522+ names : & IdentityHashMap < NameId , NameRef > ,
1523+ cache : & mut IdentityHashMap < NameId , u32 > ,
1524+ ) -> u32 {
1525+ if let Some ( & depth) = cache. get ( & name_id) {
1526+ return depth;
15231527 }
15241528
1525- let parent_depth = name. parent_scope ( ) . map_or ( 0 , |id| {
1526- let name_ref = names. get ( id) . unwrap ( ) ;
1527- Self :: name_depth ( name_ref, names)
1528- } ) ;
1529+ let name = names. get ( & name_id) . unwrap ( ) ;
15291530
1530- let nesting_depth = name. nesting ( ) . map_or ( 0 , |id| {
1531- let name_ref = names. get ( & id) . unwrap ( ) ;
1532- Self :: name_depth ( name_ref, names)
1533- } ) ;
1531+ let depth = if name. parent_scope ( ) . is_top_level ( ) {
1532+ 1
1533+ } else {
1534+ let parent_depth = name. parent_scope ( ) . map_or ( 0 , |id| Self :: name_depth ( * id, names, cache) ) ;
1535+
1536+ let nesting_depth = name. nesting ( ) . map_or ( 0 , |id| Self :: name_depth ( id, names, cache) ) ;
1537+
1538+ parent_depth + nesting_depth + 1
1539+ } ;
1540+
1541+ cache. insert ( name_id, depth) ;
1542+ depth
1543+ }
1544+
1545+ /// Pre-compute name depths for all names in a single pass. Each name's depth is computed once
1546+ /// and cached, avoiding redundant recursive walks during sorting.
1547+ fn compute_name_depths ( names : & IdentityHashMap < NameId , NameRef > ) -> IdentityHashMap < NameId , u32 > {
1548+ let mut cache = IdentityHashMap :: with_capacity_and_hasher ( names. len ( ) , IdentityHashBuilder ) ;
1549+
1550+ for & name_id in names. keys ( ) {
1551+ Self :: name_depth ( name_id, names, & mut cache) ;
1552+ }
15341553
1535- parent_depth + nesting_depth + 1
1554+ cache
15361555 }
15371556
15381557 fn prepare_units ( & mut self ) -> Vec < DefinitionId > {
15391558 let estimated_length = self . graph . definitions ( ) . len ( ) / 2 ;
15401559 let mut definitions = Vec :: with_capacity ( estimated_length) ;
15411560 let mut others = Vec :: with_capacity ( estimated_length) ;
15421561 let names = self . graph . names ( ) ;
1562+ let depths = Self :: compute_name_depths ( names) ;
15431563
15441564 for ( id, definition) in self . graph . definitions ( ) {
15451565 let uri = self . graph . documents ( ) . get ( definition. uri_id ( ) ) . unwrap ( ) . uri ( ) ;
15461566
15471567 match definition {
15481568 Definition :: Class ( def) => {
1549- definitions. push ( (
1550- Unit :: Definition ( * id) ,
1551- ( names. get ( def. name_id ( ) ) . unwrap ( ) , uri, definition. offset ( ) ) ,
1552- ) ) ;
1569+ definitions. push ( ( Unit :: Definition ( * id) , ( * def. name_id ( ) , uri, definition. offset ( ) ) ) ) ;
15531570 }
15541571 Definition :: Module ( def) => {
1555- definitions. push ( (
1556- Unit :: Definition ( * id) ,
1557- ( names. get ( def. name_id ( ) ) . unwrap ( ) , uri, definition. offset ( ) ) ,
1558- ) ) ;
1572+ definitions. push ( ( Unit :: Definition ( * id) , ( * def. name_id ( ) , uri, definition. offset ( ) ) ) ) ;
15591573 }
15601574 Definition :: Constant ( def) => {
1561- definitions. push ( (
1562- Unit :: Definition ( * id) ,
1563- ( names. get ( def. name_id ( ) ) . unwrap ( ) , uri, definition. offset ( ) ) ,
1564- ) ) ;
1575+ definitions. push ( ( Unit :: Definition ( * id) , ( * def. name_id ( ) , uri, definition. offset ( ) ) ) ) ;
15651576 }
15661577 Definition :: ConstantAlias ( def) => {
1567- definitions. push ( (
1568- Unit :: Definition ( * id) ,
1569- ( names. get ( def. name_id ( ) ) . unwrap ( ) , uri, definition. offset ( ) ) ,
1570- ) ) ;
1578+ definitions. push ( ( Unit :: Definition ( * id) , ( * def. name_id ( ) , uri, definition. offset ( ) ) ) ) ;
15711579 }
15721580 Definition :: SingletonClass ( def) => {
1573- definitions. push ( (
1574- Unit :: Definition ( * id) ,
1575- ( names. get ( def. name_id ( ) ) . unwrap ( ) , uri, definition. offset ( ) ) ,
1576- ) ) ;
1581+ definitions. push ( ( Unit :: Definition ( * id) , ( * def. name_id ( ) , uri, definition. offset ( ) ) ) ) ;
15771582 }
15781583 _ => {
15791584 others. push ( * id) ;
@@ -1583,8 +1588,8 @@ impl<'a> Resolver<'a> {
15831588
15841589 // Sort namespaces based on their name complexity so that simpler names are always first
15851590 // When the depth is the same, sort by URI and offset to maintain determinism
1586- definitions. sort_by ( |( _, ( name_a, uri_a, offset_a) ) , ( _, ( name_b, uri_b, offset_b) ) | {
1587- ( Self :: name_depth ( name_a, names ) , uri_a, offset_a) . cmp ( & ( Self :: name_depth ( name_b, names ) , uri_b, offset_b) )
1591+ definitions. sort_unstable_by ( |( _, ( name_a, uri_a, offset_a) ) , ( _, ( name_b, uri_b, offset_b) ) | {
1592+ ( depths . get ( name_a) . unwrap ( ) , uri_a, offset_a) . cmp ( & ( depths . get ( name_b) . unwrap ( ) , uri_b, offset_b) )
15881593 } ) ;
15891594
15901595 let mut const_refs = self
@@ -1596,14 +1601,14 @@ impl<'a> Resolver<'a> {
15961601
15971602 (
15981603 Unit :: ConstantRef ( * id) ,
1599- ( names . get ( constant_ref. name_id ( ) ) . unwrap ( ) , uri, constant_ref. offset ( ) ) ,
1604+ ( * constant_ref. name_id ( ) , uri, constant_ref. offset ( ) ) ,
16001605 )
16011606 } )
16021607 . collect :: < Vec < _ > > ( ) ;
16031608
16041609 // Sort constant references based on their name complexity so that simpler names are always first
1605- const_refs. sort_by ( |( _, ( name_a, uri_a, offset_a) ) , ( _, ( name_b, uri_b, offset_b) ) | {
1606- ( Self :: name_depth ( name_a, names ) , uri_a, offset_a) . cmp ( & ( Self :: name_depth ( name_b, names ) , uri_b, offset_b) )
1610+ const_refs. sort_unstable_by ( |( _, ( name_a, uri_a, offset_a) ) , ( _, ( name_b, uri_b, offset_b) ) | {
1611+ ( depths . get ( name_a) . unwrap ( ) , uri_a, offset_a) . cmp ( & ( depths . get ( name_b) . unwrap ( ) , uri_b, offset_b) )
16071612 } ) ;
16081613
16091614 self . unit_queue
@@ -1998,18 +2003,19 @@ mod tests {
19982003 "
19992004 } ) ;
20002005
2001- let mut names = context. graph ( ) . names ( ) . values ( ) . collect :: < Vec < _ > > ( ) ;
2006+ let depths = Resolver :: compute_name_depths ( context. graph ( ) . names ( ) ) ;
2007+ let mut names = context. graph ( ) . names ( ) . iter ( ) . collect :: < Vec < _ > > ( ) ;
20022008 assert_eq ! ( 10 , names. len( ) ) ;
20032009
2004- names. sort_by_key ( |a| Resolver :: name_depth ( a , context . graph ( ) . names ( ) ) ) ;
2010+ names. sort_by_key ( |( id , _ ) | depths . get ( id ) . unwrap ( ) ) ;
20052011
20062012 assert_eq ! (
20072013 [
20082014 "Top" , "Foo" , "Qux" , "AfterTop" , "Bar" , "Baz" , "Zip" , "Zap" , "Zop" , "Boop"
20092015 ] ,
20102016 names
20112017 . iter( )
2012- . map( |n | context. graph( ) . strings( ) . get( n. str ( ) ) . unwrap( ) . as_str( ) )
2018+ . map( |( _ , n ) | context. graph( ) . strings( ) . get( n. str ( ) ) . unwrap( ) . as_str( ) )
20132019 . collect:: <Vec <_>>( )
20142020 . as_slice( )
20152021 ) ;
0 commit comments