xref: /freebsd/sys/contrib/openzfs/tests/unit/test_cityhash.c (revision 22649d4dba730d46244fd2dff4fd174903c8379f)
1 // SPDX-License-Identifier: CDDL-1.0
2 /*
3  * This file and its contents are supplied under the terms of the
4  * Common Development and Distribution License ("CDDL"), version 1.0.
5  * You may only use this file in accordance with the terms of version
6  * 1.0 of the CDDL.
7  *
8  * A full copy of the text of the CDDL should have accompanied this
9  * source.  A copy of the CDDL is also available via the Internet at
10  * https://opensource.org/license/CDDL-1.0.
11  */
12 
13 /*
14  * Copyright (c) 2026, Christos Longros.
15  */
16 
17 #include <sys/types.h>
18 #include <cityhash.h>
19 
20 #include "unit.h"
21 
22 /* ========== */
23 
24 /*
25  * cityhash maps one to four uint64_t words to a single uint64_t hash.  The
26  * output is fixed by the algorithm, so we can verify exact results.
27  */
28 static MunitResult
test_cityhash_known(const MunitParameter params[],void * data)29 test_cityhash_known(const MunitParameter params[], void *data)
30 {
31 	(void) params, (void) data;
32 
33 	unit_eq(cityhash1(0), 0x7087061603e53293ULL);
34 	unit_eq(cityhash1(0x0123456789abcdefULL), 0x4d72820d4fcae8ffULL);
35 	unit_eq(cityhash2(1, 2), 0x8f1c7927f8b5dff2ULL);
36 	unit_eq(cityhash3(1, 2, 3), 0x4f6fe08120ecb540ULL);
37 	unit_eq(cityhash4(0x1111111111111111ULL, 0x2222222222222222ULL,
38 	    0x3333333333333333ULL, 0x4444444444444444ULL),
39 	    0xa6370a2070fdfd12ULL);
40 
41 	return (MUNIT_OK);
42 }
43 
44 /*
45  * cityhash1/2/3 are specialized versions of cityhash4, so each must match
46  * cityhash4 on the same arguments.  cityhash1 passes its word as the 2nd
47  * argument.
48  */
49 static MunitResult
test_cityhash_specialized(const MunitParameter params[],void * data)50 test_cityhash_specialized(const MunitParameter params[], void *data)
51 {
52 	(void) params, (void) data;
53 
54 	uint64_t a = 0xdeadbeefULL, b = 0xfeedfaceULL, c = 0x00c0ffeeULL;
55 
56 	unit_eq(cityhash1(a), cityhash4(0, a, 0, 0));
57 	unit_eq(cityhash2(a, b), cityhash4(a, b, 0, 0));
58 	unit_eq(cityhash3(a, b, c), cityhash4(a, b, c, 0));
59 
60 	return (MUNIT_OK);
61 }
62 
63 /* Different arguments produce different hash results. */
64 static MunitResult
test_cityhash_distinct(const MunitParameter params[],void * data)65 test_cityhash_distinct(const MunitParameter params[], void *data)
66 {
67 	(void) params, (void) data;
68 
69 	uint64_t base = cityhash4(1, 2, 3, 4);
70 	unit_ne(base, cityhash4(9, 2, 3, 4));	/* first word */
71 	unit_ne(base, cityhash4(1, 9, 3, 4));	/* second word */
72 	unit_ne(base, cityhash4(1, 2, 9, 4));	/* third word */
73 	unit_ne(base, cityhash4(1, 2, 3, 9));	/* fourth word */
74 	unit_ne(cityhash1(0), cityhash1(1));
75 
76 	return (MUNIT_OK);
77 }
78 
79 /* ========== */
80 
81 static const MunitTest cityhash_tests[] = {
82 	UNIT_TEST("known",		test_cityhash_known),
83 	UNIT_TEST("specialized",	test_cityhash_specialized),
84 	UNIT_TEST("distinct",		test_cityhash_distinct),
85 	{ 0 },
86 };
87 
88 static const MunitSuite cityhash_test_suite = {
89 	"cityhash.",
90 	cityhash_tests,
91 	NULL,
92 	1,
93 	MUNIT_SUITE_OPTION_NONE,
94 };
95 
96 int
main(int argc,char ** argv)97 main(int argc, char **argv)
98 {
99 	return (munit_suite_main(&cityhash_test_suite, NULL, argc, argv));
100 }
101