YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/yb/rocksdb/util/xxhash.cc
Line
Count
Source (jump to first uncovered line)
1
/*
2
xxHash - Fast Hash algorithm
3
Copyright (C) 2012-2014, Yann Collet.
4
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
5
6
Redistribution and use in source and binary forms, with or without
7
modification, are permitted provided that the following conditions are
8
met:
9
10
* Redistributions of source code must retain the above copyright
11
notice, this list of conditions and the following disclaimer.
12
* Redistributions in binary form must reproduce the above
13
copyright notice, this list of conditions and the following disclaimer
14
in the documentation and/or other materials provided with the
15
distribution.
16
17
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29
You can contact the author at :
30
- xxHash source repository : http://code.google.com/p/xxhash/
31
*/
32
33
34
//**************************************
35
// Tuning parameters
36
//**************************************
37
// Unaligned memory access is automatically enabled for "common" CPU, such as x86.
38
// For others CPU, the compiler will be more cautious, and insert extra code to ensure aligned access is respected.
39
// If you know your target CPU supports unaligned memory access, you want to force this option manually to improve performance.
40
// You can also enable this parameter if you know your input data will always be aligned (boundaries of 4, for U32).
41
//
42
// The following only applies to changes made to this file as part of YugaByte development.
43
//
44
// Portions Copyright (c) YugaByte, Inc.
45
//
46
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
47
// in compliance with the License.  You may obtain a copy of the License at
48
//
49
// http://www.apache.org/licenses/LICENSE-2.0
50
//
51
// Unless required by applicable law or agreed to in writing, software distributed under the License
52
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
53
// or implied.  See the License for the specific language governing permissions and limitations
54
// under the License.
55
//
56
#if defined(__ARM_FEATURE_UNALIGNED) || defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
57
#  define XXH_USE_UNALIGNED_ACCESS 1
58
#endif
59
60
// XXH_ACCEPT_NULL_INPUT_POINTER :
61
// If the input pointer is a null pointer, xxHash default behavior is to trigger a memory access error, since it is a bad pointer.
62
// When this option is enabled, xxHash output for null input pointers will be the same as a null-length input.
63
// This option has a very small performance cost (only measurable on small inputs).
64
// By default, this option is disabled. To enable it, uncomment below define :
65
//#define XXH_ACCEPT_NULL_INPUT_POINTER 1
66
67
// XXH_FORCE_NATIVE_FORMAT :
68
// By default, xxHash library provides endian-independent Hash values, based on little-endian convention.
69
// Results are therefore identical for little-endian and big-endian CPU.
70
// This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format.
71
// Should endian-independance be of no importance for your application, you may set the #define below to 1.
72
// It will improve speed for Big-endian CPU.
73
// This option has no impact on Little_Endian CPU.
74
0
#define XXH_FORCE_NATIVE_FORMAT 0
75
76
77
//**************************************
78
// Compiler Specific Options
79
//**************************************
80
// Disable some Visual warning messages
81
#ifdef _MSC_VER  // Visual Studio
82
#  pragma warning(disable : 4127)      // disable: C4127: conditional expression is constant
83
#  pragma warning(disable : 4804)      // disable: C4804: 'operation' : unsafe use of type 'bool' in operation (static assert line 313)
84
#endif
85
86
#ifdef _MSC_VER    // Visual Studio
87
#  define FORCE_INLINE static __forceinline
88
#else
89
#  ifdef __GNUC__
90
#    define FORCE_INLINE static inline __attribute__((always_inline))
91
#  else
92
#    define FORCE_INLINE static inline
93
#  endif
94
#endif
95
96
97
//**************************************
98
// Includes & Memory related functions
99
//**************************************
100
#include "xxhash.h"
101
// Modify the local functions below should you wish to use some other memory related routines
102
// for malloc(), free()
103
#include <stdlib.h>
104
6.99k
FORCE_INLINE void* XXH_malloc(size_t s) { return malloc(s); }
105
6.99k
FORCE_INLINE void  XXH_free  (void* p)  { free(p); }
106
// for memcpy()
107
#include <string.h>
108
12.6k
FORCE_INLINE void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); }
109
110
111
namespace rocksdb {
112
//**************************************
113
// Basic Types
114
//**************************************
115
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L   // C99
116
# include <stdint.h>
117
  typedef uint8_t  BYTE;
118
  typedef uint16_t U16;
119
  typedef uint32_t U32;
120
  typedef  int32_t S32;
121
  typedef uint64_t U64;
122
#else
123
  typedef unsigned char      BYTE;
124
  typedef unsigned short     U16;
125
  typedef unsigned int       U32;
126
  typedef   signed int       S32;
127
  typedef unsigned long long U64;
128
#endif
129
130
#if defined(__GNUC__)  && !defined(XXH_USE_UNALIGNED_ACCESS)
131
#  define _PACKED __attribute__ ((packed))
132
#else
133
#  define _PACKED
134
#endif
135
136
#if !defined(XXH_USE_UNALIGNED_ACCESS) && !defined(__GNUC__)
137
#  ifdef __IBMC__
138
#    pragma pack(1)
139
#  else
140
#    pragma pack(push, 1)
141
#  endif
142
#endif
143
144
typedef struct _U32_S { U32 v; } _PACKED U32_S;
145
146
#if !defined(XXH_USE_UNALIGNED_ACCESS) && !defined(__GNUC__)
147
#  pragma pack(pop)
148
#endif
149
150
4.76M
#define A32(x) (((U32_S *)(x))->v)
151
152
153
//***************************************
154
// Compiler-specific Functions and Macros
155
//***************************************
156
#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
157
158
// Note : although _rotl exists for minGW (GCC under windows), performance seems poor
159
#if defined(_MSC_VER)
160
#  define XXH_rotl32(x,r) _rotl(x,r)
161
#else
162
4.84M
#  define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r)))
163
#endif
164
165
#if defined(_MSC_VER)     // Visual Studio
166
#  define XXH_swap32 _byteswap_ulong
167
#elif GCC_VERSION >= 403
168
#  define XXH_swap32 __builtin_bswap32
169
#else
170
0
static inline U32 XXH_swap32 (U32 x) {
171
0
    return  ((x << 24) & 0xff000000 ) |
172
0
        ((x <<  8) & 0x00ff0000 ) |
173
0
        ((x >>  8) & 0x0000ff00 ) |
174
0
        ((x >> 24) & 0x000000ff );}
175
#endif
176
177
178
//**************************************
179
// Constants
180
//**************************************
181
4.80M
#define PRIME32_1   2654435761U
182
4.79M
#define PRIME32_2   2246822519U
183
32.2k
#define PRIME32_3   3266489917U
184
17.7k
#define PRIME32_4    668265263U
185
20.7k
#define PRIME32_5    374761393U
186
187
188
//**************************************
189
// Architecture Macros
190
//**************************************
191
typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess;
192
#ifndef XXH_CPU_LITTLE_ENDIAN   // It is possible to define XXH_CPU_LITTLE_ENDIAN externally, for example using a compiler switch
193
    static const int one = 1;
194
28.5k
#   define XXH_CPU_LITTLE_ENDIAN   (*(char*)(&one))
195
#endif
196
197
198
//**************************************
199
// Macros
200
//**************************************
201
0
#define XXH_STATIC_ASSERT(c)   { enum { XXH_static_assert = 1/(!!(c)) }; }    // use only *after* variable declarations
202
203
204
//****************************
205
// Memory reads
206
//****************************
207
typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment;
208
209
FORCE_INLINE U32 XXH_readLE32_align(const U32* ptr, XXH_endianess endian, XXH_alignment align)
210
4.76M
{
211
4.76M
    if (align==XXH_unaligned)
212
18.4E
        
return 4.76M
endian==XXH_littleEndian4.76M
?
A324.76M
(ptr) : XXH_swap32(A32(ptr));
213
49
    else
214
49
        return endian==XXH_littleEndian ? 
*ptr0
: XXH_swap32(*ptr);
215
4.76M
}
216
217
3.09M
FORCE_INLINE U32 XXH_readLE32(const U32* ptr, XXH_endianess endian) { return XXH_readLE32_align(ptr, endian, XXH_unaligned); }
218
219
220
//****************************
221
// Simple Hash Functions
222
//****************************
223
FORCE_INLINE U32 XXH32_endian_align(const void* input, int len, U32 seed, XXH_endianess endian, XXH_alignment align)
224
7.57k
{
225
7.57k
    const BYTE* p = (const BYTE*)input;
226
7.57k
    const BYTE* const bEnd = p + len;
227
7.57k
    U32 h32;
228
229
#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
230
    if (p==NULL) { len=0; p=(const BYTE*)(size_t)16; }
231
#endif
232
233
7.57k
    if (len>=16)
234
7.57k
    {
235
7.57k
        const BYTE* const limit = bEnd - 16;
236
7.57k
        U32 v1 = seed + PRIME32_1 + PRIME32_2;
237
7.57k
        U32 v2 = seed + PRIME32_2;
238
7.57k
        U32 v3 = seed + 0;
239
7.57k
        U32 v4 = seed - PRIME32_1;
240
241
7.57k
        do
242
416k
        {
243
416k
            v1 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v1 = XXH_rotl32(v1, 13); v1 *= PRIME32_1; p+=4;
244
416k
            v2 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v2 = XXH_rotl32(v2, 13); v2 *= PRIME32_1; p+=4;
245
416k
            v3 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v3 = XXH_rotl32(v3, 13); v3 *= PRIME32_1; p+=4;
246
416k
            v4 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v4 = XXH_rotl32(v4, 13); v4 *= PRIME32_1; p+=4;
247
416k
        } while (p<=limit);
248
249
7.57k
        h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);
250
7.57k
    }
251
18.4E
    else
252
18.4E
    {
253
18.4E
        h32  = seed + PRIME32_5;
254
18.4E
    }
255
256
7.57k
    h32 += (U32) len;
257
258
17.1k
    while (p<=bEnd-4)
259
9.58k
    {
260
9.58k
        h32 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_3;
261
9.58k
        h32  = XXH_rotl32(h32, 17) * PRIME32_4 ;
262
9.58k
        p+=4;
263
9.58k
    }
264
265
18.5k
    while (p<bEnd)
266
10.9k
    {
267
10.9k
        h32 += (*p) * PRIME32_5;
268
10.9k
        h32 = XXH_rotl32(h32, 11) * PRIME32_1 ;
269
10.9k
        p++;
270
10.9k
    }
271
272
7.57k
    h32 ^= h32 >> 15;
273
7.57k
    h32 *= PRIME32_2;
274
7.57k
    h32 ^= h32 >> 13;
275
7.57k
    h32 *= PRIME32_3;
276
7.57k
    h32 ^= h32 >> 16;
277
278
7.57k
    return h32;
279
7.57k
}
280
281
282
U32 XXH32(const void* input, int len, U32 seed)
283
7.57k
{
284
#if 0
285
    // Simple version, good for code maintenance, but unfortunately slow for small inputs
286
    void* state = XXH32_init(seed);
287
    XXH32_update(state, input, len);
288
    return XXH32_digest(state);
289
#else
290
7.57k
    XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
291
292
#  if !defined(XXH_USE_UNALIGNED_ACCESS)
293
    if ((((size_t)input) & 3))   // Input is aligned, let's leverage the speed advantage
294
    {
295
        if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
296
            return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
297
        else
298
            return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);
299
    }
300
#  endif
301
302
7.57k
    if ((endian_detected==XXH_littleEndian) || 
XXH_FORCE_NATIVE_FORMAT0
)
303
7.57k
        return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);
304
0
    else
305
0
        return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned);
306
7.57k
#endif
307
7.57k
}
308
309
310
//****************************
311
// Advanced Hash Functions
312
//****************************
313
314
struct XXH_state32_t
315
{
316
    U64 total_len;
317
    U32 seed;
318
    U32 v1;
319
    U32 v2;
320
    U32 v3;
321
    U32 v4;
322
    int memsize;
323
    char memory[16];
324
};
325
326
327
int XXH32_sizeofState()
328
0
{
329
0
    XXH_STATIC_ASSERT(XXH32_SIZEOFSTATE >= sizeof(struct XXH_state32_t));   // A compilation error here means XXH32_SIZEOFSTATE is not large enough
330
0
    return sizeof(struct XXH_state32_t);
331
0
}
332
333
334
XXH_errorcode XXH32_resetState(void* state_in, U32 seed)
335
6.99k
{
336
6.99k
    struct XXH_state32_t * state = (struct XXH_state32_t *) state_in;
337
6.99k
    state->seed = seed;
338
6.99k
    state->v1 = seed + PRIME32_1 + PRIME32_2;
339
6.99k
    state->v2 = seed + PRIME32_2;
340
6.99k
    state->v3 = seed + 0;
341
6.99k
    state->v4 = seed - PRIME32_1;
342
6.99k
    state->total_len = 0;
343
6.99k
    state->memsize = 0;
344
6.99k
    return XXH_OK;
345
6.99k
}
346
347
348
void* XXH32_init (U32 seed)
349
6.99k
{
350
6.99k
    void* state = XXH_malloc (sizeof(struct XXH_state32_t));
351
6.99k
    XXH32_resetState(state, seed);
352
6.99k
    return state;
353
6.99k
}
354
355
356
FORCE_INLINE XXH_errorcode XXH32_update_endian (void* state_in, const void* input, int len, XXH_endianess endian)
357
13.9k
{
358
13.9k
    struct XXH_state32_t * state = (struct XXH_state32_t *) state_in;
359
13.9k
    const BYTE* p = (const BYTE*)input;
360
13.9k
    const BYTE* const bEnd = p + len;
361
362
#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
363
    if (input==NULL) return XXH_ERROR;
364
#endif
365
366
13.9k
    state->total_len += len;
367
368
13.9k
    if (state->memsize + len < 16)   // fill in tmp buffer
369
6.74k
    {
370
6.74k
        XXH_memcpy(state->memory + state->memsize, input, len);
371
6.74k
        state->memsize +=  len;
372
6.74k
        return XXH_OK;
373
6.74k
    }
374
375
7.23k
    if (state->memsize)   // some data left from previous update
376
246
    {
377
246
        XXH_memcpy(state->memory + state->memsize, input, 16-state->memsize);
378
246
        {
379
246
            const U32* p32 = (const U32*)state->memory;
380
246
            state->v1 += XXH_readLE32(p32, endian) * PRIME32_2; state->v1 = XXH_rotl32(state->v1, 13); state->v1 *= PRIME32_1; p32++;
381
246
            state->v2 += XXH_readLE32(p32, endian) * PRIME32_2; state->v2 = XXH_rotl32(state->v2, 13); state->v2 *= PRIME32_1; p32++;
382
246
            state->v3 += XXH_readLE32(p32, endian) * PRIME32_2; state->v3 = XXH_rotl32(state->v3, 13); state->v3 *= PRIME32_1; p32++;
383
246
            state->v4 += XXH_readLE32(p32, endian) * PRIME32_2; state->v4 = XXH_rotl32(state->v4, 13); state->v4 *= PRIME32_1; p32++;
384
246
        }
385
246
        p += 16-state->memsize;
386
246
        state->memsize = 0;
387
246
    }
388
389
7.23k
    if (p <= bEnd-16)
390
6.99k
    {
391
6.99k
        const BYTE* const limit = bEnd - 16;
392
6.99k
        U32 v1 = state->v1;
393
6.99k
        U32 v2 = state->v2;
394
6.99k
        U32 v3 = state->v3;
395
6.99k
        U32 v4 = state->v4;
396
397
6.99k
        do
398
770k
        {
399
770k
            v1 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v1 = XXH_rotl32(v1, 13); v1 *= PRIME32_1; p+=4;
400
770k
            v2 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v2 = XXH_rotl32(v2, 13); v2 *= PRIME32_1; p+=4;
401
770k
            v3 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v3 = XXH_rotl32(v3, 13); v3 *= PRIME32_1; p+=4;
402
770k
            v4 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v4 = XXH_rotl32(v4, 13); v4 *= PRIME32_1; p+=4;
403
770k
        } while (p<=limit);
404
405
6.99k
        state->v1 = v1;
406
6.99k
        state->v2 = v2;
407
6.99k
        state->v3 = v3;
408
6.99k
        state->v4 = v4;
409
6.99k
    }
410
411
7.23k
    if (p < bEnd)
412
5.67k
    {
413
5.67k
        XXH_memcpy(state->memory, p, bEnd-p);
414
5.67k
        state->memsize = (int)(bEnd-p);
415
5.67k
    }
416
417
7.23k
    return XXH_OK;
418
13.9k
}
419
420
XXH_errorcode XXH32_update (void* state_in, const void* input, int len)
421
13.9k
{
422
13.9k
    XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
423
424
13.9k
    if ((endian_detected==XXH_littleEndian) || 
XXH_FORCE_NATIVE_FORMAT0
)
425
13.9k
        return XXH32_update_endian(state_in, input, len, XXH_littleEndian);
426
0
    else
427
0
        return XXH32_update_endian(state_in, input, len, XXH_bigEndian);
428
13.9k
}
429
430
431
432
FORCE_INLINE U32 XXH32_intermediateDigest_endian (void* state_in, XXH_endianess endian)
433
6.99k
{
434
6.99k
    struct XXH_state32_t * state = (struct XXH_state32_t *) state_in;
435
6.99k
    const BYTE * p = (const BYTE*)state->memory;
436
6.99k
    BYTE* bEnd = (BYTE*)state->memory + state->memsize;
437
6.99k
    U32 h32;
438
439
6.99k
    if (state->total_len >= 16)
440
6.99k
    {
441
6.99k
        h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18);
442
6.99k
    }
443
18.4E
    else
444
18.4E
    {
445
18.4E
        h32  = state->seed + PRIME32_5;
446
18.4E
    }
447
448
6.99k
    h32 += (U32) state->total_len;
449
450
15.1k
    while (p<=bEnd-4)
451
8.14k
    {
452
8.14k
        h32 += XXH_readLE32((const U32*)p, endian) * PRIME32_3;
453
8.14k
        h32  = XXH_rotl32(h32, 17) * PRIME32_4;
454
8.14k
        p+=4;
455
8.14k
    }
456
457
16.7k
    while (p<bEnd)
458
9.74k
    {
459
9.74k
        h32 += (*p) * PRIME32_5;
460
9.74k
        h32 = XXH_rotl32(h32, 11) * PRIME32_1;
461
9.74k
        p++;
462
9.74k
    }
463
464
6.99k
    h32 ^= h32 >> 15;
465
6.99k
    h32 *= PRIME32_2;
466
6.99k
    h32 ^= h32 >> 13;
467
6.99k
    h32 *= PRIME32_3;
468
6.99k
    h32 ^= h32 >> 16;
469
470
6.99k
    return h32;
471
6.99k
}
472
473
474
U32 XXH32_intermediateDigest (void* state_in)
475
6.99k
{
476
6.99k
    XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
477
478
6.99k
    if ((endian_detected==XXH_littleEndian) || 
XXH_FORCE_NATIVE_FORMAT0
)
479
6.99k
        return XXH32_intermediateDigest_endian(state_in, XXH_littleEndian);
480
0
    else
481
0
        return XXH32_intermediateDigest_endian(state_in, XXH_bigEndian);
482
6.99k
}
483
484
485
U32 XXH32_digest (void* state_in)
486
6.99k
{
487
6.99k
    U32 h32 = XXH32_intermediateDigest(state_in);
488
489
6.99k
    XXH_free(state_in);
490
491
6.99k
    return h32;
492
6.99k
}
493
494
}  // namespace rocksdb