]> wimlib.net Git - wimlib/blob - include/wimlib/lz_hash.h
Merge LZX compression updates
[wimlib] / include / wimlib / lz_hash.h
1 /*
2  * lz_hash.h
3  *
4  * Hashing for Lempel-Ziv matchfinding.
5  *
6  * Author:      Eric Biggers
7  * Year:        2014, 2015
8  *
9  * The author dedicates this file to the public domain.
10  * You can do whatever you want with this file.
11  */
12
13 #ifndef _WIMLIB_LZ_HASH_H
14 #define _WIMLIB_LZ_HASH_H
15
16 #include "wimlib/unaligned.h"
17
18 /* Constant for the multiplicative hash function.  */
19 #define LZ_HASH_MULTIPLIER 0x1E35A7BD
20
21 static inline u32
22 loaded_u32_to_u24(u32 v)
23 {
24         if (CPU_IS_LITTLE_ENDIAN)
25                 return v & 0xFFFFFF;
26         else
27                 return v >> 8;
28 }
29
30 static inline u32
31 load_u24_unaligned(const u8 *p)
32 {
33         if (UNALIGNED_ACCESS_IS_FAST)
34                 return loaded_u32_to_u24(load_u32_unaligned(p));
35         else
36                 return ((u32)p[0] << 0) | ((u32)p[1] << 8) | ((u32)p[2] << 16);
37 }
38
39 static inline u32
40 lz_hash(u32 str, unsigned num_bits)
41 {
42         return (u32)(str * LZ_HASH_MULTIPLIER) >> (32 - num_bits);
43 }
44
45 /*
46  * Hash the next 3-byte sequence in the window, producing a hash of length
47  * 'num_bits' bits.  At least LZ_HASH_REQUIRED_NBYTES must be available at 'p';
48  * this might be 4 bytes rather than 3 because an unaligned load is faster on
49  * some architectures.
50  */
51 static inline u32
52 lz_hash_3_bytes(const u8 *p, unsigned num_bits)
53 {
54         return lz_hash(load_u24_unaligned(p), num_bits);
55 }
56
57 /* Number of bytes the hash function actually requires be available, due to the
58  * possibility of an unaligned load.  */
59 #define LZ_HASH_REQUIRED_NBYTES (UNALIGNED_ACCESS_IS_FAST ? 4 : 3)
60
61 #endif /* _WIMLIB_LZ_HASH_H */