Skip to content

Commit

Permalink
Added installation instructions
Browse files Browse the repository at this point in the history
  • Loading branch information
Kardbord committed Jul 19, 2022
1 parent 9c28a53 commit ad4f309
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 55 deletions.
130 changes: 82 additions & 48 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
# ------------------------------ Setup ------------------------------- #
cmake_minimum_required(VERSION 3.16.3)
project(concurrency)
project(concurrency VERSION 0.0.1
DESCRIPTION "Sharded, thread-safe implementations of STL containers."
HOMEPAGE_URL "https://github.com/TannerKvarfordt/Concurrency")

set(CMAKE_CXX_STANDARD 17)
option(CodeCoverage "CodeCoverage" OFF)
option(INSTALL "Set up to install the library headers on the system. The target path for installation can be set by setting the CMAKE_INSTALL_PREFIX variable." OFF)
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/modules/)

if(NOT CMAKE_BUILD_TYPE)
Expand All @@ -29,55 +33,85 @@ else()
endif()

# ----------------------------- Library ------------------------------ #
add_library(${CMAKE_PROJECT_NAME} INTERFACE)
set(header_files
include/concurrency/UnorderedMap.hpp
include/concurrency/ShardedUnorderedMap.hpp)
target_sources(${CMAKE_PROJECT_NAME} INTERFACE ${header_files})
target_include_directories(${CMAKE_PROJECT_NAME} INTERFACE include/)


# -------------------------- Build Examples -------------------------- #
set("SIMPLE_EXAMPLE_SRC"
examples/simple/main.cpp
)
add_executable(${CMAKE_PROJECT_NAME}_simple_example ${SIMPLE_EXAMPLE_SRC})
target_link_libraries(${CMAKE_PROJECT_NAME}_simple_example PRIVATE ${CMAKE_PROJECT_NAME})
if(INSTALL MATCHES ON)
include(GNUInstallDirs)
add_library(${CMAKE_PROJECT_NAME} INTERFACE)
target_include_directories(${CMAKE_PROJECT_NAME} INTERFACE $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
target_compile_features(${CMAKE_PROJECT_NAME} INTERFACE cxx_std_17)

target_sources(${CMAKE_PROJECT_NAME}
INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/concurrency/UnorderedMap.hpp>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/concurrency/ShardedUnorderedMap.hpp>
$<INSTALL_INTERFACE:include/concurrency/UnorderedMap.hpp>
$<INSTALL_INTERFACE:include/concurrency/ShardedUnorderedMap.hpp>)

install(TARGETS ${CMAKE_PROJECT_NAME}
EXPORT ${PROJECT_NAME}_Targets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})

include(CMakePackageConfigHelpers)
write_basic_package_version_file("concurrencyConfigVersion.cmake" VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion)
configure_package_config_file(
"${PROJECT_SOURCE_DIR}/cmake/concurrencyConfig.cmake.in"
"${PROJECT_BINARY_DIR}/concurrencyConfig.cmake"
INSTALL_DESTINATION
${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake)

install(EXPORT ${PROJECT_NAME}_Targets
FILE ${PROJECT_NAME}Targets.cmake
NAMESPACE ${PROJECT_NAME}::
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake)

install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake)

install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/${PROJECT_NAME} DESTINATION include)
else()
include_directories(include)
# -------------------------- Build Examples -------------------------- #
set("SIMPLE_EXAMPLE_SRC"
examples/simple/main.cpp
)
add_executable(${CMAKE_PROJECT_NAME}_simple_example ${SIMPLE_EXAMPLE_SRC})

set("MAP_BENCHMARK_SRC"
examples/map_benchmark/main.cpp
examples/map_benchmark/Benchmark.cpp
)
find_package(Threads REQUIRED)
add_executable(${CMAKE_PROJECT_NAME}_map_benchmark ${MAP_BENCHMARK_SRC})
target_include_directories(${CMAKE_PROJECT_NAME}_map_benchmark PRIVATE benchmark examples/map_benchmark)
target_link_libraries(${CMAKE_PROJECT_NAME}_map_benchmark PRIVATE Threads::Threads)
target_link_libraries(${CMAKE_PROJECT_NAME}_map_benchmark PRIVATE ${CMAKE_PROJECT_NAME})
set("MAP_BENCHMARK_SRC"
examples/map_benchmark/main.cpp
examples/map_benchmark/Benchmark.cpp
)
find_package(Threads REQUIRED)
add_executable(${CMAKE_PROJECT_NAME}_map_benchmark ${MAP_BENCHMARK_SRC})
target_include_directories(${CMAKE_PROJECT_NAME}_map_benchmark PRIVATE benchmark examples/map_benchmark)
target_link_libraries(${CMAKE_PROJECT_NAME}_map_benchmark PRIVATE Threads::Threads)

# --------------------------- Build Tests ---------------------------- #
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip
)
IF (WIN32)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
ENDIF()
FetchContent_MakeAvailable(googletest)
set("TEST_SRC"
tests/UnorderedConcurrentMapTests.cpp
)
enable_testing()
add_executable(${CMAKE_PROJECT_NAME}_test ${TEST_SRC})
target_link_libraries(${CMAKE_PROJECT_NAME}_test PRIVATE gtest_main)
target_link_libraries(${CMAKE_PROJECT_NAME}_test PRIVATE ${CMAKE_PROJECT_NAME})
include(GoogleTest)
gtest_discover_tests(${CMAKE_PROJECT_NAME}_test)
# --------------------------- Build Tests ---------------------------- #
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip
)
IF (WIN32)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
ENDIF()
FetchContent_MakeAvailable(googletest)
set("TEST_SRC"
tests/UnorderedConcurrentMapTests.cpp
)
enable_testing()
add_executable(${CMAKE_PROJECT_NAME}_test ${TEST_SRC})
target_link_libraries(${CMAKE_PROJECT_NAME}_test PRIVATE gtest_main)
include(GoogleTest)
gtest_discover_tests(${CMAKE_PROJECT_NAME}_test)

# -------------------------- Code Coverage --------------------------- #
if (CMAKE_BUILD_TYPE MATCHES Debug)
if (CodeCoverage MATCHES ON)
include(CodeCoverage)
setup_target_for_coverage(${PROJECT_NAME}_coverage ${CMAKE_PROJECT_NAME}_test coverage --gtest_output=xml:coverage.junit.xml)
# -------------------------- Code Coverage --------------------------- #
if (CMAKE_BUILD_TYPE MATCHES Debug)
if (CodeCoverage MATCHES ON)
include(CodeCoverage)
setup_target_for_coverage(${PROJECT_NAME}_coverage ${CMAKE_PROJECT_NAME}_test coverage --gtest_output=xml:coverage.junit.xml)
endif()
endif()
endif()

22 changes: 15 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,26 @@ This project provides thread-safe wrappers around C++ standard library container
some exceptions have to be made to remove footguns in the context of concurrent access. Notably, iterator access is not supported for most
wrappers.

## [`std::unordered_map`](https://en.cppreference.com/w/cpp/container/unordered_map)
## Installation

The following wrappers around `std::unordered_map` are provided.
**NOTE** - This library requires C++17.

### [`::concurrency::UnorderedMap`](include/concurrency/UnorderedMap.hpp)
This is a header-only library. There are several ways to make use of the provided headers.

`::concurrency::UnorderedMap` is a simple wrapper around `std::unordered_map` which
allows thread-safe access via an internal [`std::shared_mutex`](https://en.cppreference.com/w/cpp/thread/shared_mutex).
- [`./tools/install.sh`](./tools/install.sh). Invoke this script, optionally providing an installation directory with the `-p` option.
- Alternatively, simply copy the contents of `include/` to your system.

Either way, you'll have to make sure that the location of the headers is known your build environment. At that point, you
can include the headers as you would any others.

## Container Wrappers

### [`::concurrency::ShardedUnorderedMap`](include/concurrency/ShardedUnorderedMap.hpp)
### [`std::unordered_map`](https://en.cppreference.com/w/cpp/container/unordered_map)

[`::concurrency::UnorderedMap`](include/concurrency/UnorderedMap.hpp) is a simple wrapper around `std::unordered_map` which
allows thread-safe access via an internal [`std::shared_mutex`](https://en.cppreference.com/w/cpp/thread/shared_mutex).

`::concurrency::ShardedUnorderedMap` provides the same interfaces as `::concurrency::UnorderedMap`, but employs sharding in an effort to improve
[`::concurrency::ShardedUnorderedMap`](include/concurrency/ShardedUnorderedMap.hpp) provides the same interfaces as `::concurrency::UnorderedMap`, but employs sharding in an effort to improve
write-access performance. By splitting the underlying data into multiple `::concurrency::UnorderedMap`s, multiple
threads may obtain write access at once, provided the respective keys they are accessing are stored in different
shards. See the [map_benchmark example](examples/map_benchmark/) for performance metrics.
4 changes: 4 additions & 0 deletions cmake/concurrencyConfig.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@PACKAGE_INIT@

include("${CMAKE_CURRENT_LIST_DIR}/@[email protected]")
check_required_components("@PROJECT_NAME@")
44 changes: 44 additions & 0 deletions tools/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/usr/bin/env bash
set -e

function usage() {
echo "${0}"
echo
echo "Usage"
echo " ${0} [-h] [-p]"
echo
echo "Options"
echo " -h Prints this usage"
echo " -p INSTALL_PREFIX Sets the target path for installation. If unspecified, uses the system default."
}

INSTALL_PREFIX=""
while getopts ":hp:" opt; do
case "${opt}" in
p)
INSTALL_PREFIX="${OPTARG}"
;;
h)
usage
exit 0
;;
*)
usage
exit 1
;;
esac
done
shift $((OPTIND - 1))

if [[ -n "${INSTALL_PREFIX}" ]] && ! [[ -d "${INSTALL_PREFIX}" ]]; then
echo "No such directory: ${INSTALL_PREFIX}"
exit 1
fi

mkdir -p "$(dirname "${BASH_SOURCE[0]}")/../build"
pushd "$(dirname "${BASH_SOURCE[0]}")/../build" >/dev/null
rm -rf ./* # Start from clean slate
cmake .. "-DCMAKE_INSTALL_PREFIX:PATH=${INSTALL_PREFIX}" -DINSTALL=ON
cmake --build . --config Release --target install -- -j "$(nproc)"
rm -rf ./* # Clean up build files
popd >/dev/null

0 comments on commit ad4f309

Please sign in to comment.