@@ -19,27 +19,28 @@ import lib.llvm.False;
19
19
const uint tag_paths = 0x01 u;
20
20
const uint tag_items = 0x02 u;
21
21
22
- const uint tag_paths_name = 0x03 u;
23
- const uint tag_paths_item = 0x04 u;
24
- const uint tag_paths_mod = 0x05 u;
25
-
26
- const uint tag_def_id = 0x06 u;
27
-
28
- const uint tag_items_data = 0x07 u;
29
- const uint tag_items_data_item = 0x08 u;
30
- const uint tag_items_data_item_kind = 0x09 u;
31
- const uint tag_items_data_item_ty_param = 0x0a u;
32
- const uint tag_items_data_item_type = 0x0b u;
33
- const uint tag_items_data_item_symbol = 0x0c u;
34
- const uint tag_items_data_item_variant = 0x0d u;
35
- const uint tag_items_data_item_tag_id = 0x0e u;
36
- const uint tag_items_data_item_obj_type_id = 0x0f u;
37
-
38
- const uint tag_items_index = 0x10 u;
39
- const uint tag_items_index_buckets = 0x11 u;
40
- const uint tag_items_index_buckets_bucket = 0x12 u;
41
- const uint tag_items_index_buckets_bucket_elt = 0x13 u;
42
- const uint tag_items_index_table = 0x14 u;
22
+ const uint tag_paths_data = 0x03 u;
23
+ const uint tag_paths_data_name = 0x04 u;
24
+ const uint tag_paths_data_item = 0x05 u;
25
+ const uint tag_paths_data_mod = 0x06 u;
26
+
27
+ const uint tag_def_id = 0x07 u;
28
+
29
+ const uint tag_items_data = 0x08 u;
30
+ const uint tag_items_data_item = 0x09 u;
31
+ const uint tag_items_data_item_kind = 0x0a u;
32
+ const uint tag_items_data_item_ty_param = 0x0b u;
33
+ const uint tag_items_data_item_type = 0x0c u;
34
+ const uint tag_items_data_item_symbol = 0x0d u;
35
+ const uint tag_items_data_item_variant = 0x0e u;
36
+ const uint tag_items_data_item_tag_id = 0x0f u;
37
+ const uint tag_items_data_item_obj_type_id = 0x10 u;
38
+
39
+ const uint tag_index = 0x11 u;
40
+ const uint tag_index_buckets = 0x12 u;
41
+ const uint tag_index_buckets_bucket = 0x13 u;
42
+ const uint tag_index_buckets_bucket_elt = 0x14 u;
43
+ const uint tag_index_table = 0x15 u;
43
44
44
45
// Type encoding
45
46
@@ -164,7 +165,7 @@ fn C_postr(str s) -> ValueRef {
164
165
// Path table encoding
165
166
166
167
fn encode_name ( & ebml. writer ebml_w , str name ) {
167
- ebml. start_tag ( ebml_w, tag_paths_name ) ;
168
+ ebml. start_tag ( ebml_w, tag_paths_data_name ) ;
168
169
ebml_w. writer . write ( _str. bytes ( name) ) ;
169
170
ebml. end_tag ( ebml_w) ;
170
171
}
@@ -177,25 +178,37 @@ fn encode_def_id(&ebml.writer ebml_w, &ast.def_id id) {
177
178
178
179
fn encode_tag_variant_paths ( & ebml. writer ebml_w , vec[ ast. variant] variants ) {
179
180
for ( ast. variant variant in variants) {
180
- ebml. start_tag ( ebml_w, tag_paths_item ) ;
181
+ ebml. start_tag ( ebml_w, tag_paths_data_item ) ;
181
182
encode_name ( ebml_w, variant. node . name ) ;
182
183
encode_def_id ( ebml_w, variant. node . id ) ;
183
184
ebml. end_tag ( ebml_w) ;
184
185
}
185
186
}
186
187
188
+ fn add_to_index ( & ebml. writer ebml_w ,
189
+ vec[ str] path ,
190
+ & mutable vec[ tup( str, uint) ] index ,
191
+ str name ) {
192
+ auto full_path = path + vec ( name) ;
193
+ index += vec ( tup ( _str. connect ( full_path, "." ) , ebml_w. writer . tell ( ) ) ) ;
194
+ }
195
+
187
196
fn encode_native_module_item_paths ( & ebml. writer ebml_w ,
188
- & ast. native_mod nmod ) {
197
+ & ast. native_mod nmod ,
198
+ vec[ str] path ,
199
+ & mutable vec[ tup( str, uint) ] index ) {
189
200
for ( @ast. native_item nitem in nmod. items) {
190
201
alt ( nitem. node ) {
191
202
case ( ast. native_item_ty ( ?id, ?did) ) {
192
- ebml. start_tag ( ebml_w, tag_paths_item) ;
203
+ add_to_index ( ebml_w, path, index, id) ;
204
+ ebml. start_tag ( ebml_w, tag_paths_data_item) ;
193
205
encode_name ( ebml_w, id) ;
194
206
encode_def_id ( ebml_w, did) ;
195
207
ebml. end_tag ( ebml_w) ;
196
208
}
197
209
case ( ast. native_item_fn ( ?id, _, _, _, ?did, _) ) {
198
- ebml. start_tag ( ebml_w, tag_paths_item) ;
210
+ add_to_index ( ebml_w, path, index, id) ;
211
+ ebml. start_tag ( ebml_w, tag_paths_data_item) ;
199
212
encode_name ( ebml_w, id) ;
200
213
encode_def_id ( ebml_w, did) ;
201
214
ebml. end_tag ( ebml_w) ;
@@ -204,51 +217,62 @@ fn encode_native_module_item_paths(&ebml.writer ebml_w,
204
217
}
205
218
}
206
219
207
- fn encode_module_item_paths ( & ebml. writer ebml_w , & ast. _mod module ) {
220
+ fn encode_module_item_paths ( & ebml. writer ebml_w ,
221
+ & ast. _mod module ,
222
+ vec[ str] path ,
223
+ & mutable vec[ tup( str, uint) ] index ) {
208
224
// TODO: only encode exported items
209
225
for ( @ast. item it in module. items ) {
210
226
alt ( it. node ) {
211
227
case ( ast. item_const ( ?id, _, ?tps, ?did, ?ann) ) {
212
- ebml. start_tag ( ebml_w, tag_paths_item) ;
228
+ add_to_index ( ebml_w, path, index, id) ;
229
+ ebml. start_tag ( ebml_w, tag_paths_data_item) ;
213
230
encode_name ( ebml_w, id) ;
214
231
encode_def_id ( ebml_w, did) ;
215
232
ebml. end_tag ( ebml_w) ;
216
233
}
217
234
case ( ast. item_fn ( ?id, _, ?tps, ?did, ?ann) ) {
218
- ebml. start_tag ( ebml_w, tag_paths_item) ;
235
+ add_to_index ( ebml_w, path, index, id) ;
236
+ ebml. start_tag ( ebml_w, tag_paths_data_item) ;
219
237
encode_name ( ebml_w, id) ;
220
238
encode_def_id ( ebml_w, did) ;
221
239
ebml. end_tag ( ebml_w) ;
222
240
}
223
241
case ( ast. item_mod ( ?id, ?_mod, ?did) ) {
224
- ebml. start_tag ( ebml_w, tag_paths_mod) ;
242
+ add_to_index ( ebml_w, path, index, id) ;
243
+ ebml. start_tag ( ebml_w, tag_paths_data_mod) ;
225
244
encode_name ( ebml_w, id) ;
226
245
encode_def_id ( ebml_w, did) ;
227
- encode_module_item_paths ( ebml_w, _mod) ;
246
+ encode_module_item_paths ( ebml_w, _mod, path + vec ( id ) , index ) ;
228
247
ebml. end_tag ( ebml_w) ;
229
248
}
230
249
case ( ast. item_native_mod ( ?id, ?nmod, ?did) ) {
231
- ebml. start_tag ( ebml_w, tag_paths_mod) ;
250
+ add_to_index ( ebml_w, path, index, id) ;
251
+ ebml. start_tag ( ebml_w, tag_paths_data_mod) ;
232
252
encode_name ( ebml_w, id) ;
233
253
encode_def_id ( ebml_w, did) ;
234
- encode_native_module_item_paths ( ebml_w, nmod) ;
254
+ encode_native_module_item_paths ( ebml_w, nmod, path + vec ( id) ,
255
+ index) ;
235
256
ebml. end_tag ( ebml_w) ;
236
257
}
237
258
case ( ast. item_ty ( ?id, _, ?tps, ?did, ?ann) ) {
238
- ebml. start_tag ( ebml_w, tag_paths_item) ;
259
+ add_to_index ( ebml_w, path, index, id) ;
260
+ ebml. start_tag ( ebml_w, tag_paths_data_item) ;
239
261
encode_name ( ebml_w, id) ;
240
262
encode_def_id ( ebml_w, did) ;
241
263
ebml. end_tag ( ebml_w) ;
242
264
}
243
265
case ( ast. item_tag ( ?id, ?variants, ?tps, ?did) ) {
244
- ebml. start_tag ( ebml_w, tag_paths_item) ;
266
+ add_to_index ( ebml_w, path, index, id) ;
267
+ ebml. start_tag ( ebml_w, tag_paths_data_item) ;
245
268
encode_name ( ebml_w, id) ;
246
269
encode_tag_variant_paths ( ebml_w, variants) ;
247
270
encode_def_id ( ebml_w, did) ;
248
271
ebml. end_tag ( ebml_w) ;
249
272
}
250
273
case ( ast. item_obj ( ?id, _, ?tps, ?odid, ?ann) ) {
251
- ebml. start_tag ( ebml_w, tag_paths_item) ;
274
+ add_to_index ( ebml_w, path, index, id) ;
275
+ ebml. start_tag ( ebml_w, tag_paths_data_item) ;
252
276
encode_name ( ebml_w, id) ;
253
277
encode_def_id ( ebml_w, odid. ctor ) ;
254
278
encode_obj_type_id ( ebml_w, odid. ty ) ;
@@ -258,10 +282,14 @@ fn encode_module_item_paths(&ebml.writer ebml_w, &ast._mod module) {
258
282
}
259
283
}
260
284
261
- fn encode_item_paths ( & ebml. writer ebml_w , @ast. crate crate) {
285
+ fn encode_item_paths ( & ebml. writer ebml_w , @ast. crate crate)
286
+ -> vec[ tup ( str , uint ) ] {
287
+ let vec[ tup( str, uint) ] index = vec ( ) ;
288
+ let vec[ str] path = vec ( ) ;
262
289
ebml. start_tag ( ebml_w, tag_paths) ;
263
- encode_module_item_paths ( ebml_w, crate . node. module ) ;
290
+ encode_module_item_paths ( ebml_w, crate . node. module , path , index ) ;
264
291
ebml. end_tag ( ebml_w) ;
292
+ ret index;
265
293
}
266
294
267
295
@@ -442,51 +470,61 @@ fn encode_info_for_items(@trans.crate_ctxt cx, &ebml.writer ebml_w)
442
470
}
443
471
444
472
445
- // Definition ID indexing
473
+ // Path and definition ID indexing
474
+
475
+ // djb's cdb hashes.
446
476
447
- fn hash_def_num ( int def_num ) -> uint {
477
+ fn hash_def_num ( & int def_num ) -> uint {
448
478
ret 177573 u ^ ( def_num as uint ) ;
449
479
}
450
480
451
- fn create_index ( vec[ tup( int, uint) ] index ) -> vec [ vec[ tup ( int, uint) ] ] {
452
- let vec[ vec[ tup ( int, uint) ] ] buckets = vec ( ) ;
481
+ fn hash_path ( & str s) -> uint {
482
+ auto h = 5381 u;
483
+ for ( u8 ch in _str. bytes( s) ) {
484
+ h = ( ( h << 5 u) + h) ^ ( ch as uint ) ;
485
+ }
486
+ ret h;
487
+ }
488
+
489
+ fn create_index[ T ] ( vec[ tup ( T , uint) ] index, fn ( & T ) -> uint hash_fn)
490
+ -> vec[ vec[ tup ( T , uint) ] ] {
491
+ let vec[ vec[ tup ( T , uint) ] ] buckets = vec ( ) ;
453
492
for each ( uint i in _uint. range( 0 u, 256 u) ) {
454
- let vec[ tup( int , uint) ] bucket = vec ( ) ;
493
+ let vec[ tup( T , uint) ] bucket = vec ( ) ;
455
494
buckets += vec ( bucket) ;
456
495
}
457
496
458
- for ( tup( int , uint) elt in index) {
459
- auto h = hash_def_num ( elt. _0) ;
497
+ for ( tup( T , uint) elt in index) {
498
+ auto h = hash_fn ( elt. _0) ;
460
499
buckets. ( h % 256 u) += vec( elt) ;
461
500
}
462
501
463
502
ret buckets;
464
503
}
465
504
466
- impure fn encode_index( & ebml. writer ebml_w, vec[ tup( int, uint) ] index) {
505
+ impure fn encode_index[ T ] ( & ebml. writer ebml_w, vec[ vec[ tup( T , uint) ] ] buckets,
506
+ impure fn( io. writer, & T ) write_fn) {
467
507
auto writer = io. new_writer_( ebml_w. writer) ;
468
508
469
- auto buckets = create_index( index) ;
470
-
471
- ebml. start_tag( ebml_w, tag_items_index) ;
509
+ ebml. start_tag( ebml_w, tag_index) ;
472
510
473
511
let vec[ uint] bucket_locs = vec( ) ;
474
- ebml. start_tag( ebml_w, tag_items_index_buckets ) ;
475
- for ( vec[ tup( int , uint) ] bucket in buckets) {
512
+ ebml. start_tag( ebml_w, tag_index_buckets ) ;
513
+ for ( vec[ tup( T , uint) ] bucket in buckets) {
476
514
bucket_locs += vec( ebml_w. writer. tell( ) ) ;
477
515
478
- ebml. start_tag( ebml_w, tag_items_index_buckets_bucket ) ;
479
- for ( tup( int , uint) elt in bucket) {
480
- ebml. start_tag( ebml_w, tag_items_index_buckets_bucket_elt ) ;
516
+ ebml. start_tag( ebml_w, tag_index_buckets_bucket ) ;
517
+ for ( tup( T , uint) elt in bucket) {
518
+ ebml. start_tag( ebml_w, tag_index_buckets_bucket_elt ) ;
481
519
writer. write_be_uint( elt. _1, 4 u) ;
482
- writer . write_be_uint ( elt. _0 as uint , 4 u ) ;
520
+ write_fn ( writer , elt. _0) ;
483
521
ebml. end_tag( ebml_w) ;
484
522
}
485
523
ebml. end_tag( ebml_w) ;
486
524
}
487
525
ebml. end_tag( ebml_w) ;
488
526
489
- ebml. start_tag( ebml_w, tag_items_index_table ) ;
527
+ ebml. start_tag( ebml_w, tag_index_table ) ;
490
528
for ( uint pos in bucket_locs) {
491
529
writer. write_be_uint( pos, 4 u) ;
492
530
}
@@ -496,17 +534,37 @@ impure fn encode_index(&ebml.writer ebml_w, vec[tup(int, uint)] index) {
496
534
}
497
535
498
536
537
+ impure fn write_str( io. writer writer, & str s) {
538
+ writer. write_str( s) ;
539
+ }
540
+
541
+ impure fn write_int( io. writer writer, & int n) {
542
+ writer. write_be_uint( n as uint, 4 u) ;
543
+ }
544
+
545
+
499
546
impure fn encode_metadata( @trans. crate_ctxt cx, @ast. crate crate)
500
547
-> ValueRef {
501
548
auto string_w = io. string_writer( ) ;
502
549
auto buf_w = string_w. get_writer( ) . get_buf_writer( ) ;
503
550
auto ebml_w = ebml. create_writer( buf_w) ;
504
551
505
- encode_item_paths( ebml_w, crate ) ;
552
+ // Encode and index the paths.
553
+ ebml. start_tag( ebml_w, tag_paths) ;
554
+ auto paths_index = encode_item_paths( ebml_w, crate ) ;
555
+ auto str_writer = write_str;
556
+ auto path_hasher = hash_path;
557
+ auto paths_buckets = create_index[ str ] ( paths_index, path_hasher) ;
558
+ encode_index[ str ] ( ebml_w, paths_buckets, str_writer) ;
559
+ ebml. end_tag( ebml_w) ;
506
560
561
+ // Encode and index the items.
507
562
ebml. start_tag( ebml_w, tag_items) ;
508
- auto index = encode_info_for_items( cx, ebml_w) ;
509
- encode_index( ebml_w, index) ;
563
+ auto items_index = encode_info_for_items( cx, ebml_w) ;
564
+ auto int_writer = write_int;
565
+ auto item_hasher = hash_def_num;
566
+ auto items_buckets = create_index[ int] ( items_index, item_hasher) ;
567
+ encode_index[ int] ( ebml_w, items_buckets, int_writer) ;
510
568
ebml. end_tag( ebml_w) ;
511
569
512
570
ret C_postr ( string_w. get_str( ) ) ;
0 commit comments