Skip to main content

preflate_rs/
hash_algorithm.rs

1use bitcode::{Decode, Encode};
2
3#[derive(Encode, Decode, Debug, Copy, Clone, Eq, PartialEq, Default)]
4pub enum HashAlgorithm {
5    #[default]
6    None,
7    Zlib {
8        hash_mask: u16,
9        hash_shift: u32,
10    },
11    MiniZFast,
12
13    /// Libflate 4 byte hash only
14    Libdeflate4Fast,
15    /// Libflate 4 byte hash with 3 byte secondary hash
16    Libdeflate4,
17
18    ZlibNG,
19    RandomVector,
20    Crc32cHash,
21}
22
23const HASH_ALGORITHM_NONE: u16 = 0;
24const HASH_ALGORITHM_ZLIB: u16 = 1;
25const HASH_ALGORITHM_MINIZ_FAST: u16 = 2;
26const HASH_ALGORITHM_LIBDEFLATE4: u16 = 3;
27const HASH_ALGORITHM_LIBDEFLATE4_FAST: u16 = 4;
28const HASH_ALGORITHM_ZLIBNG: u16 = 5;
29const HASH_ALGORITHM_RANDOMVECTOR: u16 = 6;
30const HASH_ALGORITHM_CRC32C: u16 = 7;
31
32impl HashAlgorithm {
33    pub fn to_u16(self) -> u16 {
34        match self {
35            HashAlgorithm::None => HASH_ALGORITHM_NONE,
36            HashAlgorithm::Zlib {
37                hash_mask,
38                hash_shift,
39            } => {
40                HASH_ALGORITHM_ZLIB
41                    | ((hash_mask.trailing_ones() as u16) << 8)
42                    | ((hash_shift as u16) << 12)
43            }
44            HashAlgorithm::MiniZFast => HASH_ALGORITHM_MINIZ_FAST,
45            HashAlgorithm::Libdeflate4Fast => HASH_ALGORITHM_LIBDEFLATE4_FAST,
46            HashAlgorithm::Libdeflate4 => HASH_ALGORITHM_LIBDEFLATE4,
47            HashAlgorithm::ZlibNG => HASH_ALGORITHM_ZLIBNG,
48            HashAlgorithm::RandomVector => HASH_ALGORITHM_RANDOMVECTOR,
49            HashAlgorithm::Crc32cHash => HASH_ALGORITHM_CRC32C,
50        }
51    }
52
53    pub fn from_u16(v: u16) -> Option<Self> {
54        match v & 0xff {
55            HASH_ALGORITHM_NONE => Some(HashAlgorithm::None),
56            HASH_ALGORITHM_ZLIB => {
57                let hash_mask = (1 << ((v >> 8) & 0xf)) - 1;
58                let hash_shift = (v >> 12) & 0xf;
59                Some(HashAlgorithm::Zlib {
60                    hash_mask,
61                    hash_shift: hash_shift.into(),
62                })
63            }
64            HASH_ALGORITHM_MINIZ_FAST => Some(HashAlgorithm::MiniZFast),
65            HASH_ALGORITHM_LIBDEFLATE4_FAST => Some(HashAlgorithm::Libdeflate4Fast),
66            HASH_ALGORITHM_LIBDEFLATE4 => Some(HashAlgorithm::Libdeflate4),
67            HASH_ALGORITHM_ZLIBNG => Some(HashAlgorithm::ZlibNG),
68            HASH_ALGORITHM_RANDOMVECTOR => Some(HashAlgorithm::RandomVector),
69            HASH_ALGORITHM_CRC32C => Some(HashAlgorithm::Crc32cHash),
70            _ => None,
71        }
72    }
73}
74
75#[test]
76fn roundtrip_hash_algorithm_to_int() {
77    let test_hashes = [
78        HashAlgorithm::Zlib {
79            hash_mask: 0x7ff,
80            hash_shift: 3,
81        },
82        HashAlgorithm::MiniZFast,
83        HashAlgorithm::Libdeflate4Fast,
84        HashAlgorithm::Libdeflate4,
85        HashAlgorithm::ZlibNG,
86        HashAlgorithm::RandomVector,
87        HashAlgorithm::Crc32cHash,
88    ];
89
90    for &hash in test_hashes.iter() {
91        let hash_int = hash.to_u16();
92        let hash2 = HashAlgorithm::from_u16(hash_int).unwrap();
93        assert_eq!(hash, hash2);
94    }
95}
96
97pub trait HashImplementation: Default + Copy + Clone {
98    const NUM_HASH_BYTES: usize;
99
100    fn get_hash(&self, b: &[u8]) -> u16;
101    fn algorithm(&self) -> HashAlgorithm;
102}
103
104#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
105pub struct ZlibRotatingHashFixed<const HASH_SHIFT: u32, const HASH_MASK: u32> {}
106
107impl<const HASH_SHIFT: u32, const HASH_MASK: u32> HashImplementation
108    for ZlibRotatingHashFixed<HASH_SHIFT, HASH_MASK>
109{
110    const NUM_HASH_BYTES: usize = 3;
111
112    fn get_hash(&self, b: &[u8]) -> u16 {
113        assert!(b.len() >= 3);
114
115        let c = u32::from(b[0]);
116        let c = (c << HASH_SHIFT) ^ u32::from(b[1]);
117        let c = (c << HASH_SHIFT) ^ u32::from(b[2]);
118        (c & HASH_MASK) as u16
119    }
120
121    fn algorithm(&self) -> HashAlgorithm {
122        HashAlgorithm::Zlib {
123            hash_mask: HASH_MASK as u16,
124            hash_shift: HASH_SHIFT,
125        }
126    }
127}
128
129#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
130pub struct ZlibRotatingHash {
131    pub hash_mask: u16,
132    pub hash_shift: u32,
133}
134
135impl HashImplementation for ZlibRotatingHash {
136    const NUM_HASH_BYTES: usize = 3;
137
138    fn get_hash(&self, b: &[u8]) -> u16 {
139        assert!(b.len() >= 3);
140
141        let c = u16::from(b[0]);
142        let c = (c << self.hash_shift) ^ u16::from(b[1]);
143        let c = (c << self.hash_shift) ^ u16::from(b[2]);
144        c & self.hash_mask
145    }
146
147    fn algorithm(&self) -> HashAlgorithm {
148        HashAlgorithm::Zlib {
149            hash_mask: self.hash_mask,
150            hash_shift: self.hash_shift,
151        }
152    }
153}
154
155#[derive(Default, Copy, Clone)]
156pub struct MiniZHash {}
157
158/// Size of hash chain for fast compression mode.
159pub const MINIZ_LEVEL1_HASH_SIZE_MASK: u16 = 4095;
160
161impl HashImplementation for MiniZHash {
162    const NUM_HASH_BYTES: usize = 3;
163
164    fn get_hash(&self, b: &[u8]) -> u16 {
165        assert!(b.len() >= 3);
166
167        let hash = u32::from(b[0]) | (u32::from(b[1]) << 8) | (u32::from(b[2]) << 16);
168
169        ((hash ^ (hash >> 17)) & u32::from(MINIZ_LEVEL1_HASH_SIZE_MASK)) as u16
170    }
171
172    fn algorithm(&self) -> HashAlgorithm {
173        HashAlgorithm::MiniZFast
174    }
175}
176
177/// Fast version of Libflate hash that doesn't use a secondary 3
178/// byte hash. This is used by level 1 compression.
179#[derive(Default, Copy, Clone)]
180pub struct LibdeflateHash4Fast {}
181
182impl HashImplementation for LibdeflateHash4Fast {
183    const NUM_HASH_BYTES: usize = 4;
184
185    fn get_hash(&self, b: &[u8]) -> u16 {
186        let hash = u32::from_le_bytes(b[..4].try_into().unwrap());
187
188        (hash.wrapping_mul(0x1E35A7BD) >> 16) as u16
189    }
190
191    fn algorithm(&self) -> HashAlgorithm {
192        HashAlgorithm::Libdeflate4Fast
193    }
194}
195
196#[derive(Default, Copy, Clone)]
197pub struct LibdeflateHash4 {}
198
199impl HashImplementation for LibdeflateHash4 {
200    const NUM_HASH_BYTES: usize = 4;
201
202    fn get_hash(&self, b: &[u8]) -> u16 {
203        let hash = u32::from_le_bytes(b[..4].try_into().unwrap());
204
205        (hash.wrapping_mul(0x1E35A7BD) >> 16) as u16
206    }
207
208    fn algorithm(&self) -> HashAlgorithm {
209        HashAlgorithm::Libdeflate4
210    }
211}
212
213/// This is the 3 byte version of the libdeflate hash algorithm, which is used
214/// as a secondary hash value to find 3 byte matches within the first 4096K if
215/// we fail to find any four byte matches with the primary hash.
216#[derive(Default, Copy, Clone)]
217pub struct LibdeflateHash3Secondary {}
218
219impl HashImplementation for LibdeflateHash3Secondary {
220    const NUM_HASH_BYTES: usize = 3;
221
222    fn get_hash(&self, b: &[u8]) -> u16 {
223        assert!(b.len() >= 3);
224
225        let hash = u32::from(b[0]) | (u32::from(b[1]) << 8) | (u32::from(b[2]) << 16);
226
227        (hash.wrapping_mul(0x1E35A7BD) >> 17) as u16
228    }
229
230    fn algorithm(&self) -> HashAlgorithm {
231        unimplemented!("shoudln't get called on secondary hash");
232    }
233}
234
235#[derive(Default, Copy, Clone)]
236pub struct ZlibNGHash {}
237
238impl HashImplementation for ZlibNGHash {
239    const NUM_HASH_BYTES: usize = 4;
240
241    fn get_hash(&self, b: &[u8]) -> u16 {
242        let hash = u32::from_le_bytes(b[..4].try_into().unwrap());
243
244        (hash.wrapping_mul(2654435761) >> 16) as u16
245    }
246
247    fn algorithm(&self) -> HashAlgorithm {
248        HashAlgorithm::ZlibNG
249    }
250}
251
252#[derive(Default, Copy, Clone)]
253pub struct Crc32cHash {}
254
255impl HashImplementation for Crc32cHash {
256    const NUM_HASH_BYTES: usize = 4;
257
258    fn get_hash(&self, b: &[u8]) -> u16 {
259        assert!(b.len() >= 4);
260
261        let mut crc = CRC32C_TABLE[b[0] as usize];
262        crc = (crc >> 8) ^ CRC32C_TABLE[((crc ^ u32::from(b[1])) & 0xFF) as usize];
263        crc = (crc >> 8) ^ CRC32C_TABLE[((crc ^ u32::from(b[2])) & 0xFF) as usize];
264        crc = (crc >> 8) ^ CRC32C_TABLE[((crc ^ u32::from(b[3])) & 0xFF) as usize];
265
266        crc as u16
267    }
268
269    fn algorithm(&self) -> HashAlgorithm {
270        HashAlgorithm::Crc32cHash
271    }
272}
273
274static CRC32C_TABLE: [u32; 256] = [
275    0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4, 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
276    0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B, 0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
277    0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B, 0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
278    0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54, 0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
279    0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A, 0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
280    0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5, 0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
281    0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45, 0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
282    0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A, 0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
283    0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48, 0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
284    0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687, 0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
285    0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927, 0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
286    0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8, 0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
287    0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096, 0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
288    0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859, 0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
289    0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9, 0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
290    0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36, 0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
291    0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C, 0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
292    0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043, 0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
293    0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3, 0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
294    0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C, 0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
295    0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652, 0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
296    0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D, 0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
297    0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D, 0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
298    0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2, 0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
299    0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530, 0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
300    0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF, 0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
301    0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F, 0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
302    0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90, 0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
303    0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE, 0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
304    0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321, 0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
305    0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81, 0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
306    0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E, 0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351,
307];
308
309/// This vector uses a lookup into a table for random values
310#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
311pub struct RandomVectorHash {}
312
313static RANDOM_VECTOR: [u16; 768] = [
314    0x499d, 0x3dc2, 0x2d07, 0x705b, 0x7a76, 0x3469, 0x59db, 0x0c58, 0x2b72, 0x412d, 0x1246, 0x2095,
315    0x1c1c, 0x4726, 0x5f45, 0x2c4e, 0x7b1b, 0x1e70, 0x2743, 0x554f, 0x1334, 0x5328, 0x78c1, 0x41cc,
316    0x4b2c, 0x62a5, 0x1d93, 0x4aa4, 0x64c8, 0x65f0, 0x194d, 0x1ac0, 0x3f96, 0x41df, 0x4389, 0x065b,
317    0x4b74, 0x15e2, 0x0389, 0x0b7e, 0x5778, 0x5d95, 0x7ffc, 0x1e6f, 0x5465, 0x23d3, 0x01ab, 0x567e,
318    0x0b3b, 0x6c2f, 0x5e4d, 0x2641, 0x03a4, 0x1214, 0x4b01, 0x48f3, 0x7ba9, 0x7009, 0x1270, 0x0e67,
319    0x40e8, 0x710d, 0x6b7f, 0x1418, 0x45f6, 0x2785, 0x4725, 0x7904, 0x14a2, 0x71b8, 0x3189, 0x6ccc,
320    0x4d66, 0x701e, 0x4148, 0x6c05, 0x01a8, 0x5ff1, 0x4fbb, 0x0a2a, 0x541d, 0x4378, 0x3f15, 0x3677,
321    0x0d82, 0x578b, 0x345d, 0x6052, 0x0beb, 0x553d, 0x4d89, 0x1315, 0x311c, 0x3f33, 0x226d, 0x3223,
322    0x478b, 0x487b, 0x5326, 0x160e, 0x05b3, 0x486d, 0x0f2f, 0x1ecc, 0x04b7, 0x01a0, 0x6f70, 0x425c,
323    0x3d3f, 0x1610, 0x4211, 0x68d3, 0x3041, 0x7ddf, 0x5967, 0x36f3, 0x31a5, 0x2137, 0x4692, 0x56de,
324    0x53d8, 0x4466, 0x5720, 0x6d64, 0x3421, 0x6979, 0x3151, 0x5ee6, 0x0e2f, 0x35d8, 0x30ff, 0x3070,
325    0x19b1, 0x4651, 0x6b4f, 0x4cea, 0x7991, 0x4e0b, 0x2d3f, 0x3d1e, 0x09a0, 0x4bac, 0x0571, 0x079a,
326    0x4380, 0x411a, 0x4012, 0x57f5, 0x0f7a, 0x5ae9, 0x1b6d, 0x6f3c, 0x3b37, 0x0b66, 0x60af, 0x17b9,
327    0x77df, 0x286f, 0x14c9, 0x2274, 0x1d96, 0x67dc, 0x7801, 0x68d9, 0x0942, 0x1c06, 0x4922, 0x7a4b,
328    0x1732, 0x6c5d, 0x4928, 0x3c70, 0x64fa, 0x6ce8, 0x2979, 0x163b, 0x4379, 0x64ee, 0x37d3, 0x5bf2,
329    0x1725, 0x5749, 0x26aa, 0x13e7, 0x1e82, 0x2226, 0x723c, 0x4677, 0x4a6f, 0x0e39, 0x6431, 0x50f7,
330    0x7ff9, 0x7b82, 0x2307, 0x7254, 0x1c17, 0x1d2c, 0x580d, 0x3b5f, 0x3e99, 0x46ee, 0x3105, 0x5d19,
331    0x38bb, 0x4134, 0x21bc, 0x068a, 0x0e6b, 0x5aa7, 0x68ef, 0x2bd2, 0x71b5, 0x0db8, 0x28c5, 0x5a48,
332    0x14ad, 0x1ec0, 0x2c71, 0x690c, 0x1559, 0x5638, 0x73b2, 0x26c6, 0x301b, 0x2aad, 0x256f, 0x15fd,
333    0x7e60, 0x5a5a, 0x70a8, 0x70a2, 0x3c76, 0x5a00, 0x49b3, 0x0f1d, 0x7a43, 0x18d8, 0x56e1, 0x6101,
334    0x3f86, 0x4ad9, 0x26b4, 0x0305, 0x388c, 0x13e2, 0x36e9, 0x35e4, 0x587c, 0x2e31, 0x5ecb, 0x2ed3,
335    0x4493, 0x40a6, 0x0d5c, 0x57de, 0x5b6b, 0x656c, 0x1ca2, 0x167c, 0x65a5, 0x7597, 0x1f4f, 0x47dd,
336    0x602c, 0x2169, 0x7ccb, 0x7719, 0x07a3, 0x735b, 0x1afd, 0x6315, 0x1fba, 0x36fe, 0x5961, 0x4c63,
337    0x79af, 0x1126, 0x269a, 0x312f, 0x3d20, 0x1783, 0x334b, 0x44a8, 0x6580, 0x2f6b, 0x5174, 0x5daf,
338    0x01b4, 0x15b8, 0x33c1, 0x5c4b, 0x302f, 0x73bf, 0x59ce, 0x0b13, 0x1c9b, 0x2e1b, 0x27f7, 0x00a7,
339    0x7c7e, 0x6763, 0x202e, 0x7a6d, 0x4a1c, 0x20dd, 0x591d, 0x7edb, 0x7c3b, 0x7532, 0x1909, 0x1dd6,
340    0x466a, 0x72d0, 0x2c9a, 0x79d7, 0x0fda, 0x6dc0, 0x4907, 0x0a6c, 0x3f75, 0x34cc, 0x6e42, 0x35e4,
341    0x6dbb, 0x51f0, 0x2af5, 0x441f, 0x6907, 0x27d9, 0x540b, 0x7095, 0x6723, 0x66b3, 0x1f85, 0x6213,
342    0x405b, 0x06ed, 0x1d8b, 0x6550, 0x2585, 0x002e, 0x3c07, 0x5208, 0x7933, 0x3897, 0x777d, 0x03db,
343    0x4d9f, 0x50cc, 0x31f1, 0x3213, 0x4a70, 0x6e2f, 0x78c4, 0x5c1e, 0x391e, 0x0e49, 0x007b, 0x7c8f,
344    0x55d8, 0x51b7, 0x4477, 0x61ac, 0x7eb2, 0x330e, 0x1882, 0x4d04, 0x4b59, 0x3188, 0x74f5, 0x3ebe,
345    0x2a7f, 0x6b8e, 0x705b, 0x6688, 0x1cfc, 0x084d, 0x60ed, 0x1cd9, 0x5799, 0x1f59, 0x0beb, 0x6732,
346    0x6640, 0x782b, 0x455f, 0x5910, 0x7066, 0x26b0, 0x26d2, 0x7e26, 0x22bd, 0x15b3, 0x634e, 0x24f0,
347    0x4649, 0x282b, 0x5631, 0x4539, 0x1b49, 0x4023, 0x48b1, 0x115b, 0x6ca6, 0x5bde, 0x4f40, 0x288f,
348    0x4106, 0x6f41, 0x62fe, 0x09b1, 0x7929, 0x71e0, 0x2a80, 0x2164, 0x66be, 0x3fa8, 0x094b, 0x4a09,
349    0x1177, 0x355f, 0x645a, 0x2940, 0x5a2a, 0x5369, 0x7ade, 0x0a66, 0x74e8, 0x6502, 0x6cbb, 0x1971,
350    0x2ba3, 0x0ab5, 0x2f4f, 0x4539, 0x150e, 0x1dc4, 0x3262, 0x04ed, 0x5df0, 0x35af, 0x5c4a, 0x4fb4,
351    0x5fcd, 0x0dc7, 0x6fef, 0x266e, 0x0be6, 0x69d9, 0x5e02, 0x4650, 0x561f, 0x03e8, 0x26e5, 0x4778,
352    0x6be3, 0x4375, 0x1559, 0x7786, 0x0653, 0x2a4a, 0x4825, 0x70f0, 0x56f2, 0x596f, 0x4f6b, 0x0937,
353    0x4e89, 0x5390, 0x5bf9, 0x03ea, 0x1eb7, 0x1296, 0x1966, 0x77bc, 0x6d2a, 0x3cf1, 0x43a7, 0x01a3,
354    0x2e0f, 0x696e, 0x5654, 0x4ba6, 0x66be, 0x6b16, 0x2c6c, 0x3db4, 0x7b52, 0x2d5f, 0x0b3c, 0x7391,
355    0x25f7, 0x45bf, 0x44c7, 0x7052, 0x3da7, 0x117c, 0x0797, 0x20b9, 0x6b35, 0x61bc, 0x511a, 0x2168,
356    0x7693, 0x6de2, 0x4c7c, 0x04e1, 0x234a, 0x1e36, 0x16c7, 0x2b67, 0x5c40, 0x1dd8, 0x7164, 0x77cc,
357    0x0c10, 0x6789, 0x1a4b, 0x42dd, 0x5ea5, 0x545a, 0x2c55, 0x0eb7, 0x6126, 0x48b6, 0x1a5b, 0x093d,
358    0x77ee, 0x75d6, 0x5e4c, 0x0153, 0x2b53, 0x5587, 0x4e6d, 0x4cff, 0x2afb, 0x37e1, 0x4f61, 0x6ff2,
359    0x1758, 0x74b2, 0x0b70, 0x4146, 0x51b8, 0x51fe, 0x6fae, 0x696b, 0x0a58, 0x43d0, 0x623e, 0x57c4,
360    0x07f8, 0x712c, 0x1221, 0x7378, 0x7c69, 0x7bd0, 0x00f4, 0x35de, 0x6cd7, 0x4947, 0x6344, 0x1575,
361    0x67ed, 0x1bd0, 0x45f3, 0x3d2d, 0x0bd1, 0x66c8, 0x7c11, 0x47b0, 0x19bb, 0x6695, 0x6509, 0x5eed,
362    0x4e6a, 0x19ac, 0x3234, 0x5dab, 0x3a2b, 0x7a79, 0x5c58, 0x2347, 0x434b, 0x32a7, 0x3eb5, 0x1a2a,
363    0x02ec, 0x1f61, 0x62a7, 0x70c0, 0x228e, 0x445d, 0x5ab6, 0x401c, 0x5404, 0x41cd, 0x46a9, 0x3358,
364    0x1cb1, 0x67d6, 0x3106, 0x7ae3, 0x1ea6, 0x2ad7, 0x07d5, 0x7aa5, 0x750a, 0x6601, 0x595b, 0x4867,
365    0x7b8c, 0x0c0c, 0x3f99, 0x7843, 0x27ac, 0x7a3c, 0x7928, 0x20d9, 0x024f, 0x6c8f, 0x1b90, 0x1142,
366    0x75c0, 0x0227, 0x1cb7, 0x4863, 0x7705, 0x553f, 0x7d44, 0x6dff, 0x5f8c, 0x3dae, 0x1984, 0x2410,
367    0x757d, 0x6403, 0x567c, 0x4bda, 0x49de, 0x10e9, 0x6a0a, 0x2054, 0x5cb1, 0x534e, 0x0206, 0x7a42,
368    0x66b3, 0x18f0, 0x604f, 0x1b4f, 0x2b97, 0x1a34, 0x0284, 0x5d71, 0x0642, 0x6390, 0x6d85, 0x2e2a,
369    0x17d9, 0x3d3f, 0x35d6, 0x4118, 0x5700, 0x3e89, 0x6ddb, 0x0dc2, 0x6750, 0x232e, 0x566b, 0x77b6,
370    0x607f, 0x31cc, 0x0c29, 0x602b, 0x50f6, 0x6ac0, 0x305c, 0x181a, 0x4c16, 0x701b, 0x7b3d, 0x20c5,
371    0x3359, 0x7034, 0x1837, 0x090a, 0x5f2d, 0x5837, 0x53dd, 0x6827, 0x0afb, 0x2968, 0x5983, 0x3a36,
372    0x6a3b, 0x0b8e, 0x04e4, 0x3bf7, 0x3bba, 0x2c2b, 0x084e, 0x5ad4, 0x0da4, 0x6828, 0x7332, 0x15f4,
373    0x034d, 0x1c30, 0x6907, 0x6c5f, 0x07c3, 0x0154, 0x69d0, 0x6779, 0x30bc, 0x7bf6, 0x702e, 0x614c,
374    0x2696, 0x76ff, 0x0463, 0x56f7, 0x5cfa, 0x6bf7, 0x6cbc, 0x57d9, 0x4d25, 0x10fb, 0x4e57, 0x3668,
375    0x091c, 0x63a8, 0x1a6d, 0x60b1, 0x5675, 0x62ca, 0x5a16, 0x550e, 0x3b66, 0x1479, 0x6827, 0x1511,
376    0x64e9, 0x7ee7, 0x7b8d, 0x4137, 0x1c46, 0x44e9, 0x6d7c, 0x1709, 0x646e, 0x620a, 0x497a, 0x2971,
377    0x23df, 0x1451, 0x558d, 0x693c, 0x52d6, 0x27e1, 0x487d, 0x404e, 0x092b, 0x1f57, 0x33b7, 0x3748,
378];
379
380impl HashImplementation for RandomVectorHash {
381    const NUM_HASH_BYTES: usize = 3;
382
383    fn get_hash(&self, b: &[u8]) -> u16 {
384        assert!(b.len() >= 3);
385
386        RANDOM_VECTOR[b[0] as usize]
387            ^ RANDOM_VECTOR[b[1] as usize + 256]
388            ^ RANDOM_VECTOR[b[2] as usize + 512]
389    }
390
391    fn algorithm(&self) -> HashAlgorithm {
392        HashAlgorithm::RandomVector
393    }
394}