LCOV - code coverage report
Current view: top level - src - hash.h (source / functions) Hit Total Coverage
Test: Code coverage Lines: 5 5 100.0 %
Date: 2025-03-29 09:04:10 Functions: 1 1 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 7 8 87.5 %

           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

Generated by: LCOV version 1.16