YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/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
12.1k
FORCE_INLINE void* XXH_malloc(size_t s) { return malloc(s); }
105
12.1k
FORCE_INLINE void  XXH_free  (void* p)  { free(p); }
106
// for memcpy()
107
#include <string.h>
108
22.7k
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
5.52M
#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
5.65M
#  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
5.58M
#define PRIME32_1   2654435761U
182
5.57M
#define PRIME32_2   2246822519U
183
51.4k
#define PRIME32_3   3266489917U
184
28.0k
#define PRIME32_4    668265263U
185
33.2k
#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
47.7k
#   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
5.52M
{
211
5.52M
    if (align==XXH_unaligned)
212
5.52M
        return endian==XXH_littleEndian ? A32(ptr) : XXH_swap32(A32(ptr));
213
18.4E
    else
214
18.4E
        return endian==XXH_littleEndian ? *ptr : XXH_swap32(*ptr);
215
5.52M
}
216
217
3.53M
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
11.2k
{
225
11.2k
    const BYTE* p = (const BYTE*)input;
226
11.2k
    const BYTE* const bEnd = p + len;
227
11.2k
    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
11.2k
    if (len>=16)
234
11.2k
    {
235
11.2k
        const BYTE* const limit = bEnd - 16;
236
11.2k
        U32 v1 = seed + PRIME32_1 + PRIME32_2;
237
11.2k
        U32 v2 = seed + PRIME32_2;
238
11.2k
        U32 v3 = seed + 0;
239
11.2k
        U32 v4 = seed - PRIME32_1;
240
241
11.2k
        do
242
495k
        {
243
495k
            v1 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v1 = XXH_rotl32(v1, 13); v1 *= PRIME32_1; p+=4;
244
495k
            v2 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v2 = XXH_rotl32(v2, 13); v2 *= PRIME32_1; p+=4;
245
495k
            v3 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v3 = XXH_rotl32(v3, 13); v3 *= PRIME32_1; p+=4;
246
495k
            v4 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v4 = XXH_rotl32(v4, 13); v4 *= PRIME32_1; p+=4;
247
495k
        } while (p<=limit);
248
249
11.2k
        h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);
250
11.2k
    }
251
0
    else
252
0
    {
253
0
        h32  = seed + PRIME32_5;
254
0
    }
255
256
11.2k
    h32 += (U32) len;
257
258
25.1k
    while (p<=bEnd-4)
259
13.8k
    {
260
13.8k
        h32 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_3;
261
13.8k
        h32  = XXH_rotl32(h32, 17) * PRIME32_4 ;
262
13.8k
        p+=4;
263
13.8k
    }
264
265
27.4k
    while (p<bEnd)
266
16.1k
    {
267
16.1k
        h32 += (*p) * PRIME32_5;
268
16.1k
        h32 = XXH_rotl32(h32, 11) * PRIME32_1 ;
269
16.1k
        p++;
270
16.1k
    }
271
272
11.2k
    h32 ^= h32 >> 15;
273
11.2k
    h32 *= PRIME32_2;
274
11.2k
    h32 ^= h32 >> 13;
275
11.2k
    h32 *= PRIME32_3;
276
11.2k
    h32 ^= h32 >> 16;
277
278
11.2k
    return h32;
279
11.2k
}
280
281
282
U32 XXH32(const void* input, int len, U32 seed)
283
11.2k
{
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
11.2k
    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
11.2k
    if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
303
11.2k
        return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);
304
18.4E
    else
305
18.4E
        return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned);
306
11.2k
#endif
307
11.2k
}
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
12.1k
{
336
12.1k
    struct XXH_state32_t * state = (struct XXH_state32_t *) state_in;
337
12.1k
    state->seed = seed;
338
12.1k
    state->v1 = seed + PRIME32_1 + PRIME32_2;
339
12.1k
    state->v2 = seed + PRIME32_2;
340
12.1k
    state->v3 = seed + 0;
341
12.1k
    state->v4 = seed - PRIME32_1;
342
12.1k
    state->total_len = 0;
343
12.1k
    state->memsize = 0;
344
12.1k
    return XXH_OK;
345
12.1k
}
346
347
348
void* XXH32_init (U32 seed)
349
12.1k
{
350
12.1k
    void* state = XXH_malloc (sizeof(struct XXH_state32_t));
351
12.1k
    XXH32_resetState(state, seed);
352
12.1k
    return state;
353
12.1k
}
354
355
356
FORCE_INLINE XXH_errorcode XXH32_update_endian (void* state_in, const void* input, int len, XXH_endianess endian)
357
24.3k
{
358
24.3k
    struct XXH_state32_t * state = (struct XXH_state32_t *) state_in;
359
24.3k
    const BYTE* p = (const BYTE*)input;
360
24.3k
    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
24.3k
    state->total_len += len;
367
368
24.3k
    if (state->memsize + len < 16)   // fill in tmp buffer
369
11.6k
    {
370
11.6k
        XXH_memcpy(state->memory + state->memsize, input, len);
371
11.6k
        state->memsize +=  len;
372
11.6k
        return XXH_OK;
373
11.6k
    }
374
375
12.6k
    if (state->memsize)   // some data left from previous update
376
473
    {
377
473
        XXH_memcpy(state->memory + state->memsize, input, 16-state->memsize);
378
473
        {
379
473
            const U32* p32 = (const U32*)state->memory;
380
473
            state->v1 += XXH_readLE32(p32, endian) * PRIME32_2; state->v1 = XXH_rotl32(state->v1, 13); state->v1 *= PRIME32_1; p32++;
381
473
            state->v2 += XXH_readLE32(p32, endian) * PRIME32_2; state->v2 = XXH_rotl32(state->v2, 13); state->v2 *= PRIME32_1; p32++;
382
473
            state->v3 += XXH_readLE32(p32, endian) * PRIME32_2; state->v3 = XXH_rotl32(state->v3, 13); state->v3 *= PRIME32_1; p32++;
383
473
            state->v4 += XXH_readLE32(p32, endian) * PRIME32_2; state->v4 = XXH_rotl32(state->v4, 13); state->v4 *= PRIME32_1; p32++;
384
473
        }
385
473
        p += 16-state->memsize;
386
473
        state->memsize = 0;
387
473
    }
388
389
12.6k
    if (p <= bEnd-16)
390
12.1k
    {
391
12.1k
        const BYTE* const limit = bEnd - 16;
392
12.1k
        U32 v1 = state->v1;
393
12.1k
        U32 v2 = state->v2;
394
12.1k
        U32 v3 = state->v3;
395
12.1k
        U32 v4 = state->v4;
396
397
12.1k
        do
398
879k
        {
399
879k
            v1 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v1 = XXH_rotl32(v1, 13); v1 *= PRIME32_1; p+=4;
400
879k
            v2 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v2 = XXH_rotl32(v2, 13); v2 *= PRIME32_1; p+=4;
401
879k
            v3 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v3 = XXH_rotl32(v3, 13); v3 *= PRIME32_1; p+=4;
402
879k
            v4 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v4 = XXH_rotl32(v4, 13); v4 *= PRIME32_1; p+=4;
403
879k
        } while (p<=limit);
404
405
12.1k
        state->v1 = v1;
406
12.1k
        state->v2 = v2;
407
12.1k
        state->v3 = v3;
408
12.1k
        state->v4 = v4;
409
12.1k
    }
410
411
12.6k
    if (p < bEnd)
412
10.5k
    {
413
10.5k
        XXH_memcpy(state->memory, p, bEnd-p);
414
10.5k
        state->memsize = (int)(bEnd-p);
415
10.5k
    }
416
417
12.6k
    return XXH_OK;
418
12.6k
}
419
420
XXH_errorcode XXH32_update (void* state_in, const void* input, int len)
421
24.3k
{
422
24.3k
    XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
423
424
24.3k
    if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
425
24.3k
        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
24.3k
}
429
430
431
432
FORCE_INLINE U32 XXH32_intermediateDigest_endian (void* state_in, XXH_endianess endian)
433
12.1k
{
434
12.1k
    struct XXH_state32_t * state = (struct XXH_state32_t *) state_in;
435
12.1k
    const BYTE * p = (const BYTE*)state->memory;
436
12.1k
    BYTE* bEnd = (BYTE*)state->memory + state->memsize;
437
12.1k
    U32 h32;
438
439
12.1k
    if (state->total_len >= 16)
440
12.1k
    {
441
12.1k
        h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18);
442
12.1k
    }
443
0
    else
444
0
    {
445
0
        h32  = state->seed + PRIME32_5;
446
0
    }
447
448
12.1k
    h32 += (U32) state->total_len;
449
450
26.3k
    while (p<=bEnd-4)
451
14.1k
    {
452
14.1k
        h32 += XXH_readLE32((const U32*)p, endian) * PRIME32_3;
453
14.1k
        h32  = XXH_rotl32(h32, 17) * PRIME32_4;
454
14.1k
        p+=4;
455
14.1k
    }
456
457
29.2k
    while (p<bEnd)
458
17.1k
    {
459
17.1k
        h32 += (*p) * PRIME32_5;
460
17.1k
        h32 = XXH_rotl32(h32, 11) * PRIME32_1;
461
17.1k
        p++;
462
17.1k
    }
463
464
12.1k
    h32 ^= h32 >> 15;
465
12.1k
    h32 *= PRIME32_2;
466
12.1k
    h32 ^= h32 >> 13;
467
12.1k
    h32 *= PRIME32_3;
468
12.1k
    h32 ^= h32 >> 16;
469
470
12.1k
    return h32;
471
12.1k
}
472
473
474
U32 XXH32_intermediateDigest (void* state_in)
475
12.1k
{
476
12.1k
    XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
477
478
12.1k
    if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
479
12.1k
        return XXH32_intermediateDigest_endian(state_in, XXH_littleEndian);
480
0
    else
481
0
        return XXH32_intermediateDigest_endian(state_in, XXH_bigEndian);
482
12.1k
}
483
484
485
U32 XXH32_digest (void* state_in)
486
12.1k
{
487
12.1k
    U32 h32 = XXH32_intermediateDigest(state_in);
488
489
12.1k
    XXH_free(state_in);
490
491
12.1k
    return h32;
492
12.1k
}
493
494
}  // namespace rocksdb