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