Skip to content

Commit da81ee5

Browse files
build OPTIMIZE use xxhash instead of jenkins one-at-a-time hash, if available (#2365)
* use xxhash instead of jenkins hash In several benchmarks, xxhash scores far better than the jenkins one at a time hash function. See https://xxhash.com/ for a comparison. * make xxhash dependency optional
1 parent f827745 commit da81ee5

File tree

9 files changed

+95
-10
lines changed

9 files changed

+95
-10
lines changed

.github/workflows/ci.yml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525
options: "-DENABLE_TESTS=ON",
2626
packager: "sudo apt-get",
2727
# no expect because stdout seems to be redirected
28-
packages: "libcmocka-dev shunit2",
28+
packages: "libcmocka-dev libxxhash-dev shunit2",
2929
snaps: "",
3030
build-cmd: "make"
3131
}
@@ -36,7 +36,7 @@ jobs:
3636
cc: "clang",
3737
options: "-DENABLE_TESTS=ON",
3838
packager: "sudo apt-get",
39-
packages: "libcmocka-dev shunit2",
39+
packages: "libcmocka-dev libxxhash-dev shunit2",
4040
snaps: "",
4141
build-cmd: "make"
4242
}
@@ -47,7 +47,7 @@ jobs:
4747
cc: "gcc",
4848
options: "",
4949
packager: "sudo apt-get",
50-
packages: "libcmocka-dev valgrind shunit2",
50+
packages: "libcmocka-dev libxxhash-dev valgrind shunit2",
5151
snaps: "",
5252
build-cmd: "make"
5353
}
@@ -59,7 +59,7 @@ jobs:
5959
options: "",
6060
packager: "sudo apt-get",
6161
# no valgrind because it does not support DWARF5 yet generated by clang 14
62-
packages: "libcmocka-dev shunit2",
62+
packages: "libcmocka-dev libxxhash-dev shunit2",
6363
snaps: "",
6464
build-cmd: "make"
6565
}
@@ -70,7 +70,7 @@ jobs:
7070
cc: "clang",
7171
options: "-DENABLE_TESTS=ON -DPATH_EXPECT=",
7272
packager: "brew",
73-
packages: "cmocka shunit2 tcl-tk",
73+
packages: "cmocka xxhash shunit2 tcl-tk",
7474
snaps: "",
7575
build-cmd: "make"
7676
}
@@ -81,7 +81,7 @@ jobs:
8181
cc: "clang",
8282
options: "-DCMAKE_C_FLAGS=-fsanitize=address,undefined -DENABLE_TESTS=ON -DENABLE_VALGRIND_TESTS=OFF",
8383
packager: "sudo apt-get",
84-
packages: "libcmocka-dev",
84+
packages: "libcmocka-dev libxxhash-dev",
8585
snaps: "",
8686
build-cmd: "make"
8787
}
@@ -92,7 +92,7 @@ jobs:
9292
cc: "gcc",
9393
options: "",
9494
packager: "sudo apt-get",
95-
packages: "libcmocka-dev abi-dumper abi-compliance-checker",
95+
packages: "libcmocka-dev libxxhash-dev abi-dumper abi-compliance-checker",
9696
snaps: "core universal-ctags",
9797
build-cmd: "make abi-check"
9898
}
@@ -103,7 +103,7 @@ jobs:
103103
cc: "gcc",
104104
options: "",
105105
packager: "sudo apt-get",
106-
packages: "cmake debhelper libcmocka-dev python3-pip",
106+
packages: "cmake debhelper libcmocka-dev libxxhash-dev python3-pip",
107107
snaps: "",
108108
build-cmd: ""
109109
}
@@ -210,7 +210,7 @@ jobs:
210210
uses: SimenB/github-actions-cpu-cores@v1
211211

212212
- name: Install Windows dependencies
213-
run: vcpkg install --triplet=${{ matrix.triplet }} pcre2 pthreads dirent dlfcn-win32 cmocka getopt
213+
run: vcpkg install --triplet=${{ matrix.triplet }} pcre2 pthreads dirent dlfcn-win32 cmocka getopt xxhash
214214

215215
- name: Configure
216216
shell: bash

.github/workflows/devel-push.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ jobs:
3434
cc: "gcc",
3535
options: "-DENABLE_COVERAGE=ON",
3636
packager: "sudo apt-get",
37-
packages: "libcmocka-dev lcov",
37+
packages: "libcmocka-dev libxxhash-dev lcov",
3838
snaps: "",
3939
make-prepend: "",
4040
make-target: ""

CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ else()
242242
option(ENABLE_TESTS "Build tests" OFF)
243243
option(ENABLE_VALGRIND_TESTS "Build tests with valgrind" OFF)
244244
endif()
245+
option(USE_XXHASH "Use xxhash if available" ON)
245246
option(ENABLE_PERF_TESTS "Build performance tests" OFF)
246247
option(ENABLE_COVERAGE "Build code coverage report from tests" OFF)
247248
option(ENABLE_FUZZ_TARGETS "Build target programs suitable for fuzzing with AFL" OFF)
@@ -411,6 +412,16 @@ find_package(PCRE2 10.21 REQUIRED)
411412
include_directories(${PCRE2_INCLUDE_DIRS})
412413
target_link_libraries(yang ${PCRE2_LIBRARIES})
413414

415+
# XXHash include and library
416+
find_package(XXHash)
417+
if (XXHASH_FOUND AND USE_XXHASH)
418+
add_definitions(-DUSE_XXHASH)
419+
include_directories(${XXHASH_INCLUDE_DIR})
420+
target_link_libraries(yang ${XXHASH_LIBRARY})
421+
else()
422+
set (USE_XXHASH OFF)
423+
endif()
424+
414425
# generated header list
415426
foreach(h IN LISTS gen_headers)
416427
list(APPEND g_headers ${PROJECT_BINARY_DIR}/libyang/${h})

CMakeModules/FindXXHash.cmake

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Try to find XXHash
2+
# Once done this will define
3+
#
4+
# Read-Only variables:
5+
# XXHASH_FOUND - system has XXHash
6+
# XXHASH_INCLUDE_DIR - the XXHash include directory
7+
# XXHASH_LIBRARY - Link these to use XXHash
8+
9+
find_path(XXHASH_INCLUDE_DIR
10+
NAMES
11+
xxhash.h
12+
PATHS
13+
/usr/include
14+
/usr/local/include
15+
/opt/local/include
16+
/sw/include
17+
${CMAKE_INCLUDE_PATH}
18+
${CMAKE_INSTALL_PREFIX}/include
19+
)
20+
21+
find_library(XXHASH_LIBRARY
22+
NAMES
23+
xxhash
24+
libxxhash
25+
PATHS
26+
PATHS
27+
/usr/lib
28+
/usr/lib64
29+
/usr/local/lib
30+
/usr/local/lib64
31+
/opt/local/lib
32+
/sw/lib
33+
${CMAKE_LIBRARY_PATH}
34+
${CMAKE_INSTALL_PREFIX}/lib
35+
)
36+
37+
include(FindPackageHandleStandardArgs)
38+
find_package_handle_standard_args(XXHash FOUND_VAR XXHASH_FOUND REQUIRED_VARS XXHASH_INCLUDE_DIR XXHASH_LIBRARY)

src/hash_table.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,27 @@
2626
#include "log.h"
2727
#include "ly_common.h"
2828

29+
#ifdef USE_XXHASH
30+
#include <xxhash.h>
31+
32+
LIBYANG_API_DEF uint32_t
33+
lyht_hash_multi(uint32_t hash, const char *key_part, size_t len)
34+
{
35+
if (key_part && len) {
36+
return XXH3_64bits_withSeed(key_part, len, hash);
37+
}
38+
39+
return XXH3_64bits_withSeed(NULL, 0, hash);
40+
}
41+
42+
LIBYANG_API_DEF uint32_t
43+
lyht_hash(const char *key, size_t len)
44+
{
45+
return XXH3_64bits(key, len);
46+
}
47+
48+
#else
49+
2950
LIBYANG_API_DEF uint32_t
3051
lyht_hash_multi(uint32_t hash, const char *key_part, size_t len)
3152
{
@@ -55,6 +76,8 @@ lyht_hash(const char *key, size_t len)
5576
return lyht_hash_multi(hash, NULL, len);
5677
}
5778

79+
#endif
80+
5881
static LY_ERR
5982
lyht_init_hlists_and_records(struct ly_ht *ht)
6083
{

src/hash_table.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ LIBYANG_API_DECL uint32_t lyht_hash_multi(uint32_t hash, const char *key_part, s
5454
*
5555
* Spooky hash is faster, but it works only for little endian architectures.
5656
*
57+
* Uses XXH3_64bits internally if xxhash is available. See https://xxhash.com
58+
*
5759
* @param[in] key Key to hash.
5860
* @param[in] len Length of @p key.
5961
* @return Hash of the key.

tests/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ function(ly_add_utest)
3030
endif()
3131
endif()
3232

33+
if (USE_XXHASH)
34+
target_link_libraries(${TEST_NAME} ${XXHASH_LIBRARY})
35+
endif()
3336
add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME})
3437
set_property(TEST ${TEST_NAME} APPEND PROPERTY ENVIRONMENT "MALLOC_CHECK_=3")
3538

tests/perf/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ set(format_sources
66
add_executable(ly_perf ${CMAKE_CURRENT_SOURCE_DIR}/perf.c $<TARGET_OBJECTS:yangobj>)
77
set_target_properties(ly_perf PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests")
88
target_link_libraries(ly_perf ${CMAKE_THREAD_LIBS_INIT} ${PCRE2_LIBRARIES} ${CMAKE_DL_LIBS})
9+
if (USE_XXHASH)
10+
target_link_libraries(ly_perf ${XXHASH_LIBRARY})
11+
endif()
12+
913
if (NOT WIN32)
1014
target_link_libraries(ly_perf m)
1115
endif()

tests/style/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,8 @@ endif()
99
add_executable(cpp_compat cpp_compat.c $<TARGET_OBJECTS:yangobj>)
1010
target_include_directories(cpp_compat BEFORE PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
1111
target_link_libraries(cpp_compat ${CMAKE_THREAD_LIBS_INIT} ${PCRE2_LIBRARIES} ${CMAKE_DL_LIBS} m)
12+
if (USE_XXHASH)
13+
target_link_libraries(cpp_compat ${XXHASH_LIBRARY})
14+
endif()
15+
1216
target_compile_options(cpp_compat PUBLIC "-Werror=c++-compat")

0 commit comments

Comments
 (0)