1- use hashbrown:: hash_map :: RawEntryMut ;
1+ use hashbrown:: { HashTable , hash_table :: Entry } ;
22use rustc_hash:: FxHasher ;
3- use std:: hash:: { BuildHasherDefault , Hash , Hasher } ;
3+ use std:: hash:: { Hash , Hasher } ;
44
55use crate :: {
66 GreenNode , GreenNodeData , GreenToken , GreenTokenData , NodeOrToken , SyntaxKind ,
@@ -9,11 +9,6 @@ use crate::{
99
1010use super :: element:: GreenElement ;
1111
12- type HashMap < K , V > = hashbrown:: HashMap < K , V , BuildHasherDefault < FxHasher > > ;
13-
14- #[ derive( Debug ) ]
15- struct NoHash < T > ( T ) ;
16-
1712/// Interner for GreenTokens and GreenNodes
1813// XXX: the impl is a bit tricky. As usual when writing interners, we want to
1914// store all values in one HashSet.
@@ -25,18 +20,17 @@ struct NoHash<T>(T);
2520// That means that computing the hash naively is wasteful -- we just *know*
2621// hashes of children, and we can re-use those.
2722//
28- // So here we use *raw* API of hashbrown and provide the hashes manually,
23+ // So here we use `HashTable` of hashbrown and provide the hashes manually,
2924// instead of going via a `Hash` impl. Our manual `Hash` and the
3025// `#[derive(Hash)]` are actually different! At some point we had a fun bug,
3126// where we accidentally mixed the two hashes, which made the cache much less
3227// efficient.
3328//
34- // To fix that, we additionally wrap the data in `NoHash` wrapper, to make sure
35- // we don't accidentally use the wrong hash!
29+ // `HashTable` prevents us to accidentally use the wrong hash!
3630#[ derive( Default , Debug ) ]
3731pub struct NodeCache {
38- nodes : HashMap < NoHash < GreenNode > , ( ) > ,
39- tokens : HashMap < NoHash < GreenToken > , ( ) > ,
32+ nodes : HashTable < GreenNode > ,
33+ tokens : HashTable < GreenToken > ,
4034}
4135
4236fn token_hash ( token : & GreenTokenData ) -> u64 {
@@ -103,26 +97,30 @@ impl NodeCache {
10397 // For example, all `#[inline]` in this file share the same green node!
10498 // For `libsyntax/parse/parser.rs`, measurements show that deduping saves
10599 // 17% of the memory for green nodes!
106- let entry = self . nodes . raw_entry_mut ( ) . from_hash ( hash, |node| {
107- node. 0 . kind ( ) == kind && node. 0 . children ( ) . len ( ) == children_ref. len ( ) && {
108- let lhs = node. 0 . children ( ) ;
109- let rhs = children_ref. iter ( ) . map ( |( _, it) | it. as_deref ( ) ) ;
100+ let entry = self . nodes . entry (
101+ hash,
102+ |node| {
103+ node. kind ( ) == kind && node. children ( ) . len ( ) == children_ref. len ( ) && {
104+ let lhs = node. children ( ) ;
105+ let rhs = children_ref. iter ( ) . map ( |( _, it) | it. as_deref ( ) ) ;
110106
111- let lhs = lhs. map ( element_id) ;
112- let rhs = rhs. map ( element_id) ;
107+ let lhs = lhs. map ( element_id) ;
108+ let rhs = rhs. map ( element_id) ;
113109
114- lhs. eq ( rhs)
115- }
116- } ) ;
110+ lhs. eq ( rhs)
111+ }
112+ } ,
113+ |node| node_hash ( node) ,
114+ ) ;
117115
118116 let node = match entry {
119- RawEntryMut :: Occupied ( entry) => {
117+ Entry :: Occupied ( entry) => {
120118 drop ( children. drain ( first_child..) ) ;
121- entry. key ( ) . 0 . clone ( )
119+ entry. get ( ) . clone ( )
122120 }
123- RawEntryMut :: Vacant ( entry) => {
121+ Entry :: Vacant ( entry) => {
124122 let node = build_node ( children) ;
125- entry. insert_with_hasher ( hash , NoHash ( node. clone ( ) ) , ( ) , |n| node_hash ( & n . 0 ) ) ;
123+ entry. insert ( node. clone ( ) ) ;
126124 node
127125 }
128126 } ;
@@ -138,16 +136,17 @@ impl NodeCache {
138136 h. finish ( )
139137 } ;
140138
141- let entry = self
142- . tokens
143- . raw_entry_mut ( )
144- . from_hash ( hash, |token| token. 0 . kind ( ) == kind && token. 0 . text ( ) == text) ;
139+ let entry = self . tokens . entry (
140+ hash,
141+ |token| token. kind ( ) == kind && token. text ( ) == text,
142+ |token| token_hash ( token) ,
143+ ) ;
145144
146145 let token = match entry {
147- RawEntryMut :: Occupied ( entry) => entry. key ( ) . 0 . clone ( ) ,
148- RawEntryMut :: Vacant ( entry) => {
146+ Entry :: Occupied ( entry) => entry. get ( ) . clone ( ) ,
147+ Entry :: Vacant ( entry) => {
149148 let token = GreenToken :: new ( kind, text) ;
150- entry. insert_with_hasher ( hash , NoHash ( token. clone ( ) ) , ( ) , |t| token_hash ( & t . 0 ) ) ;
149+ entry. insert ( token. clone ( ) ) ;
151150 token
152151 }
153152 } ;
0 commit comments