11use super :: bitmask:: BitMask ;
2- use super :: EMPTY ;
2+ use super :: Tag ;
33use core:: { mem, ptr} ;
44
55// Use the native word size as the group size. Using a 64-bit group size on
@@ -24,18 +24,18 @@ cfg_if! {
2424pub ( crate ) type BitMaskWord = GroupWord ;
2525pub ( crate ) type NonZeroBitMaskWord = NonZeroGroupWord ;
2626pub ( crate ) const BITMASK_STRIDE : usize = 8 ;
27- // We only care about the highest bit of each byte for the mask.
27+ // We only care about the highest bit of each tag for the mask.
2828#[ allow( clippy:: cast_possible_truncation, clippy:: unnecessary_cast) ]
29- pub ( crate ) const BITMASK_MASK : BitMaskWord = 0x8080_8080_8080_8080_u64 as GroupWord ;
29+ pub ( crate ) const BITMASK_MASK : BitMaskWord = u64 :: from_ne_bytes ( [ Tag :: DELETED . 0 ; 8 ] ) as GroupWord ;
3030pub ( crate ) const BITMASK_ITER_MASK : BitMaskWord = !0 ;
3131
32- /// Helper function to replicate a byte across a `GroupWord`.
32+ /// Helper function to replicate a tag across a `GroupWord`.
3333#[ inline]
34- fn repeat ( byte : u8 ) -> GroupWord {
35- GroupWord :: from_ne_bytes ( [ byte ; Group :: WIDTH ] )
34+ fn repeat ( tag : Tag ) -> GroupWord {
35+ GroupWord :: from_ne_bytes ( [ tag . 0 ; Group :: WIDTH ] )
3636}
3737
38- /// Abstraction over a group of control bytes which can be scanned in
38+ /// Abstraction over a group of control tags which can be scanned in
3939/// parallel.
4040///
4141/// This implementation uses a word-sized integer.
@@ -51,94 +51,94 @@ impl Group {
5151 /// Number of bytes in the group.
5252 pub ( crate ) const WIDTH : usize = mem:: size_of :: < Self > ( ) ;
5353
54- /// Returns a full group of empty bytes , suitable for use as the initial
54+ /// Returns a full group of empty tags , suitable for use as the initial
5555 /// value for an empty hash table.
5656 ///
5757 /// This is guaranteed to be aligned to the group size.
5858 #[ inline]
59- pub ( crate ) const fn static_empty ( ) -> & ' static [ u8 ; Group :: WIDTH ] {
59+ pub ( crate ) const fn static_empty ( ) -> & ' static [ Tag ; Group :: WIDTH ] {
6060 #[ repr( C ) ]
61- struct AlignedBytes {
61+ struct AlignedTags {
6262 _align : [ Group ; 0 ] ,
63- bytes : [ u8 ; Group :: WIDTH ] ,
63+ tags : [ Tag ; Group :: WIDTH ] ,
6464 }
65- const ALIGNED_BYTES : AlignedBytes = AlignedBytes {
65+ const ALIGNED_TAGS : AlignedTags = AlignedTags {
6666 _align : [ ] ,
67- bytes : [ EMPTY ; Group :: WIDTH ] ,
67+ tags : [ Tag :: EMPTY ; Group :: WIDTH ] ,
6868 } ;
69- & ALIGNED_BYTES . bytes
69+ & ALIGNED_TAGS . tags
7070 }
7171
72- /// Loads a group of bytes starting at the given address.
72+ /// Loads a group of tags starting at the given address.
7373 #[ inline]
7474 #[ allow( clippy:: cast_ptr_alignment) ] // unaligned load
75- pub ( crate ) unsafe fn load ( ptr : * const u8 ) -> Self {
75+ pub ( crate ) unsafe fn load ( ptr : * const Tag ) -> Self {
7676 Group ( ptr:: read_unaligned ( ptr. cast ( ) ) )
7777 }
7878
79- /// Loads a group of bytes starting at the given address, which must be
79+ /// Loads a group of tags starting at the given address, which must be
8080 /// aligned to `mem::align_of::<Group>()`.
8181 #[ inline]
8282 #[ allow( clippy:: cast_ptr_alignment) ]
83- pub ( crate ) unsafe fn load_aligned ( ptr : * const u8 ) -> Self {
83+ pub ( crate ) unsafe fn load_aligned ( ptr : * const Tag ) -> Self {
8484 // FIXME: use align_offset once it stabilizes
8585 debug_assert_eq ! ( ptr as usize & ( mem:: align_of:: <Self >( ) - 1 ) , 0 ) ;
8686 Group ( ptr:: read ( ptr. cast ( ) ) )
8787 }
8888
89- /// Stores the group of bytes to the given address, which must be
89+ /// Stores the group of tags to the given address, which must be
9090 /// aligned to `mem::align_of::<Group>()`.
9191 #[ inline]
9292 #[ allow( clippy:: cast_ptr_alignment) ]
93- pub ( crate ) unsafe fn store_aligned ( self , ptr : * mut u8 ) {
93+ pub ( crate ) unsafe fn store_aligned ( self , ptr : * mut Tag ) {
9494 // FIXME: use align_offset once it stabilizes
9595 debug_assert_eq ! ( ptr as usize & ( mem:: align_of:: <Self >( ) - 1 ) , 0 ) ;
9696 ptr:: write ( ptr. cast ( ) , self . 0 ) ;
9797 }
9898
99- /// Returns a `BitMask` indicating all bytes in the group which *may*
99+ /// Returns a `BitMask` indicating all tags in the group which *may*
100100 /// have the given value.
101101 ///
102102 /// This function may return a false positive in certain cases where
103- /// the byte in the group differs from the searched value only in its
103+ /// the tag in the group differs from the searched value only in its
104104 /// lowest bit. This is fine because:
105105 /// - This never happens for `EMPTY` and `DELETED`, only full entries.
106106 /// - The check for key equality will catch these.
107107 /// - This only happens if there is at least 1 true match.
108108 /// - The chance of this happening is very low (< 1% chance per byte).
109109 #[ inline]
110- pub ( crate ) fn match_byte ( self , byte : u8 ) -> BitMask {
110+ pub ( crate ) fn match_tag ( self , tag : Tag ) -> BitMask {
111111 // This algorithm is derived from
112112 // https://graphics.stanford.edu/~seander/bithacks.html##ValueInWord
113- let cmp = self . 0 ^ repeat ( byte ) ;
114- BitMask ( ( cmp. wrapping_sub ( repeat ( 0x01 ) ) & !cmp & repeat ( 0x80 ) ) . to_le ( ) )
113+ let cmp = self . 0 ^ repeat ( tag ) ;
114+ BitMask ( ( cmp. wrapping_sub ( repeat ( Tag ( 0x01 ) ) ) & !cmp & repeat ( Tag :: DELETED ) ) . to_le ( ) )
115115 }
116116
117- /// Returns a `BitMask` indicating all bytes in the group which are
117+ /// Returns a `BitMask` indicating all tags in the group which are
118118 /// `EMPTY`.
119119 #[ inline]
120120 pub ( crate ) fn match_empty ( self ) -> BitMask {
121- // If the high bit is set, then the byte must be either:
121+ // If the high bit is set, then the tag must be either:
122122 // 1111_1111 (EMPTY) or 1000_0000 (DELETED).
123123 // So we can just check if the top two bits are 1 by ANDing them.
124- BitMask ( ( self . 0 & ( self . 0 << 1 ) & repeat ( 0x80 ) ) . to_le ( ) )
124+ BitMask ( ( self . 0 & ( self . 0 << 1 ) & repeat ( Tag :: DELETED ) ) . to_le ( ) )
125125 }
126126
127- /// Returns a `BitMask` indicating all bytes in the group which are
127+ /// Returns a `BitMask` indicating all tags in the group which are
128128 /// `EMPTY` or `DELETED`.
129129 #[ inline]
130130 pub ( crate ) fn match_empty_or_deleted ( self ) -> BitMask {
131- // A byte is EMPTY or DELETED iff the high bit is set
132- BitMask ( ( self . 0 & repeat ( 0x80 ) ) . to_le ( ) )
131+ // A tag is EMPTY or DELETED iff the high bit is set
132+ BitMask ( ( self . 0 & repeat ( Tag :: DELETED ) ) . to_le ( ) )
133133 }
134134
135- /// Returns a `BitMask` indicating all bytes in the group which are full.
135+ /// Returns a `BitMask` indicating all tags in the group which are full.
136136 #[ inline]
137137 pub ( crate ) fn match_full ( self ) -> BitMask {
138138 self . match_empty_or_deleted ( ) . invert ( )
139139 }
140140
141- /// Performs the following transformation on all bytes in the group:
141+ /// Performs the following transformation on all tags in the group:
142142 /// - `EMPTY => EMPTY`
143143 /// - `DELETED => EMPTY`
144144 /// - `FULL => DELETED`
@@ -151,7 +151,7 @@ impl Group {
151151 // let full = 1000_0000 (true) or 0000_0000 (false)
152152 // !1000_0000 + 1 = 0111_1111 + 1 = 1000_0000 (no carry)
153153 // !0000_0000 + 0 = 1111_1111 + 0 = 1111_1111 (no carry)
154- let full = !self . 0 & repeat ( 0x80 ) ;
154+ let full = !self . 0 & repeat ( Tag :: DELETED ) ;
155155 Group ( !full + ( full >> 7 ) )
156156 }
157157}
0 commit comments