11use std:: { error:: Error , fmt} ;
22
3+ // fast constant division
34#[ rustfmt:: skip]
4- const MAGIC : [ ( i32 , i32 , i32 ) ; 64 ] = [
5- // divide_mul, divide_add, divide_shift
6- ( - 1 , - 1 , 0 ) ,
7- ( - 0b10000000000000000000000000000000 , 0 , 0 ) ,
8- ( 0b1010101010101010101010101010101 , 0b1010101010101010101010101010101 , 0 ) ,
9- ( - 0b10000000000000000000000000000000 , 0 , 1 ) ,
10- ( 0b110011001100110011001100110011 , 0b110011001100110011001100110011 , 0 ) ,
11- ( 0b101010101010101010101010101010 , 0b101010101010101010101010101010 , 0 ) ,
12- ( 0b100100100100100100100100100100 , 0b100100100100100100100100100100 , 0 ) ,
13- ( - 0b10000000000000000000000000000000 , 0 , 2 ) ,
14- ( 0b11100011100011100011100011100 , 0b11100011100011100011100011100 , 0 ) ,
15- ( 0b11001100110011001100110011001 , 0b11001100110011001100110011001 , 0 ) ,
16- ( 0b10111010001011101000101110100 , 0b10111010001011101000101110100 , 0 ) ,
17- ( 0b10101010101010101010101010101 , 0b10101010101010101010101010101 , 0 ) ,
18- ( 0b10011101100010011101100010011 , 0b10011101100010011101100010011 , 0 ) ,
19- ( 0b10010010010010010010010010010 , 0b10010010010010010010010010010 , 0 ) ,
20- ( 0b10001000100010001000100010001 , 0b10001000100010001000100010001 , 0 ) ,
21- ( - 0b10000000000000000000000000000000 , 0 , 3 ) ,
22- ( 0b1111000011110000111100001111 , 0b1111000011110000111100001111 , 0 ) ,
23- ( 0b1110001110001110001110001110 , 0b1110001110001110001110001110 , 0 ) ,
24- ( 0b1101011110010100001101011110 , 0b1101011110010100001101011110 , 0 ) ,
25- ( 0b1111111111111111111111111111000 , 0b1111111111111111111111111111000 , 0 ) ,
26- ( 0b1100001100001100001100001100 , 0b1100001100001100001100001100 , 0 ) ,
27- ( 0b1011101000101110100010111010 , 0b1011101000101110100010111010 , 0 ) ,
28- ( 0b1011001000010110010000101100 , 0b1011001000010110010000101100 , 0 ) ,
29- ( 0b1010101010101010101010101010 , 0b1010101010101010101010101010 , 0 ) ,
30- ( 0b1010001111010111000010100011 , 0b1010001111010111000010100011 , 0 ) ,
31- ( 0b1001110110001001110110001001 , 0b1001110110001001110110001001 , 0 ) ,
32- ( 0b1001011110110100001001011110 , 0b1001011110110100001001011110 , 0 ) ,
33- ( 0b1001001001001001001001001001 , 0b1001001001001001001001001001 , 0 ) ,
34- ( 0b1000110100111101110010110000 , 0b1000110100111101110010110000 , 0 ) ,
35- ( 0b1000100010001000100010001000 , 0b1000100010001000100010001000 , 0 ) ,
36- ( 0b1000010000100001000010000100 , 0b1000010000100001000010000100 , 0 ) ,
37- ( - 0b10000000000000000000000000000000 , 0 , 4 ) ,
38- ( 0b111110000011111000001111100 , 0b111110000011111000001111100 , 0 ) ,
39- ( 0b111100001111000011110000111 , 0b111100001111000011110000111 , 0 ) ,
40- ( 0b111010100000111010100000111 , 0b111010100000111010100000111 , 0 ) ,
41- ( 0b111000111000111000111000111 , 0b111000111000111000111000111 , 0 ) ,
42- ( 0b110111010110011111001000101 , 0b110111010110011111001000101 , 0 ) ,
43- ( 0b110101111001010000110101111 , 0b110101111001010000110101111 , 0 ) ,
44- ( 0b110100100000110100100000110 , 0b110100100000110100100000110 , 0 ) ,
45- ( 0b110011001100110011001100110 , 0b110011001100110011001100110 , 0 ) ,
46- ( 0b110001111100111000001100011 , 0b110001111100111000001100011 , 0 ) ,
47- ( 0b110000110000110000110000110 , 0b110000110000110000110000110 , 0 ) ,
48- ( 0b101111101000001011111010000 , 0b101111101000001011111010000 , 0 ) ,
49- ( 0b101110100010111010001011101 , 0b101110100010111010001011101 , 0 ) ,
50- ( 0b101101100000101101100000101 , 0b101101100000101101100000101 , 0 ) ,
51- ( 0b101100100001011001000010110 , 0b101100100001011001000010110 , 0 ) ,
52- ( 0b101011100100110001000001010 , 0b101011100100110001000001010 , 0 ) ,
53- ( 0b101010101010101010101010101 , 0b101010101010101010101010101 , 0 ) ,
54- ( 0b101001110010111100000101001 , 0b101001110010111100000101001 , 0 ) ,
55- ( 0b101000111101011100001010001 , 0b101000111101011100001010001 , 0 ) ,
56- ( 0b101000001010000010100000101 , 0b101000001010000010100000101 , 0 ) ,
57- ( 0b100111011000100111011000100 , 0b100111011000100111011000100 , 0 ) ,
58- ( 0b100110101001000011100111110 , 0b100110101001000011100111110 , 0 ) ,
59- ( 0b100101111011010000100101111 , 0b100101111011010000100101111 , 0 ) ,
60- ( 0b100101001111001000001001010 , 0b100101001111001000001001010 , 0 ) ,
61- ( 0b100100100100100100100100100 , 0b100100100100100100100100100 , 0 ) ,
62- ( 0b100011111011100000100011111 , 0b100011111011100000100011111 , 0 ) ,
63- ( 0b100011010011110111001011000 , 0b100011010011110111001011000 , 0 ) ,
64- ( 0b100010101101100011110010111 , 0b100010101101100011110010111 , 0 ) ,
65- ( 0b100010001000100010001000100 , 0b100010001000100010001000100 , 0 ) ,
66- ( 0b100001100100101110001010011 , 0b100001100100101110001010011 , 0 ) ,
67- ( 0b100001000010000100001000010 , 0b100001000010000100001000010 , 0 ) ,
68- ( 0b100000100000100000100000100 , 0b100000100000100000100000100 , 0 ) ,
69- ( - 0b10000000000000000000000000000000 , 0 , 5 ) ,
5+ const MAGIC : [ ( i32 , i32 , u32 ) ; 64 ] = [
6+ // mul, add, shift
7+ ( 1 , 0 , 0 ) , // divide by 1
8+ ( 1 , 0 , 1 ) , // divide by 2, etc
9+ ( 0x55555555 , 0x55555555 , 32 ) ,
10+ ( 1 , 0 , 2 ) ,
11+ ( 0x33333333 , 0x33333333 , 32 ) ,
12+ ( 0x2AAAAAAA , 0x2AAAAAAA , 32 ) ,
13+ ( 0x24924924 , 0x24924924 , 32 ) ,
14+ ( 1 , 0 , 3 ) ,
15+ ( 0x1C71C71C , 0x1C71C71C , 32 ) ,
16+ ( 0x19999999 , 0x19999999 , 32 ) ,
17+ ( 0x1745D174 , 0x1745D174 , 32 ) ,
18+ ( 0x15555555 , 0x15555555 , 32 ) ,
19+ ( 0x13B13B13 , 0x13B13B13 , 32 ) ,
20+ ( 0x12492492 , 0x12492492 , 32 ) ,
21+ ( 0x11111111 , 0x11111111 , 32 ) ,
22+ ( 1 , 0 , 4 ) ,
23+ ( 0xF0F0F0F , 0xF0F0F0F , 32 ) ,
24+ ( 0xE38E38E , 0xE38E38E , 32 ) ,
25+ ( 0xD79435E , 0xD79435E , 32 ) ,
26+ ( 0x7FFFFFF8 , 0x7FFFFFF8 , 32 ) ,
27+ ( 0xC30C30C , 0xC30C30C , 32 ) ,
28+ ( 0xBA2E8BA , 0xBA2E8BA , 32 ) ,
29+ ( 0xB21642C , 0xB21642C , 32 ) ,
30+ ( 0xAAAAAAA , 0xAAAAAAA , 32 ) ,
31+ ( 0xA3D70A3 , 0xA3D70A3 , 32 ) ,
32+ ( 0x9D89D89 , 0x9D89D89 , 32 ) ,
33+ ( 0x97B425E , 0x97B425E , 32 ) ,
34+ ( 0x9249249 , 0x9249249 , 32 ) ,
35+ ( 0x8D3DCB0 , 0x8D3DCB0 , 32 ) ,
36+ ( 0x8888888 , 0x8888888 , 32 ) ,
37+ ( 0x8421084 , 0x8421084 , 32 ) ,
38+ ( 1 , 0 , 5 ) ,
39+ ( 0x7C1F07C , 0x7C1F07C , 32 ) ,
40+ ( 0x7878787 , 0x7878787 , 32 ) ,
41+ ( 0x7507507 , 0x7507507 , 32 ) ,
42+ ( 0x71C71C7 , 0x71C71C7 , 32 ) ,
43+ ( 0x6EB3E45 , 0x6EB3E45 , 32 ) ,
44+ ( 0x6BCA1AF , 0x6BCA1AF , 32 ) ,
45+ ( 0x6906906 , 0x6906906 , 32 ) ,
46+ ( 0x6666666 , 0x6666666 , 32 ) ,
47+ ( 0x63E7063 , 0x63E7063 , 32 ) ,
48+ ( 0x6186186 , 0x6186186 , 32 ) ,
49+ ( 0x5F417D0 , 0x5F417D0 , 32 ) ,
50+ ( 0x5D1745D , 0x5D1745D , 32 ) ,
51+ ( 0x5B05B05 , 0x5B05B05 , 32 ) ,
52+ ( 0x590B216 , 0x590B216 , 32 ) ,
53+ ( 0x572620A , 0x572620A , 32 ) ,
54+ ( 0x5555555 , 0x5555555 , 32 ) ,
55+ ( 0x5397829 , 0x5397829 , 32 ) ,
56+ ( 0x51EB851 , 0x51EB851 , 32 ) ,
57+ ( 0x5050505 , 0x5050505 , 32 ) ,
58+ ( 0x4EC4EC4 , 0x4EC4EC4 , 32 ) ,
59+ ( 0x4D4873E , 0x4D4873E , 32 ) ,
60+ ( 0x4BDA12F , 0x4BDA12F , 32 ) ,
61+ ( 0x4A7904A , 0x4A7904A , 32 ) ,
62+ ( 0x4924924 , 0x4924924 , 32 ) ,
63+ ( 0x47DC11F , 0x47DC11F , 32 ) ,
64+ ( 0x469EE58 , 0x469EE58 , 32 ) ,
65+ ( 0x456C797 , 0x456C797 , 32 ) ,
66+ ( 0x4444444 , 0x4444444 , 32 ) ,
67+ ( 0x4325C53 , 0x4325C53 , 32 ) ,
68+ ( 0x4210842 , 0x4210842 , 32 ) ,
69+ ( 0x4104104 , 0x4104104 , 32 ) ,
70+ ( 1 , 0 , 6 ) ,
7071] ;
7172
7273/// A compact list of integers with the given number of bits per entry.
@@ -77,9 +78,9 @@ pub struct BitStorage {
7778 mask : u64 ,
7879 size : usize ,
7980 values_per_long : usize ,
80- divide_mul : u64 ,
81- divide_add : u64 ,
82- divide_shift : i32 ,
81+ divide_mul : i32 ,
82+ divide_add : i32 ,
83+ divide_shift : u32 ,
8384}
8485
8586#[ derive( Debug ) ]
@@ -99,8 +100,8 @@ impl fmt::Display for BitStorageError {
99100impl Error for BitStorageError { }
100101
101102impl BitStorage {
102- /// Create a new BitStorage with the given number of bits per entry.
103- /// `size` is the number of entries in the BitStorage.
103+ /// Create a new BitStorage with the given number of bits per entry. `size`
104+ /// is the number of entries in the BitStorage.
104105 pub fn new (
105106 bits : usize ,
106107 size : usize ,
@@ -145,18 +146,19 @@ impl BitStorage {
145146 mask,
146147 size,
147148 values_per_long,
148- divide_mul : divide_mul as u32 as u64 ,
149- divide_add : divide_add as u32 as u64 ,
149+ divide_mul,
150+ divide_add,
150151 divide_shift,
151152 } )
152153 }
153154
154- pub fn cell_index ( & self , index : u64 ) -> usize {
155- // as unsigned wrap
156- let first = self . divide_mul ;
157- let second = self . divide_add ;
155+ #[ inline]
156+ fn cell_index ( & self , index : u64 ) -> usize {
157+ let mul = self . divide_mul as u32 as u64 ;
158+ let add = self . divide_add as u32 as u64 ;
159+ let shift = self . divide_shift ;
158160
159- ( ( ( index * first ) + second ) >> 32 >> self . divide_shift ) as usize
161+ ( ( ( index * mul ) + add ) >> shift ) as usize
160162 }
161163
162164 /// Get the data at the given index.
@@ -254,7 +256,9 @@ mod tests {
254256 use super :: * ;
255257
256258 #[ test]
257- fn test_wikivg_example ( ) {
259+ fn test_protocol_wiki_example ( ) {
260+ // https://minecraft.wiki/w/Java_Edition_protocol/Chunk_format#Visual_example
261+
258262 let data = [
259263 1 , 2 , 2 , 3 , 4 , 4 , 5 , 6 , 6 , 4 , 8 , 0 , 7 , 4 , 3 , 13 , 15 , 16 , 9 , 14 , 10 , 12 , 0 , 2 ,
260264 ] ;
0 commit comments