GCC Code Coverage Report


Directory: ./
File: hash_key.c
Date: 2025-12-31 16:19:05
Exec Total Coverage
Lines: 51 51 100.0%
Functions: 4 4 100.0%
Branches: 14 14 100.0%

Line Branch Exec Source
1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 *
4 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include "cx/hash_key.h"
30 #include "cx/compare.h"
31 #include <string.h>
32
33 1439 void cx_hash_murmur(CxHashKey *key) {
34 1439 const unsigned char *data = key->data;
35
2/2
✓ Branch 0 (2→3) taken 4 times.
✓ Branch 1 (2→4) taken 1435 times.
1439 if (data == NULL) {
36 // extension: special value for NULL
37 4 key->hash = 1574210520u;
38 4 return;
39 }
40 1435 size_t len = key->len;
41
42 1435 unsigned m = 0x5bd1e995;
43 1435 unsigned r = 24;
44 1435 unsigned h = 25 ^ (unsigned) len;
45 1435 unsigned i = 0;
46
2/2
✓ Branch 0 (6→5) taken 1302 times.
✓ Branch 1 (6→7) taken 1435 times.
2737 while (len >= 4) {
47 1302 unsigned k = data[i + 0] & 0xFF;
48 1302 k |= (data[i + 1] & 0xFF) << 8;
49 1302 k |= (data[i + 2] & 0xFF) << 16;
50 1302 k |= (data[i + 3] & 0xFF) << 24;
51
52 1302 k *= m;
53 1302 k ^= k >> r;
54 1302 k *= m;
55
56 1302 h *= m;
57 1302 h ^= k;
58
59 1302 i += 4;
60 1302 len -= 4;
61 }
62
63
4/4
✓ Branch 0 (7→8) taken 438 times.
✓ Branch 1 (7→9) taken 464 times.
✓ Branch 2 (7→10) taken 417 times.
✓ Branch 3 (7→11) taken 116 times.
1435 switch (len) {
64 438 case 3:
65 438 h ^= (data[i + 2] & 0xFF) << 16;
66 CX_FALLTHROUGH;
67 902 case 2:
68 902 h ^= (data[i + 1] & 0xFF) << 8;
69 CX_FALLTHROUGH;
70 1319 case 1:
71 1319 h ^= (data[i + 0] & 0xFF);
72 1319 h *= m;
73 CX_FALLTHROUGH;
74 1435 default: // do nothing
75 ;
76 }
77
78 1435 h ^= h >> 13;
79 1435 h *= m;
80 1435 h ^= h >> 15;
81
82 1435 key->hash = h;
83 }
84
85 1407 CxHashKey cx_hash_key(
86 const void *obj,
87 size_t len
88 ) {
89 CxHashKey key;
90 1407 key.data = obj;
91 1407 key.len = len;
92 1407 cx_hash_murmur(&key);
93 1407 return key;
94 }
95
96 3394 int cx_hash_key_cmp(const void *l, const void *r) {
97 3394 const CxHashKey *left = l;
98 3394 const CxHashKey *right = r;
99 int d;
100 3394 d = cx_vcmp_uint64(left->hash, right->hash);
101
2/2
✓ Branch 0 (3→4) taken 2658 times.
✓ Branch 1 (3→5) taken 736 times.
3394 if (d != 0) return d;
102 736 d = cx_vcmp_size(left->len, right->len);
103
2/2
✓ Branch 0 (6→7) taken 1 times.
✓ Branch 1 (6→8) taken 735 times.
736 if (d != 0) return d;
104
2/2
✓ Branch 0 (8→9) taken 2 times.
✓ Branch 1 (8→10) taken 733 times.
735 if (left->len == 0) return 0;
105 733 return memcmp(left->data, right->data, left->len);
106 }
107
108 509 cxstring cx_hash_key_as_string(const CxHashKey *key) {
109 1018 return cx_strn(key->data, key->len);
110 }
111