@@ -73,44 +73,41 @@ impl FixedSizeEncoding for u32 {
73
73
/// (e.g. while visiting the definitions of a crate), and on-demand decoding
74
74
/// of specific indices (e.g. queries for per-definition data).
75
75
/// 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.
76
80
crate struct Table < T : LazyMeta < Meta = ( ) > > {
77
- positions : Vec < u8 > ,
81
+ bytes : Vec < u8 > ,
78
82
_marker : PhantomData < T > ,
79
83
}
80
84
81
85
impl < T : LazyMeta < Meta = ( ) > > Table < T > {
82
- crate fn new ( max_index : usize ) -> Self {
86
+ crate fn new ( len : usize ) -> Self {
83
87
Table {
84
- positions : vec ! [ 0 ; max_index * 4 ] ,
88
+ bytes : vec ! [ 0 ; len * 4 ] ,
85
89
_marker : PhantomData ,
86
90
}
87
91
}
88
92
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 > ) {
95
94
let position: u32 = entry. position . get ( ) . try_into ( ) . unwrap ( ) ;
96
- let array_index = item. index ( ) ;
97
95
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) ,
103
100
position) ;
104
101
105
- position. write_to_bytes_at ( positions , array_index )
102
+ position. write_to_bytes_at ( & mut self . bytes , i )
106
103
}
107
104
108
105
crate fn encode ( & self , buf : & mut Encoder ) -> Lazy < Self > {
109
106
let pos = buf. position ( ) ;
110
- buf. emit_raw_bytes ( & self . positions ) ;
107
+ buf. emit_raw_bytes ( & self . bytes ) ;
111
108
Lazy :: from_position_and_meta (
112
109
NonZeroUsize :: new ( pos as usize ) . unwrap ( ) ,
113
- self . positions . len ( ) / 4 ,
110
+ self . bytes . len ( ) ,
114
111
)
115
112
}
116
113
}
@@ -119,22 +116,62 @@ impl<T: LazyMeta<Meta = ()>> LazyMeta for Table<T> {
119
116
type Meta = usize ;
120
117
121
118
fn min_size ( len : usize ) -> usize {
122
- len * 4
119
+ len
123
120
}
124
121
}
125
122
126
123
impl < 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).
129
125
#[ 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) ;
134
128
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 ) ;
137
131
debug ! ( "Table::lookup: position={:?}" , position) ;
132
+
138
133
NonZeroUsize :: new ( position as usize ) . map ( Lazy :: from_position)
139
134
}
140
135
}
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