@@ -353,22 +353,23 @@ impl<T> Bucket<T> {
353
353
}
354
354
}
355
355
356
+ /// A raw hash table with an unsafe API.
356
357
pub struct RawTable < T > {
357
358
header : NonNull < Header < T > > ,
358
359
marker : PhantomData < T > ,
359
360
}
360
361
361
- /// A raw hash table with an unsafe API.
362
+ /// The header of a RawTable's allocation (or the EMPTY_SINGLETON)
362
363
pub struct Header < T > {
363
364
// Mask to get an index from a hash value. The value is one less than the
364
365
// number of buckets in the table.
365
366
bucket_mask : usize ,
366
367
367
368
// Pointer to the array of control bytes
368
- ctrl : * mut u8 ,
369
+ ctrl : * const u8 ,
369
370
370
371
// Pointer to the array of buckets
371
- data : * mut T ,
372
+ data : * const T ,
372
373
373
374
// Number of elements that can be inserted before we need to grow the table
374
375
growth_left : usize ,
@@ -377,14 +378,27 @@ pub struct Header<T> {
377
378
items : usize ,
378
379
}
379
380
380
- static EMPTY_SINGLETON : Header < ( ) > = Header {
381
- data : 0xA000_0000 as * mut ( ) ,
382
- ctrl : std:: ptr:: null_mut ( ) ,
383
- bucket_mask : 0 ,
384
- items : 0 ,
385
- growth_left : 0 ,
381
+ static EMPTY_SINGLETON : Header < ( ) > = {
382
+ union AlignedBytes {
383
+ _align : Group ,
384
+ bytes : [ u8 ; Group :: WIDTH ] ,
385
+ } ;
386
+ static ALIGNED_BYTES : AlignedBytes = AlignedBytes {
387
+ bytes : [ EMPTY ; Group :: WIDTH ] ,
388
+ } ;
389
+ let ctrl = unsafe { & ALIGNED_BYTES . bytes as * const u8 } ;
390
+
391
+ Header {
392
+ data : core:: ptr:: null ( ) ,
393
+ ctrl,
394
+ bucket_mask : 0 ,
395
+ items : 0 ,
396
+ growth_left : 0 ,
397
+ }
386
398
} ;
387
399
400
+ unsafe impl < T : Sync > Sync for Header < T > { }
401
+
388
402
impl < T > RawTable < T > {
389
403
/// Creates a new empty hash table without allocating any memory.
390
404
///
@@ -411,8 +425,8 @@ impl<T> RawTable<T> {
411
425
calculate_layout :: < T > ( buckets) . ok_or_else ( || fallability. capacity_overflow ( ) ) ?;
412
426
413
427
let header = NonNull :: new ( alloc ( layout) ) . ok_or_else ( || fallability. alloc_err ( layout) ) ?;
414
- let ctrl = NonNull :: new_unchecked ( header. as_ptr ( ) . add ( ctrl_offset) as * mut u8 ) ;
415
- let data = NonNull :: new_unchecked ( header. as_ptr ( ) . add ( data_offset) as * mut T ) ;
428
+ let ctrl = header. as_ptr ( ) . add ( ctrl_offset) as * mut u8 ;
429
+ let data = header. as_ptr ( ) . add ( data_offset) as * mut T ;
416
430
417
431
let header = header. cast ( ) ;
418
432
* header. as_ptr ( ) = Header {
@@ -476,24 +490,26 @@ impl<T> RawTable<T> {
476
490
477
491
#[ inline]
478
492
fn header ( & self ) -> & Header < T > {
479
- & * self . header . as_ptr ( )
493
+ unsafe {
494
+ & * self . header . as_ptr ( )
495
+ }
480
496
}
481
497
482
498
#[ inline]
483
- unsafe fn header_mut ( & self ) -> & mut Header < T > {
499
+ unsafe fn header_mut ( & mut self ) -> & mut Header < T > {
484
500
& mut * self . header . as_ptr ( )
485
501
}
486
502
487
503
/// Returns a pointer to the data array
488
504
#[ inline]
489
505
fn data_ptr ( & self ) -> * mut T {
490
- self . header ( ) . data . as_ptr ( )
506
+ self . header ( ) . data as * mut T
491
507
}
492
508
493
509
/// Returns a pointer to the ctrl array
494
510
#[ inline]
495
511
fn ctrl_ptr ( & self ) -> * mut u8 {
496
- self . header ( ) . ctrl . as_ptr ( )
512
+ self . header ( ) . ctrl as * mut u8
497
513
}
498
514
499
515
#[ inline]
0 commit comments