xref: /aosp_15_r20/external/erofs-utils/lib/xxhash.c (revision 33b1fccf6a0fada2c2875d400ed01119b7676ee5)
1*33b1fccfSAndroid Build Coastguard Worker // SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0-only
2*33b1fccfSAndroid Build Coastguard Worker /*
3*33b1fccfSAndroid Build Coastguard Worker  * The xxhash is copied from the linux kernel at:
4*33b1fccfSAndroid Build Coastguard Worker  *	https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/lib/xxhash.c
5*33b1fccfSAndroid Build Coastguard Worker  *
6*33b1fccfSAndroid Build Coastguard Worker  * The original copyright is:
7*33b1fccfSAndroid Build Coastguard Worker  *
8*33b1fccfSAndroid Build Coastguard Worker  * xxHash - Extremely Fast Hash algorithm
9*33b1fccfSAndroid Build Coastguard Worker  * Copyright (C) 2012-2016, Yann Collet.
10*33b1fccfSAndroid Build Coastguard Worker  *
11*33b1fccfSAndroid Build Coastguard Worker  * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
12*33b1fccfSAndroid Build Coastguard Worker  *
13*33b1fccfSAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
14*33b1fccfSAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions are
15*33b1fccfSAndroid Build Coastguard Worker  * met:
16*33b1fccfSAndroid Build Coastguard Worker  *
17*33b1fccfSAndroid Build Coastguard Worker  *   * Redistributions of source code must retain the above copyright
18*33b1fccfSAndroid Build Coastguard Worker  *     notice, this list of conditions and the following disclaimer.
19*33b1fccfSAndroid Build Coastguard Worker  *   * Redistributions in binary form must reproduce the above
20*33b1fccfSAndroid Build Coastguard Worker  *     copyright notice, this list of conditions and the following disclaimer
21*33b1fccfSAndroid Build Coastguard Worker  *     in the documentation and/or other materials provided with the
22*33b1fccfSAndroid Build Coastguard Worker  *     distribution.
23*33b1fccfSAndroid Build Coastguard Worker  *
24*33b1fccfSAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25*33b1fccfSAndroid Build Coastguard Worker  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26*33b1fccfSAndroid Build Coastguard Worker  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27*33b1fccfSAndroid Build Coastguard Worker  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28*33b1fccfSAndroid Build Coastguard Worker  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29*33b1fccfSAndroid Build Coastguard Worker  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30*33b1fccfSAndroid Build Coastguard Worker  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31*33b1fccfSAndroid Build Coastguard Worker  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32*33b1fccfSAndroid Build Coastguard Worker  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33*33b1fccfSAndroid Build Coastguard Worker  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34*33b1fccfSAndroid Build Coastguard Worker  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35*33b1fccfSAndroid Build Coastguard Worker  *
36*33b1fccfSAndroid Build Coastguard Worker  * This program is free software; you can redistribute it and/or modify it under
37*33b1fccfSAndroid Build Coastguard Worker  * the terms of the GNU General Public License version 2 as published by the
38*33b1fccfSAndroid Build Coastguard Worker  * Free Software Foundation. This program is dual-licensed; you may select
39*33b1fccfSAndroid Build Coastguard Worker  * either version 2 of the GNU General Public License ("GPL") or BSD license
40*33b1fccfSAndroid Build Coastguard Worker  * ("BSD").
41*33b1fccfSAndroid Build Coastguard Worker  *
42*33b1fccfSAndroid Build Coastguard Worker  * You can contact the author at:
43*33b1fccfSAndroid Build Coastguard Worker  * - xxHash homepage: https://cyan4973.github.io/xxHash/
44*33b1fccfSAndroid Build Coastguard Worker  * - xxHash source repository: https://github.com/Cyan4973/xxHash
45*33b1fccfSAndroid Build Coastguard Worker  */
46*33b1fccfSAndroid Build Coastguard Worker #include "erofs/defs.h"
47*33b1fccfSAndroid Build Coastguard Worker #include "xxhash.h"
48*33b1fccfSAndroid Build Coastguard Worker 
49*33b1fccfSAndroid Build Coastguard Worker /*-*************************************
50*33b1fccfSAndroid Build Coastguard Worker  * Macros
51*33b1fccfSAndroid Build Coastguard Worker  **************************************/
52*33b1fccfSAndroid Build Coastguard Worker #define xxh_rotl32(x, r) ((x << r) | (x >> (32 - r)))
53*33b1fccfSAndroid Build Coastguard Worker #define xxh_rotl64(x, r) ((x << r) | (x >> (64 - r)))
54*33b1fccfSAndroid Build Coastguard Worker 
55*33b1fccfSAndroid Build Coastguard Worker /*-*************************************
56*33b1fccfSAndroid Build Coastguard Worker  * Constants
57*33b1fccfSAndroid Build Coastguard Worker  **************************************/
58*33b1fccfSAndroid Build Coastguard Worker static const uint32_t PRIME32_1 = 2654435761U;
59*33b1fccfSAndroid Build Coastguard Worker static const uint32_t PRIME32_2 = 2246822519U;
60*33b1fccfSAndroid Build Coastguard Worker static const uint32_t PRIME32_3 = 3266489917U;
61*33b1fccfSAndroid Build Coastguard Worker static const uint32_t PRIME32_4 =  668265263U;
62*33b1fccfSAndroid Build Coastguard Worker static const uint32_t PRIME32_5 =  374761393U;
63*33b1fccfSAndroid Build Coastguard Worker 
64*33b1fccfSAndroid Build Coastguard Worker static const uint64_t PRIME64_1 = 11400714785074694791ULL;
65*33b1fccfSAndroid Build Coastguard Worker static const uint64_t PRIME64_2 = 14029467366897019727ULL;
66*33b1fccfSAndroid Build Coastguard Worker static const uint64_t PRIME64_3 =  1609587929392839161ULL;
67*33b1fccfSAndroid Build Coastguard Worker static const uint64_t PRIME64_4 =  9650029242287828579ULL;
68*33b1fccfSAndroid Build Coastguard Worker static const uint64_t PRIME64_5 =  2870177450012600261ULL;
69*33b1fccfSAndroid Build Coastguard Worker 
70*33b1fccfSAndroid Build Coastguard Worker /*-***************************
71*33b1fccfSAndroid Build Coastguard Worker  * Simple Hash Functions
72*33b1fccfSAndroid Build Coastguard Worker  ****************************/
xxh32_round(uint32_t seed,const uint32_t input)73*33b1fccfSAndroid Build Coastguard Worker static uint32_t xxh32_round(uint32_t seed, const uint32_t input)
74*33b1fccfSAndroid Build Coastguard Worker {
75*33b1fccfSAndroid Build Coastguard Worker 	seed += input * PRIME32_2;
76*33b1fccfSAndroid Build Coastguard Worker 	seed = xxh_rotl32(seed, 13);
77*33b1fccfSAndroid Build Coastguard Worker 	seed *= PRIME32_1;
78*33b1fccfSAndroid Build Coastguard Worker 	return seed;
79*33b1fccfSAndroid Build Coastguard Worker }
80*33b1fccfSAndroid Build Coastguard Worker 
xxh32(const void * input,const size_t len,const uint32_t seed)81*33b1fccfSAndroid Build Coastguard Worker uint32_t xxh32(const void *input, const size_t len, const uint32_t seed)
82*33b1fccfSAndroid Build Coastguard Worker {
83*33b1fccfSAndroid Build Coastguard Worker 	const uint8_t *p = (const uint8_t *)input;
84*33b1fccfSAndroid Build Coastguard Worker 	const uint8_t *b_end = p + len;
85*33b1fccfSAndroid Build Coastguard Worker 	uint32_t h32;
86*33b1fccfSAndroid Build Coastguard Worker 
87*33b1fccfSAndroid Build Coastguard Worker 	if (len >= 16) {
88*33b1fccfSAndroid Build Coastguard Worker 		const uint8_t *const limit = b_end - 16;
89*33b1fccfSAndroid Build Coastguard Worker 		uint32_t v1 = seed + PRIME32_1 + PRIME32_2;
90*33b1fccfSAndroid Build Coastguard Worker 		uint32_t v2 = seed + PRIME32_2;
91*33b1fccfSAndroid Build Coastguard Worker 		uint32_t v3 = seed + 0;
92*33b1fccfSAndroid Build Coastguard Worker 		uint32_t v4 = seed - PRIME32_1;
93*33b1fccfSAndroid Build Coastguard Worker 
94*33b1fccfSAndroid Build Coastguard Worker 		do {
95*33b1fccfSAndroid Build Coastguard Worker 			v1 = xxh32_round(v1, get_unaligned_le32(p));
96*33b1fccfSAndroid Build Coastguard Worker 			p += 4;
97*33b1fccfSAndroid Build Coastguard Worker 			v2 = xxh32_round(v2, get_unaligned_le32(p));
98*33b1fccfSAndroid Build Coastguard Worker 			p += 4;
99*33b1fccfSAndroid Build Coastguard Worker 			v3 = xxh32_round(v3, get_unaligned_le32(p));
100*33b1fccfSAndroid Build Coastguard Worker 			p += 4;
101*33b1fccfSAndroid Build Coastguard Worker 			v4 = xxh32_round(v4, get_unaligned_le32(p));
102*33b1fccfSAndroid Build Coastguard Worker 			p += 4;
103*33b1fccfSAndroid Build Coastguard Worker 		} while (p <= limit);
104*33b1fccfSAndroid Build Coastguard Worker 
105*33b1fccfSAndroid Build Coastguard Worker 		h32 = xxh_rotl32(v1, 1) + xxh_rotl32(v2, 7) +
106*33b1fccfSAndroid Build Coastguard Worker 			xxh_rotl32(v3, 12) + xxh_rotl32(v4, 18);
107*33b1fccfSAndroid Build Coastguard Worker 	} else {
108*33b1fccfSAndroid Build Coastguard Worker 		h32 = seed + PRIME32_5;
109*33b1fccfSAndroid Build Coastguard Worker 	}
110*33b1fccfSAndroid Build Coastguard Worker 
111*33b1fccfSAndroid Build Coastguard Worker 	h32 += (uint32_t)len;
112*33b1fccfSAndroid Build Coastguard Worker 
113*33b1fccfSAndroid Build Coastguard Worker 	while (p + 4 <= b_end) {
114*33b1fccfSAndroid Build Coastguard Worker 		h32 += get_unaligned_le32(p) * PRIME32_3;
115*33b1fccfSAndroid Build Coastguard Worker 		h32 = xxh_rotl32(h32, 17) * PRIME32_4;
116*33b1fccfSAndroid Build Coastguard Worker 		p += 4;
117*33b1fccfSAndroid Build Coastguard Worker 	}
118*33b1fccfSAndroid Build Coastguard Worker 
119*33b1fccfSAndroid Build Coastguard Worker 	while (p < b_end) {
120*33b1fccfSAndroid Build Coastguard Worker 		h32 += (*p) * PRIME32_5;
121*33b1fccfSAndroid Build Coastguard Worker 		h32 = xxh_rotl32(h32, 11) * PRIME32_1;
122*33b1fccfSAndroid Build Coastguard Worker 		p++;
123*33b1fccfSAndroid Build Coastguard Worker 	}
124*33b1fccfSAndroid Build Coastguard Worker 
125*33b1fccfSAndroid Build Coastguard Worker 	h32 ^= h32 >> 15;
126*33b1fccfSAndroid Build Coastguard Worker 	h32 *= PRIME32_2;
127*33b1fccfSAndroid Build Coastguard Worker 	h32 ^= h32 >> 13;
128*33b1fccfSAndroid Build Coastguard Worker 	h32 *= PRIME32_3;
129*33b1fccfSAndroid Build Coastguard Worker 	h32 ^= h32 >> 16;
130*33b1fccfSAndroid Build Coastguard Worker 
131*33b1fccfSAndroid Build Coastguard Worker 	return h32;
132*33b1fccfSAndroid Build Coastguard Worker }
133*33b1fccfSAndroid Build Coastguard Worker 
xxh64_round(uint64_t acc,const uint64_t input)134*33b1fccfSAndroid Build Coastguard Worker static uint64_t xxh64_round(uint64_t acc, const uint64_t input)
135*33b1fccfSAndroid Build Coastguard Worker {
136*33b1fccfSAndroid Build Coastguard Worker 	acc += input * PRIME64_2;
137*33b1fccfSAndroid Build Coastguard Worker 	acc = xxh_rotl64(acc, 31);
138*33b1fccfSAndroid Build Coastguard Worker 	acc *= PRIME64_1;
139*33b1fccfSAndroid Build Coastguard Worker 	return acc;
140*33b1fccfSAndroid Build Coastguard Worker }
141*33b1fccfSAndroid Build Coastguard Worker 
xxh64_merge_round(uint64_t acc,uint64_t val)142*33b1fccfSAndroid Build Coastguard Worker static uint64_t xxh64_merge_round(uint64_t acc, uint64_t val)
143*33b1fccfSAndroid Build Coastguard Worker {
144*33b1fccfSAndroid Build Coastguard Worker 	val = xxh64_round(0, val);
145*33b1fccfSAndroid Build Coastguard Worker 	acc ^= val;
146*33b1fccfSAndroid Build Coastguard Worker 	acc = acc * PRIME64_1 + PRIME64_4;
147*33b1fccfSAndroid Build Coastguard Worker 	return acc;
148*33b1fccfSAndroid Build Coastguard Worker }
149*33b1fccfSAndroid Build Coastguard Worker 
xxh64(const void * input,const size_t len,const uint64_t seed)150*33b1fccfSAndroid Build Coastguard Worker uint64_t xxh64(const void *input, const size_t len, const uint64_t seed)
151*33b1fccfSAndroid Build Coastguard Worker {
152*33b1fccfSAndroid Build Coastguard Worker 	const uint8_t *p = (const uint8_t *)input;
153*33b1fccfSAndroid Build Coastguard Worker 	const uint8_t *const b_end = p + len;
154*33b1fccfSAndroid Build Coastguard Worker 	uint64_t h64;
155*33b1fccfSAndroid Build Coastguard Worker 
156*33b1fccfSAndroid Build Coastguard Worker 	if (len >= 32) {
157*33b1fccfSAndroid Build Coastguard Worker 		const uint8_t *const limit = b_end - 32;
158*33b1fccfSAndroid Build Coastguard Worker 		uint64_t v1 = seed + PRIME64_1 + PRIME64_2;
159*33b1fccfSAndroid Build Coastguard Worker 		uint64_t v2 = seed + PRIME64_2;
160*33b1fccfSAndroid Build Coastguard Worker 		uint64_t v3 = seed + 0;
161*33b1fccfSAndroid Build Coastguard Worker 		uint64_t v4 = seed - PRIME64_1;
162*33b1fccfSAndroid Build Coastguard Worker 
163*33b1fccfSAndroid Build Coastguard Worker 		do {
164*33b1fccfSAndroid Build Coastguard Worker 			v1 = xxh64_round(v1, get_unaligned_le64(p));
165*33b1fccfSAndroid Build Coastguard Worker 			p += 8;
166*33b1fccfSAndroid Build Coastguard Worker 			v2 = xxh64_round(v2, get_unaligned_le64(p));
167*33b1fccfSAndroid Build Coastguard Worker 			p += 8;
168*33b1fccfSAndroid Build Coastguard Worker 			v3 = xxh64_round(v3, get_unaligned_le64(p));
169*33b1fccfSAndroid Build Coastguard Worker 			p += 8;
170*33b1fccfSAndroid Build Coastguard Worker 			v4 = xxh64_round(v4, get_unaligned_le64(p));
171*33b1fccfSAndroid Build Coastguard Worker 			p += 8;
172*33b1fccfSAndroid Build Coastguard Worker 		} while (p <= limit);
173*33b1fccfSAndroid Build Coastguard Worker 
174*33b1fccfSAndroid Build Coastguard Worker 		h64 = xxh_rotl64(v1, 1) + xxh_rotl64(v2, 7) +
175*33b1fccfSAndroid Build Coastguard Worker 			xxh_rotl64(v3, 12) + xxh_rotl64(v4, 18);
176*33b1fccfSAndroid Build Coastguard Worker 		h64 = xxh64_merge_round(h64, v1);
177*33b1fccfSAndroid Build Coastguard Worker 		h64 = xxh64_merge_round(h64, v2);
178*33b1fccfSAndroid Build Coastguard Worker 		h64 = xxh64_merge_round(h64, v3);
179*33b1fccfSAndroid Build Coastguard Worker 		h64 = xxh64_merge_round(h64, v4);
180*33b1fccfSAndroid Build Coastguard Worker 
181*33b1fccfSAndroid Build Coastguard Worker 	} else {
182*33b1fccfSAndroid Build Coastguard Worker 		h64  = seed + PRIME64_5;
183*33b1fccfSAndroid Build Coastguard Worker 	}
184*33b1fccfSAndroid Build Coastguard Worker 
185*33b1fccfSAndroid Build Coastguard Worker 	h64 += (uint64_t)len;
186*33b1fccfSAndroid Build Coastguard Worker 
187*33b1fccfSAndroid Build Coastguard Worker 	while (p + 8 <= b_end) {
188*33b1fccfSAndroid Build Coastguard Worker 		const uint64_t k1 = xxh64_round(0, get_unaligned_le64(p));
189*33b1fccfSAndroid Build Coastguard Worker 
190*33b1fccfSAndroid Build Coastguard Worker 		h64 ^= k1;
191*33b1fccfSAndroid Build Coastguard Worker 		h64 = xxh_rotl64(h64, 27) * PRIME64_1 + PRIME64_4;
192*33b1fccfSAndroid Build Coastguard Worker 		p += 8;
193*33b1fccfSAndroid Build Coastguard Worker 	}
194*33b1fccfSAndroid Build Coastguard Worker 
195*33b1fccfSAndroid Build Coastguard Worker 	if (p + 4 <= b_end) {
196*33b1fccfSAndroid Build Coastguard Worker 		h64 ^= (uint64_t)(get_unaligned_le32(p)) * PRIME64_1;
197*33b1fccfSAndroid Build Coastguard Worker 		h64 = xxh_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
198*33b1fccfSAndroid Build Coastguard Worker 		p += 4;
199*33b1fccfSAndroid Build Coastguard Worker 	}
200*33b1fccfSAndroid Build Coastguard Worker 
201*33b1fccfSAndroid Build Coastguard Worker 	while (p < b_end) {
202*33b1fccfSAndroid Build Coastguard Worker 		h64 ^= (*p) * PRIME64_5;
203*33b1fccfSAndroid Build Coastguard Worker 		h64 = xxh_rotl64(h64, 11) * PRIME64_1;
204*33b1fccfSAndroid Build Coastguard Worker 		p++;
205*33b1fccfSAndroid Build Coastguard Worker 	}
206*33b1fccfSAndroid Build Coastguard Worker 
207*33b1fccfSAndroid Build Coastguard Worker 	h64 ^= h64 >> 33;
208*33b1fccfSAndroid Build Coastguard Worker 	h64 *= PRIME64_2;
209*33b1fccfSAndroid Build Coastguard Worker 	h64 ^= h64 >> 29;
210*33b1fccfSAndroid Build Coastguard Worker 	h64 *= PRIME64_3;
211*33b1fccfSAndroid Build Coastguard Worker 	h64 ^= h64 >> 32;
212*33b1fccfSAndroid Build Coastguard Worker 
213*33b1fccfSAndroid Build Coastguard Worker 	return h64;
214*33b1fccfSAndroid Build Coastguard Worker }
215