GCC Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 51 / 0 / 51
Functions: 100.0% 4 / 0 / 4
Branches: 100.0% 14 / 0 / 14

hash_key.c
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 2 → 3 taken 4 times.
✓ Branch 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 6 → 5 taken 1302 times.
✓ Branch 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 7 → 8 taken 438 times.
✓ Branch 7 → 9 taken 464 times.
✓ Branch 7 → 10 taken 417 times.
✓ Branch 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 3 → 4 taken 2658 times.
✓ Branch 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 6 → 7 taken 1 time.
✓ Branch 6 → 8 taken 735 times.
736 if (d != 0) return d;
104
2/2
✓ Branch 8 → 9 taken 2 times.
✓ Branch 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