Branch data Line data Source code
1 : : /* 2 : : * This file is part of libplacebo. 3 : : * 4 : : * libplacebo is free software; you can redistribute it and/or 5 : : * modify it under the terms of the GNU Lesser General Public 6 : : * License as published by the Free Software Foundation; either 7 : : * version 2.1 of the License, or (at your option) any later version. 8 : : * 9 : : * libplacebo is distributed in the hope that it will be useful, 10 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 : : * GNU Lesser General Public License for more details. 13 : : * 14 : : * You should have received a copy of the GNU Lesser General Public 15 : : * License along with libplacebo. If not, see <http://www.gnu.org/licenses/>. 16 : : */ 17 : : 18 : : #pragma once 19 : : 20 : : #include "common.h" 21 : : 22 : : #define GOLDEN_RATIO_64 UINT64_C(0x9e3779b97f4a7c15) 23 : : 24 : : static inline void pl_hash_merge(uint64_t *accum, uint64_t hash) { 25 [ + + + + ]: 7486 : *accum ^= hash + GOLDEN_RATIO_64 + (*accum << 6) + (*accum >> 2); 26 : 624 : } 27 : : 28 : : static inline uint64_t pl_mem_hash(const void *mem, size_t size); 29 : : #define pl_var_hash(x) pl_mem_hash(&(x), sizeof(x)) 30 : : 31 : : static inline uint64_t pl_str_hash(pl_str str) 32 : : { 33 : : return pl_mem_hash(str.buf, str.len); 34 : : } 35 : : 36 : 37 : static inline uint64_t pl_str0_hash(const char *str) 37 : : { 38 [ + - ]: 37 : return pl_mem_hash(str, str ? strlen(str) : 0); 39 : : } 40 : : 41 : : #ifdef PL_HAVE_XXHASH 42 : : 43 : : #define XXH_NAMESPACE pl_ 44 : : #define XXH_INLINE_ALL 45 : : #define XXH_NO_STREAM 46 : : #if defined(__GNUC__) && !defined(__clang__) 47 : : # pragma GCC diagnostic push 48 : : # pragma GCC diagnostic ignored "-Warray-bounds=" 49 : : #endif 50 : : #include <xxhash.h> 51 : : #if defined(__GNUC__) && !defined(__clang__) 52 : : # pragma GCC diagnostic pop 53 : : #endif 54 : : 55 : : XXH_FORCE_INLINE uint64_t pl_mem_hash(const void *mem, size_t size) 56 : : { 57 [ + + ]: 5126 : return XXH3_64bits(mem, size); 58 : : } 59 : : 60 : : #else // !PL_HAVE_XXHASH 61 : : 62 : : /* 63 : : SipHash reference C implementation 64 : : Modified for use by libplacebo: 65 : : - Hard-coded a fixed key (k0 and k1) 66 : : - Hard-coded the output size to 64 bits 67 : : - Return the result vector directly 68 : : 69 : : Copyright (c) 2012-2016 Jean-Philippe Aumasson 70 : : <jeanphilippe.aumasson@gmail.com> 71 : : Copyright (c) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to> 72 : : 73 : : To the extent possible under law, the author(s) have dedicated all copyright 74 : : and related and neighboring rights to this software to the public domain 75 : : worldwide. This software is distributed without any warranty. 76 : : 77 : : <http://creativecommons.org/publicdomain/zero/1.0/>. 78 : : */ 79 : : 80 : : /* default: SipHash-2-4 */ 81 : : #define cROUNDS 2 82 : : #define dROUNDS 4 83 : : 84 : : #define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b)))) 85 : : 86 : : #define U8TO64_LE(p) \ 87 : : (((uint64_t)((p)[0])) | ((uint64_t)((p)[1]) << 8) | \ 88 : : ((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) | \ 89 : : ((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) | \ 90 : : ((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56)) 91 : : 92 : : #define SIPROUND \ 93 : : do { \ 94 : : v0 += v1; \ 95 : : v1 = ROTL(v1, 13); \ 96 : : v1 ^= v0; \ 97 : : v0 = ROTL(v0, 32); \ 98 : : v2 += v3; \ 99 : : v3 = ROTL(v3, 16); \ 100 : : v3 ^= v2; \ 101 : : v0 += v3; \ 102 : : v3 = ROTL(v3, 21); \ 103 : : v3 ^= v0; \ 104 : : v2 += v1; \ 105 : : v1 = ROTL(v1, 17); \ 106 : : v1 ^= v2; \ 107 : : v2 = ROTL(v2, 32); \ 108 : : } while (0) 109 : : 110 : : static inline uint64_t pl_mem_hash(const void *mem, size_t size) 111 : : { 112 : : if (!size) 113 : : return 0x8533321381b8254bULL; 114 : : 115 : : uint64_t v0 = 0x736f6d6570736575ULL; 116 : : uint64_t v1 = 0x646f72616e646f6dULL; 117 : : uint64_t v2 = 0x6c7967656e657261ULL; 118 : : uint64_t v3 = 0x7465646279746573ULL; 119 : : uint64_t k0 = 0xfe9f075098ddb0faULL; 120 : : uint64_t k1 = 0x68f7f03510e5285cULL; 121 : : uint64_t m; 122 : : int i; 123 : : const uint8_t *buf = mem; 124 : : const uint8_t *end = buf + size - (size % sizeof(uint64_t)); 125 : : const int left = size & 7; 126 : : uint64_t b = ((uint64_t) size) << 56; 127 : : v3 ^= k1; 128 : : v2 ^= k0; 129 : : v1 ^= k1; 130 : : v0 ^= k0; 131 : : 132 : : for (; buf != end; buf += 8) { 133 : : m = U8TO64_LE(buf); 134 : : v3 ^= m; 135 : : 136 : : for (i = 0; i < cROUNDS; ++i) 137 : : SIPROUND; 138 : : 139 : : v0 ^= m; 140 : : } 141 : : 142 : : switch (left) { 143 : : case 7: b |= ((uint64_t) buf[6]) << 48; // fall through 144 : : case 6: b |= ((uint64_t) buf[5]) << 40; // fall through 145 : : case 5: b |= ((uint64_t) buf[4]) << 32; // fall through 146 : : case 4: b |= ((uint64_t) buf[3]) << 24; // fall through 147 : : case 3: b |= ((uint64_t) buf[2]) << 16; // fall through 148 : : case 2: b |= ((uint64_t) buf[1]) << 8; // fall through 149 : : case 1: b |= ((uint64_t) buf[0]); break; 150 : : case 0: break; 151 : : } 152 : : 153 : : v3 ^= b; 154 : : 155 : : for (i = 0; i < cROUNDS; ++i) 156 : : SIPROUND; 157 : : 158 : : v0 ^= b; 159 : : 160 : : v2 ^= 0xff; 161 : : 162 : : for (i = 0; i < dROUNDS; ++i) 163 : : SIPROUND; 164 : : 165 : : b = v0 ^ v1 ^ v2 ^ v3; 166 : : return b; 167 : : } 168 : : 169 : : #endif // PL_HAVE_XXHASH