@@ -73,44 +73,41 @@ impl FixedSizeEncoding for u32 {
7373/// (e.g. while visiting the definitions of a crate), and on-demand decoding
7474/// of specific indices (e.g. queries for per-definition data).
7575/// Similar to `Vec<Lazy<T>>`, but with zero-copy decoding.
76+ // FIXME(eddyb) newtype `[u8]` here, such that `Box<Table<T>>` would be used
77+ // when building it, and `Lazy<Table<T>>` or `&Table<T>` when reading it.
78+ // Sadly, that doesn't work for `DefPerTable`, which is `(Table<T>, Table<T>)`,
79+ // and so would need two lengths in its metadata, which is not supported yet.
7680crate struct Table < T : LazyMeta < Meta = ( ) > > {
77- positions : Vec < u8 > ,
81+ bytes : Vec < u8 > ,
7882 _marker : PhantomData < T > ,
7983}
8084
8185impl < T : LazyMeta < Meta = ( ) > > Table < T > {
82- crate fn new ( max_index : usize ) -> Self {
86+ crate fn new ( len : usize ) -> Self {
8387 Table {
84- positions : vec ! [ 0 ; max_index * 4 ] ,
88+ bytes : vec ! [ 0 ; len * 4 ] ,
8589 _marker : PhantomData ,
8690 }
8791 }
8892
89- crate fn record ( & mut self , def_id : DefId , entry : Lazy < T > ) {
90- assert ! ( def_id. is_local( ) ) ;
91- self . record_index ( def_id. index , entry) ;
92- }
93-
94- crate fn record_index ( & mut self , item : DefIndex , entry : Lazy < T > ) {
93+ crate fn record ( & mut self , i : usize , entry : Lazy < T > ) {
9594 let position: u32 = entry. position . get ( ) . try_into ( ) . unwrap ( ) ;
96- let array_index = item. index ( ) ;
9795
98- let positions = & mut self . positions ;
99- assert ! ( u32 :: read_from_bytes_at( positions, array_index) == 0 ,
100- "recorded position for item {:?} twice, first at {:?} and now at {:?}" ,
101- item,
102- u32 :: read_from_bytes_at( positions, array_index) ,
96+ assert ! ( u32 :: read_from_bytes_at( & self . bytes, i) == 0 ,
97+ "recorded position for index {:?} twice, first at {:?} and now at {:?}" ,
98+ i,
99+ u32 :: read_from_bytes_at( & self . bytes, i) ,
103100 position) ;
104101
105- position. write_to_bytes_at ( positions , array_index )
102+ position. write_to_bytes_at ( & mut self . bytes , i )
106103 }
107104
108105 crate fn encode ( & self , buf : & mut Encoder ) -> Lazy < Self > {
109106 let pos = buf. position ( ) ;
110- buf. emit_raw_bytes ( & self . positions ) ;
107+ buf. emit_raw_bytes ( & self . bytes ) ;
111108 Lazy :: from_position_and_meta (
112109 NonZeroUsize :: new ( pos as usize ) . unwrap ( ) ,
113- self . positions . len ( ) / 4 ,
110+ self . bytes . len ( ) ,
114111 )
115112 }
116113}
@@ -119,22 +116,62 @@ impl<T: LazyMeta<Meta = ()>> LazyMeta for Table<T> {
119116 type Meta = usize ;
120117
121118 fn min_size ( len : usize ) -> usize {
122- len * 4
119+ len
123120 }
124121}
125122
126123impl < T : Encodable > Lazy < Table < T > > {
127- /// Given the metadata, extract out the offset of a particular
128- /// DefIndex (if any).
124+ /// Given the metadata, extract out the offset of a particular index (if any).
129125 #[ inline( never) ]
130- crate fn lookup ( & self , bytes : & [ u8 ] , def_index : DefIndex ) -> Option < Lazy < T > > {
131- debug ! ( "Table::lookup: index={:?} len={:?}" ,
132- def_index,
133- self . meta) ;
126+ crate fn lookup ( & self , bytes : & [ u8 ] , i : usize ) -> Option < Lazy < T > > {
127+ debug ! ( "Table::lookup: index={:?} len={:?}" , i, self . meta) ;
134128
135- let bytes = & bytes[ self . position . get ( ) ..] [ ..self . meta * 4 ] ;
136- let position = u32:: read_from_bytes_at ( bytes, def_index . index ( ) ) ;
129+ let bytes = & bytes[ self . position . get ( ) ..] [ ..self . meta ] ;
130+ let position = u32:: read_from_bytes_at ( bytes, i ) ;
137131 debug ! ( "Table::lookup: position={:?}" , position) ;
132+
138133 NonZeroUsize :: new ( position as usize ) . map ( Lazy :: from_position)
139134 }
140135}
136+
137+
138+ /// Per-definition table, similar to `Table` but keyed on `DefIndex`.
139+ // FIXME(eddyb) replace by making `Table` behave like `IndexVec`,
140+ // and by using `newtype_index!` to define `DefIndex`.
141+ crate struct PerDefTable < T : LazyMeta < Meta = ( ) > > ( Table < T > ) ;
142+
143+ impl < T : LazyMeta < Meta = ( ) > > PerDefTable < T > {
144+ crate fn new ( def_index_count : usize ) -> Self {
145+ PerDefTable ( Table :: new ( def_index_count) )
146+ }
147+
148+ crate fn record ( & mut self , def_id : DefId , entry : Lazy < T > ) {
149+ assert ! ( def_id. is_local( ) ) ;
150+ self . 0 . record ( def_id. index . index ( ) , entry) ;
151+ }
152+
153+ crate fn encode ( & self , buf : & mut Encoder ) -> Lazy < Self > {
154+ let lazy = self . 0 . encode ( buf) ;
155+ Lazy :: from_position_and_meta ( lazy. position , lazy. meta )
156+ }
157+ }
158+
159+ impl < T : LazyMeta < Meta = ( ) > > LazyMeta for PerDefTable < T > {
160+ type Meta = <Table < T > as LazyMeta >:: Meta ;
161+
162+ fn min_size ( meta : Self :: Meta ) -> usize {
163+ Table :: < T > :: min_size ( meta)
164+ }
165+ }
166+
167+ impl < T : Encodable > Lazy < PerDefTable < T > > {
168+ fn as_table ( & self ) -> Lazy < Table < T > > {
169+ Lazy :: from_position_and_meta ( self . position , self . meta )
170+ }
171+
172+ /// Given the metadata, extract out the offset of a particular DefIndex (if any).
173+ #[ inline( never) ]
174+ crate fn lookup ( & self , bytes : & [ u8 ] , def_index : DefIndex ) -> Option < Lazy < T > > {
175+ self . as_table ( ) . lookup ( bytes, def_index. index ( ) )
176+ }
177+ }
0 commit comments