├── .clang-format ├── .gitattributes ├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── LICENCE ├── README.md ├── apps ├── daqdb-top │ ├── CMakeLists.txt │ ├── README.md │ ├── configs │ │ ├── client.cfg │ │ └── server.cfg │ ├── consumer.cpp │ ├── producer.cpp │ └── utils.hpp ├── minidaq │ ├── CMakeLists.txt │ ├── MinidaqAroNode.cpp │ ├── MinidaqAroNode.h │ ├── MinidaqFfNode.cpp │ ├── MinidaqFfNode.h │ ├── MinidaqFfNodeSeq.cpp │ ├── MinidaqFfNodeSeq.h │ ├── MinidaqNode.cpp │ ├── MinidaqNode.h │ ├── MinidaqRoNode.cpp │ ├── MinidaqRoNode.h │ ├── MinidaqStats.cpp │ ├── MinidaqStats.h │ ├── MinidaqTimer.cpp │ ├── MinidaqTimer.h │ ├── MinidaqTimerHR.cpp │ ├── MinidaqTimerHR.h │ ├── minidaq.cfg.in │ └── minidaq.cpp └── mist │ ├── CMakeLists.txt │ ├── config.cpp │ ├── config.h │ ├── mist.cfg.in │ └── mist.cpp ├── cmake ├── BoostTestHelpers.cmake ├── CleanAll.cmake └── FindConfig++.cmake ├── daqdb.Doxyfile ├── doc ├── config │ └── config_4_15.txt ├── network_setup_guide.md └── user_guides.md ├── examples ├── basic │ ├── .gitignore │ ├── CMakeLists.txt │ └── basic.cpp └── clinode │ ├── .gitignore │ ├── CMakeLists.txt │ ├── clinode.cfg.in │ ├── config.cpp │ ├── config.h │ ├── debug.h │ ├── node.cpp │ ├── nodeCli.cpp │ └── nodeCli.h ├── include ├── config │ └── KVStoreConfig.h └── daqdb │ ├── KVPair.h │ ├── KVStoreBase.h │ ├── Key.h │ ├── Options.h │ ├── Status.h │ ├── Types.h │ └── Value.h ├── lib ├── KVStoreBase.cpp ├── common │ ├── AllocStrategy.h │ ├── BlockingPoller.h │ ├── ClassAlloc.cpp │ ├── ClassAlloc.h │ ├── ClassMemoryAlloc.h │ ├── Configuration.cpp │ ├── DefaultAllocStrategy.cpp │ ├── DefaultAllocStrategy.h │ ├── GeneralPool.h │ ├── GeneralPoolBase.cpp │ ├── GeneralPoolBase.h │ ├── GeneralPoolBucket.cpp │ ├── GeneralPoolBucket.h │ ├── GeneralPoolBuffer.h │ ├── GlobalMemoryAlloc.h │ ├── Logger.cpp │ ├── Logger.h │ ├── MemMgr.cpp │ ├── MemMgr.h │ ├── Poller.h │ ├── PoolManager.cpp │ ├── PoolManager.h │ └── Rqst.h ├── core │ ├── KVStore.cpp │ └── KVStore.h ├── dht │ ├── DhtClient.cpp │ ├── DhtClient.h │ ├── DhtCore.cpp │ ├── DhtCore.h │ ├── DhtNode.cpp │ ├── DhtNode.h │ ├── DhtServer.cpp │ ├── DhtServer.h │ ├── DhtServerLoopback.cpp │ ├── DhtServerLoopback.h │ ├── DhtTypes.h │ ├── DhtUtils.cpp │ └── DhtUtils.h ├── offload │ ├── FinalizePoller.cpp │ ├── FinalizePoller.h │ ├── OffloadFreeList.cpp │ ├── OffloadFreeList.h │ ├── OffloadLbaAlloc.cpp │ ├── OffloadLbaAlloc.h │ ├── OffloadPoller.cpp │ ├── OffloadPoller.h │ ├── config-bdev.spdk │ ├── config-jbod.spdk │ └── config-raid0.spdk ├── pmem │ ├── ARTree.cpp │ ├── ARTree.h │ ├── PmemPoller.cpp │ ├── PmemPoller.h │ ├── RTree.cpp │ ├── RTree.h │ ├── RTreeEngine.cpp │ └── RTreeEngine.h ├── primary │ ├── PrimaryKeyBase.cpp │ ├── PrimaryKeyBase.h │ ├── PrimaryKeyEngine.cpp │ ├── PrimaryKeyEngine.h │ ├── PrimaryKeyNextQueue.cpp │ └── PrimaryKeyNextQueue.h ├── spdk │ ├── BdevStats.cpp │ ├── BdevStats.h │ ├── SpdkBdev.cpp │ ├── SpdkBdev.h │ ├── SpdkBdevFactory.cpp │ ├── SpdkBdevFactory.h │ ├── SpdkConf.cpp │ ├── SpdkConf.h │ ├── SpdkCore.cpp │ ├── SpdkCore.h │ ├── SpdkDevice.h │ ├── SpdkIoBuf.cpp │ ├── SpdkIoBuf.h │ ├── SpdkIoEngine.cpp │ ├── SpdkIoEngine.h │ ├── SpdkJBODBdev.cpp │ ├── SpdkJBODBdev.h │ ├── SpdkRAID0Bdev.cpp │ └── SpdkRAID0Bdev.h └── thin │ ├── KVStoreThin.cpp │ └── KVStoreThin.h ├── scripts ├── autogen_isal.sh ├── githooks │ ├── git-clang-format │ └── pre-commit ├── libspdk.mri ├── minidaq_run.sh ├── patch_spdk_isal.sh ├── pkgdep.sh ├── prepare_spdk_libs.sh └── setup_env_lcg.sh ├── tests ├── functional │ ├── CMakeLists.txt │ ├── base_operations.cpp │ ├── base_operations.h │ ├── config.cpp │ ├── config.h │ ├── debug.h │ ├── functests.cfg.in │ ├── main.cpp │ └── tests │ │ ├── tests.h │ │ ├── tests_base.cpp │ │ ├── tests_dht.cpp │ │ ├── tests_offload.cpp │ │ ├── tests_offload_ext.cpp │ │ └── tests_val_size.cpp ├── functional_thin │ ├── CMakeLists.txt │ ├── base_operations.cpp │ ├── base_operations.h │ ├── config.cpp │ ├── config.h │ ├── debug.h │ ├── functests_thin.cfg.in │ ├── functests_thin.sh │ ├── functests_thin_clinode.cfg.in │ ├── main.cpp │ └── tests │ │ ├── tests.h │ │ ├── tests_base.cpp │ │ ├── tests_multithreading.cpp │ │ └── tests_val_size.cpp └── unit │ ├── CMakeLists.txt │ ├── common │ └── main.cpp │ ├── dht │ ├── DhtClientTest.cpp │ ├── DhtCoreTest.cpp │ ├── DhtNodeTest.cpp │ └── DhtUtilsTest.cpp │ ├── mock │ ├── LICENSE │ └── fakeit.hpp │ ├── offload │ ├── OffloadFreeListTest.cpp │ └── OffloadPollerTest.cpp │ └── pmem │ └── PmemPollerTest.cpp └── third-party ├── CMakeLists.txt ├── erpc.cmake ├── libconfig.cmake ├── pmdk.cmake └── spdk.cmake /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: LLVM 2 | IndentWidth: 4 3 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # These files are text and should be normalized (Convert crlf => lf) 2 | *.txt text 3 | *.md text 4 | *.gitattributes text 5 | .gitignore text 6 | *.cpp text 7 | *.h text 8 | *.sh text 9 | *.in text 10 | *.ac text 11 | *.am text 12 | configure text 13 | scripts/githooks/pre-commit text 14 | scripts/githooks/git-clang-format text 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.a 3 | *.pyc 4 | *.csv 5 | .*.swp 6 | *.d 7 | .cproject 8 | .project 9 | .settings 10 | .pydevproject 11 | build 12 | bin 13 | config.log 14 | cmake_install.cmake 15 | project_protobuf-prefix 16 | CMakeCache.txt 17 | CMakeFiles 18 | CTestTestfile.cmake 19 | DartConfiguration.tcl 20 | Makefile 21 | Testing -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "third-party/spdk"] 2 | path = third-party/spdk 3 | url = https://github.com/spdk/spdk.git 4 | ignore = dirty 5 | [submodule "third-party/pmdk"] 6 | path = third-party/pmdk 7 | url = https://github.com/pmem/pmdk.git 8 | ignore = dirty 9 | [submodule "third-party/HdrHistogram_c"] 10 | path = third-party/HdrHistogram_c 11 | url = https://github.com/HdrHistogram/HdrHistogram_c.git 12 | ignore = dirty 13 | [submodule "third-party/libconfig"] 14 | path = third-party/libconfig 15 | url = https://github.com/hyperrealm/libconfig.git 16 | ignore = dirty 17 | [submodule "src/3rd/linenoise"] 18 | path = examples/clinode/linenoise 19 | url = https://github.com/antirez/linenoise.git 20 | ignore = dirty 21 | [submodule "third-party/libpmemobj-cpp"] 22 | path = third-party/libpmemobj-cpp 23 | url = https://github.com/pmem/libpmemobj-cpp.git 24 | ignore = dirty 25 | [submodule "third-party/eRPC"] 26 | path = third-party/eRPC 27 | url = https://github.com/anujkaliaiitd/eRPC.git 28 | ignore = dirty 29 | -------------------------------------------------------------------------------- /apps/daqdb-top/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | project(test_daqdb) 4 | 5 | include(FindPkgConfig) 6 | find_package(PkgConfig) 7 | 8 | set(CMAKE_CXX_STANDARD 14) 9 | 10 | set(ROOT_DAQDB_DIR ${PROJECT_SOURCE_DIR}/../..) 11 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${ROOT_DAQDB_DIR}/bin) 12 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${ROOT_DAQDB_DIR}/bin) 13 | 14 | find_package(Boost REQUIRED COMPONENTS program_options system filesystem) 15 | find_package(Threads REQUIRED) 16 | 17 | include_directories(${LIBCONFIG_INCLUDES_EXPORT}) 18 | 19 | file(GLOB PUT_SOURCES ${APPS}/daqdb-top/producer.cpp ${APPS}/daqdb-top/utils.hpp) 20 | file(GLOB GET_SOURCES ${APPS}/daqdb-top/consumer.cpp ${APPS}/daqdb-top/utils.hpp) 21 | 22 | add_executable(producer ${PUT_SOURCES}) 23 | set(Dpdk_LIBRARIES -Wl,--whole-archive dpdk -Wl,--no-whole-archive) 24 | target_link_libraries(producer ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} 25 | ${Dpdk_LIBRARIES} pmem daqdb linenoise pmemobj dl numa) 26 | 27 | add_executable(consumer ${GET_SOURCES}) 28 | set(Dpdk_LIBRARIES -Wl,--whole-archive dpdk -Wl,--no-whole-archive) 29 | target_link_libraries(consumer ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} 30 | ${Dpdk_LIBRARIES} pmem daqdb linenoise pmemobj dl numa) 31 | 32 | -------------------------------------------------------------------------------- /apps/daqdb-top/configs/client.cfg: -------------------------------------------------------------------------------- 1 | //***************************************************************************** 2 | //******************************* DHT SECTION ******************************** 3 | //***************************************************************************** 4 | mode = "satellite"; 5 | 6 | /** 7 | * key_mask 8 | * neighbors 9 | */ 10 | dht_key_mask_length = 1; 11 | dht_key_mask_offset = 5; 12 | neighbors : ( { 13 | // satellite 14 | ip = "192.168.1.4" ; 15 | port = 31852; 16 | local = 1; 17 | }, 18 | { 19 | // Storage node 20 | ip = "192.168.1.4" ; 21 | port = 31850; 22 | keys = { start = "0", end = "255" }; 23 | } ); 24 | 25 | -------------------------------------------------------------------------------- /apps/daqdb-top/configs/server.cfg: -------------------------------------------------------------------------------- 1 | //***************************************************************************** 2 | //******************************* DHT SECTION ******************************** 3 | //***************************************************************************** 4 | 5 | /** 6 | * key_mask 7 | * neighbors 8 | */ 9 | dht_key_mask_length = 1; 10 | dht_key_mask_offset = 5; 11 | neighbors : ( 12 | { 13 | // Storage node 14 | ip = "192.168.1.4"; 15 | port = 31850; 16 | keys = { start = "0", end = "255" }; 17 | local = 1; 18 | } ); 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /apps/daqdb-top/utils.hpp: -------------------------------------------------------------------------------- 1 | // Standard 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | // DAQDB 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | 19 | struct __attribute__((packed)) CliNodeKey { 20 | uint8_t eventId[5]; 21 | uint8_t detectorId; 22 | uint16_t componentId; 23 | }; 24 | 25 | DaqDB::Key assign_key(DaqDB::KVStoreBase *m_kvs, uint64_t &eventId, int detectorId ) { 26 | DaqDB::Key key = m_kvs->AllocKey(DaqDB::KeyValAttribute::NOT_BUFFERED); 27 | 28 | CliNodeKey *daqdb_key = reinterpret_cast(key.data()); 29 | daqdb_key->detectorId = 0; 30 | daqdb_key->componentId = detectorId; 31 | memcpy(&daqdb_key->eventId, &eventId, sizeof(daqdb_key->eventId)); 32 | return key; 33 | } 34 | 35 | 36 | 37 | // Setting CPU affinity when executing the benchmark (DHT Threads and DHT Poolers) 38 | void SetAffinity(int baseCore) { 39 | int cid = baseCore ; 40 | cpu_set_t cpuset; 41 | CPU_ZERO(&cpuset); 42 | CPU_SET(cid, &cpuset); 43 | int rc = pthread_setaffinity_np(pthread_self(), sizeof(cpuset), &cpuset); 44 | if (rc != 0) { 45 | std::cerr << "Error calling pthread_setaffinity_np: " << rc << "\n"; 46 | } 47 | } 48 | 49 | 50 | bool thread_wait(int ms, std::shared_future f ){ 51 | std::future_status status; 52 | if (!ms) { 53 | f.wait(); 54 | } else { 55 | status = f.wait_for(std::chrono::milliseconds(ms)); 56 | if (status != std::future_status::ready) { 57 | return false; 58 | } 59 | } 60 | return true; 61 | } 62 | 63 | -------------------------------------------------------------------------------- /apps/minidaq/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | project(minidaq) 4 | 5 | include(FindPkgConfig) 6 | find_package(PkgConfig) 7 | 8 | option(MINIDAQ_INTEGRITY_CHECK "Enable data integrity check" OFF) 9 | if(MINIDAQ_INTEGRITY_CHECK) 10 | add_definitions(-DWITH_INTEGRITY_CHECK) 11 | MESSAGE(STATUS "Data integrity check enabled.") 12 | else(MINIDAQ_INTEGRITY_CHECK) 13 | MESSAGE(STATUS "Data integrity check disabled.") 14 | endif(MINIDAQ_INTEGRITY_CHECK) 15 | 16 | set(CMAKE_CXX_STANDARD 14) 17 | 18 | set(ROOT_DAQDB_DIR ${PROJECT_SOURCE_DIR}/../..) 19 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${ROOT_DAQDB_DIR}/bin) 20 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${ROOT_DAQDB_DIR}/bin) 21 | 22 | find_package(Boost REQUIRED COMPONENTS program_options) 23 | find_package(Threads REQUIRED) 24 | set(Dpdk_LIBRARIES -Wl,--whole-archive dpdk -Wl,--no-whole-archive) 25 | 26 | configure_file(minidaq.cfg.in 27 | ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/minidaq.cfg.sample COPYONLY) 28 | 29 | file(GLOB MINIDAQ_SOURCES *.cpp *.h) 30 | add_executable(minidaq ${MINIDAQ_SOURCES}) 31 | set(MINIDAQ_LINK_LIBRARIES ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} dl numa z hdr_histogram) 32 | if(NOT THIN_LIB) 33 | list(APPEND MINIDAQ_LINK_LIBRARIES pmem pmemobj daqdb ${Dpdk_LIBRARIES}) 34 | else (NOT THIN_LIB) 35 | list(APPEND MINIDAQ_LINK_LIBRARIES daqdb_thin) 36 | if(NOT ERPC_RAW_TRANSPORT) 37 | list(APPEND MINIDAQ_LINK_LIBRARIES ${Dpdk_LIBRARIES}) 38 | endif(NOT ERPC_RAW_TRANSPORT) 39 | endif(NOT THIN_LIB) 40 | target_link_libraries(minidaq ${MINIDAQ_LINK_LIBRARIES}) 41 | -------------------------------------------------------------------------------- /apps/minidaq/MinidaqAroNode.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "MinidaqAroNode.h" 18 | #include 19 | 20 | namespace DaqDB { 21 | 22 | MinidaqAroNode::MinidaqAroNode(KVStoreBase *kvs) : MinidaqRoNode(kvs) {} 23 | 24 | MinidaqAroNode::~MinidaqAroNode() {} 25 | 26 | std::string MinidaqAroNode::_GetType() { return std::string("readout-async"); } 27 | 28 | void MinidaqAroNode::_Task(Key &&key, std::atomic &cnt, 29 | std::atomic &cntErr) { 30 | DaqDB::Value value; 31 | try { 32 | value = _kvs->Alloc(key, _nextFragmentSize()); 33 | } 34 | catch (...) { 35 | _kvs->Free(std::move(key)); 36 | throw; 37 | } 38 | 39 | pmem_memcpy_nodrain(value.data(), _data_buffer, value.size()); 40 | 41 | #ifdef WITH_INTEGRITY_CHECK 42 | _FillBuffer(key, value.data(), value.size()); 43 | #endif /* WITH_INTEGRITY_CHECK */ 44 | 45 | _kvs->PutAsync(std::move(key), std::move(value), 46 | [&cnt, &cntErr](DaqDB::KVStoreBase *kvs, 47 | DaqDB::Status status, const char *key, 48 | const size_t keySize, const char *value, 49 | const size_t valueSize) { 50 | if (!status.ok()) { 51 | cntErr++; 52 | } else { 53 | cnt++; 54 | } 55 | }); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /apps/minidaq/MinidaqAroNode.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include "MinidaqRoNode.h" 20 | 21 | namespace DaqDB { 22 | 23 | class MinidaqAroNode : public MinidaqRoNode { 24 | public: 25 | explicit MinidaqAroNode(KVStoreBase *kvs); 26 | ~MinidaqAroNode(); 27 | 28 | protected: 29 | void _Task(Key &&key, std::atomic &cnt, 30 | std::atomic &cntErr); 31 | std::string _GetType(); 32 | }; 33 | } 34 | -------------------------------------------------------------------------------- /apps/minidaq/MinidaqFfNode.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include "MinidaqNode.h" 20 | 21 | namespace DaqDB { 22 | 23 | class MinidaqFfNode : public MinidaqNode { 24 | public: 25 | explicit MinidaqFfNode(KVStoreBase *kvs); 26 | virtual ~MinidaqFfNode(); 27 | 28 | void SetSubdetectors(int n); 29 | void SetBaseSubdetectorId(int id); 30 | void SetAcceptLevel(double p); 31 | void SetRetryDelay(int d); 32 | 33 | protected: 34 | void _Task(Key &&key, std::atomic &cnt, 35 | std::atomic &cntErr); 36 | void _Setup(int executorId); 37 | Key _NextKey(); 38 | std::string _GetType(); 39 | bool _Accept(); 40 | int _PickSubdetector(); 41 | int _PickNFragments(); 42 | 43 | int _baseId = 0; 44 | int _nSubdetectors = 0; 45 | int _delay_us = 100; 46 | int _maxRetries = 100; 47 | 48 | private: 49 | double _acceptLevel = 1.0; // desired acceptance level for filtering nodes 50 | }; 51 | } 52 | -------------------------------------------------------------------------------- /apps/minidaq/MinidaqFfNodeSeq.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include "MinidaqFfNode.h" 20 | 21 | namespace DaqDB { 22 | 23 | class MinidaqFfNodeSeq : public MinidaqFfNode { 24 | public: 25 | explicit MinidaqFfNodeSeq(KVStoreBase *kvs); 26 | virtual ~MinidaqFfNodeSeq(); 27 | 28 | protected: 29 | void _Task(Key &&key, std::atomic &cnt, 30 | std::atomic &cntErr); 31 | void _Setup(int executorId); 32 | Key _NextKey(); 33 | std::string _GetType(); 34 | 35 | static thread_local uint64_t _eventId; 36 | static_assert(sizeof(_eventId) >= sizeof(MinidaqKey().eventId), 37 | "Event Id field of MinidaqKey is too big"); 38 | }; 39 | } 40 | -------------------------------------------------------------------------------- /apps/minidaq/MinidaqRoNode.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include "MinidaqNode.h" 20 | 21 | namespace DaqDB { 22 | 23 | class MinidaqRoNode : public MinidaqNode { 24 | public: 25 | explicit MinidaqRoNode(KVStoreBase *kvs); 26 | virtual ~MinidaqRoNode(); 27 | 28 | void SetFragmentSize(size_t s); 29 | void SetFragmentDistro(const std::string &distro); 30 | void SetSubdetectorId(int id); 31 | 32 | protected: 33 | void _Task(Key &&key, std::atomic &cnt, 34 | std::atomic &cntErr); 35 | void _Setup(int executorId); 36 | std::function _nextFragmentSize; 37 | Key _NextKey(); 38 | std::string _GetType(); 39 | 40 | size_t _fSize = 0; 41 | int _id = 0; 42 | static thread_local uint64_t _eventId; 43 | static_assert(sizeof(_eventId) >= sizeof(MinidaqKey().eventId), 44 | "Event Id field of MinidaqKey is too big"); 45 | static thread_local constexpr char _data_buffer[100000] = " "; 46 | }; 47 | } 48 | -------------------------------------------------------------------------------- /apps/minidaq/MinidaqStats.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include "hdr_histogram.h" 20 | #include 21 | #include 22 | #include 23 | 24 | namespace DaqDB { 25 | 26 | enum MinidaqMetricType { 27 | MINIDAQ_METRIC_RPS, 28 | MINIDAQ_METRIC_RPS_ERR, 29 | MINIDAQ_METRIC_CPS, 30 | MINIDAQ_METRIC_CPS_ERR, 31 | }; 32 | 33 | struct MinidaqSample { 34 | MinidaqSample() = default; 35 | MinidaqSample(uint64_t r, uint64_t c, uint64_t e_r, uint64_t e_c, 36 | uint64_t ns) 37 | : nRequests(r), nCompletions(c), nErrRequests(e_r), 38 | nErrCompletions(e_c), interval_ns(ns){}; 39 | void Reset() { 40 | nRequests = 0; 41 | nCompletions = 0; 42 | nErrRequests = 0; 43 | nErrCompletions = 0; 44 | interval_ns = 0; 45 | } 46 | uint64_t nRequests = 0; 47 | uint64_t nCompletions = 0; 48 | uint64_t nErrRequests = 0; 49 | uint64_t nErrCompletions = 0; 50 | uint64_t interval_ns = 0; 51 | }; 52 | 53 | class MinidaqStats { 54 | public: 55 | MinidaqStats(); 56 | explicit MinidaqStats(const std::vector &rVector); 57 | ~MinidaqStats(); 58 | MinidaqStats(const MinidaqStats &other); 59 | MinidaqStats &operator=(MinidaqStats &&other); 60 | 61 | static void ShowSample(const std::string &info, const MinidaqSample &s); 62 | void RecordSample(const MinidaqSample &s); 63 | void Combine(const MinidaqStats &stats); 64 | 65 | void Dump(); 66 | void Dump(const std::string &fp); 67 | void DumpSummary(); 68 | void DumpSummary(const std::string &fp, const std::string &name); 69 | void DumpSummaryHeader(); 70 | 71 | private: 72 | void _DumpCsv(const std::string &fp, enum MinidaqMetricType histo_type); 73 | void _DumpSummary(enum MinidaqMetricType histo_type); 74 | void _DumpSummaryCsv(std::fstream &f, enum MinidaqMetricType histo_type); 75 | 76 | struct hdr_histogram *_histogramRps = nullptr; 77 | struct hdr_histogram *_histogramCps = nullptr; 78 | struct hdr_histogram *_histogramRpsErr = nullptr; 79 | struct hdr_histogram *_histogramCpsErr = nullptr; 80 | 81 | uint64_t _nIterations = 0; 82 | uint64_t _totalTime_ns = 0; 83 | uint64_t _nOverflows = 0; 84 | }; 85 | } 86 | -------------------------------------------------------------------------------- /apps/minidaq/MinidaqTimer.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "MinidaqTimer.h" 18 | 19 | using namespace std; 20 | 21 | namespace DaqDB { 22 | 23 | MinidaqTimer::MinidaqTimer() {} 24 | 25 | MinidaqTimer::~MinidaqTimer() {} 26 | } 27 | -------------------------------------------------------------------------------- /apps/minidaq/MinidaqTimer.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | namespace DaqDB { 22 | 23 | class MinidaqTimer { 24 | public: 25 | MinidaqTimer(); 26 | virtual ~MinidaqTimer(); 27 | 28 | virtual void Restart_s(int interval_s) = 0; 29 | virtual void Restart_ms(int interval_ms) = 0; 30 | virtual void Restart_us(int interval_us) = 0; 31 | virtual bool IsExpired() = 0; 32 | virtual uint64_t GetElapsed_ns() = 0; 33 | }; 34 | } 35 | -------------------------------------------------------------------------------- /apps/minidaq/MinidaqTimerHR.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "MinidaqTimerHR.h" 18 | 19 | namespace DaqDB { 20 | 21 | MinidaqTimerHR::MinidaqTimerHR() {} 22 | 23 | MinidaqTimerHR::~MinidaqTimerHR() {} 24 | 25 | void MinidaqTimerHR::_restart() { 26 | _expired = false; 27 | _start = std::chrono::high_resolution_clock::now(); 28 | } 29 | 30 | void MinidaqTimerHR::Restart_s(int interval_s) { 31 | _reqInterval = std::chrono::seconds(interval_s); 32 | _restart(); 33 | } 34 | 35 | void MinidaqTimerHR::Restart_ms(int interval_ms) { 36 | _reqInterval = std::chrono::milliseconds(interval_ms); 37 | _restart(); 38 | } 39 | 40 | void MinidaqTimerHR::Restart_us(int interval_us) { 41 | _reqInterval = std::chrono::microseconds(interval_us); 42 | _restart(); 43 | } 44 | 45 | bool MinidaqTimerHR::IsExpired() { 46 | if (_expired) { 47 | return _expired; 48 | } 49 | auto now = std::chrono::high_resolution_clock::now(); 50 | _currInterval = 51 | std::chrono::duration_cast(now - _start); 52 | if (_currInterval >= _reqInterval) { 53 | _expired = true; 54 | } 55 | return _expired; 56 | } 57 | 58 | uint64_t MinidaqTimerHR::GetElapsed_ns() { 59 | IsExpired(); 60 | std::chrono::duration ns(_currInterval); 61 | return ns.count(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /apps/minidaq/MinidaqTimerHR.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include "MinidaqTimer.h" 22 | 23 | namespace DaqDB { 24 | 25 | class MinidaqTimerHR : public MinidaqTimer { 26 | public: 27 | MinidaqTimerHR(); 28 | ~MinidaqTimerHR(); 29 | 30 | void Restart_s(int interval_s); 31 | void Restart_ms(int interval_ms); 32 | void Restart_us(int interval_us); 33 | bool IsExpired(); 34 | uint64_t GetElapsed_ns(); 35 | 36 | private: 37 | std::chrono::nanoseconds _reqInterval; 38 | std::chrono::nanoseconds _currInterval; 39 | std::chrono::time_point _start; 40 | bool _expired = true; 41 | 42 | void _restart(); 43 | }; 44 | } 45 | -------------------------------------------------------------------------------- /apps/minidaq/minidaq.cfg.in: -------------------------------------------------------------------------------- 1 | // Configuration example for running minidaq 2 | 3 | //***************************************************************************** 4 | //******************************* DHT SECTION ******************************** 5 | //***************************************************************************** 6 | 7 | /** 8 | * key_mask 9 | * neighbors 10 | */ 11 | dht_key_mask_length = 1; 12 | dht_key_mask_offset = 5; 13 | neighbors : ( 14 | { 15 | // Local node 16 | ip = "10.10.10.53"; 17 | port = 31850; 18 | local = 1; 19 | }, 20 | { 21 | // Storage node 22 | ip = "10.10.10.55"; 23 | port = 31850; 24 | keys = { start = "0", end = "255" } 25 | }, ); 26 | -------------------------------------------------------------------------------- /apps/mist/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | project(mist) 4 | 5 | include(FindPkgConfig) 6 | find_package(PkgConfig) 7 | 8 | set(CMAKE_CXX_STANDARD 14) 9 | 10 | set(ROOT_DAQDB_DIR ${PROJECT_SOURCE_DIR}/../..) 11 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${ROOT_DAQDB_DIR}/bin) 12 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${ROOT_DAQDB_DIR}/bin) 13 | 14 | find_package(Boost REQUIRED COMPONENTS program_options system filesystem) 15 | find_package(Threads REQUIRED) 16 | 17 | include_directories(${LIBCONFIG_INCLUDES_EXPORT}) 18 | 19 | file(GLOB MIST_SOURCES ${APPS}/mist/*.cpp ${APPS}/mist/*.hpp) 20 | add_executable(mist ${MIST_SOURCES}) 21 | set(Dpdk_LIBRARIES -Wl,--whole-archive dpdk -Wl,--no-whole-archive) 22 | target_link_libraries(mist ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INT} 23 | ${CMAKE_THREAD_LIBS_INIT} ${Dpdk_LIBRARIES} daqdb_thin dl numa) 24 | 25 | configure_file(mist.cfg.in 26 | ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/mist.cfg.sample COPYONLY) 27 | -------------------------------------------------------------------------------- /apps/mist/config.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "config.h" 18 | #include 19 | #include 20 | 21 | typedef char DEFAULT_KeyType[16]; 22 | 23 | void initKvsOptions(DaqDB::Options &options, const std::string &configFile) { 24 | options.runtime.logFunc = [](std::string msg) { 25 | std::cout << msg << std::endl; 26 | }; 27 | 28 | /* Set default values */ 29 | options.dht.id = 0; 30 | 31 | options.key.field(0, sizeof(DEFAULT_KeyType)); 32 | 33 | if (boost::filesystem::exists(configFile)) { 34 | std::stringstream errorMsg; 35 | if (!DaqDB::readConfiguration(configFile, options, errorMsg)) { 36 | std::cout << errorMsg.str() << std::flush; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /apps/mist/config.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | void initKvsOptions(DaqDB::Options &options, const std::string &configFile); 22 | -------------------------------------------------------------------------------- /apps/mist/mist.cfg.in: -------------------------------------------------------------------------------- 1 | // Configuration example running DaqDB library in sattellite mode 2 | 3 | //***************************************************************************** 4 | //******************************* MAIN SECTION ******************************** 5 | //***************************************************************************** 6 | 7 | /** 8 | * mode - operational mode of this DaqDB instance. Valid parameters: 9 | * storage - this instance will accept and store internally data 10 | * satellite - this instance will accept and forward all data to 11 | * one of the storage nodes 12 | */ 13 | mode = "satellite"; 14 | 15 | /** 16 | * logging_level - valid parameters: 17 | * logging_level = "DEBUG"; 18 | * logging_level = "FATAL"; 19 | */ 20 | logging_level = "DEBUG"; 21 | 22 | //***************************************************************************** 23 | //******************************* DATA SECTION ******************************** 24 | //***************************************************************************** 25 | 26 | /** 27 | * keys_structure - defines how compound structure of a key looks like 28 | * format: /1/8/4/16, representing 29 bytes total key 29 | * with four parts 30 | * primaryKey - primary key is being used to derive positioning of 31 | * data. It is defined by operation on key parts. 32 | * described by consecutive numbers starting with 1, e.g. 33 | * 1*3 34 | * Result has to be unique for all the key stored. 35 | */ 36 | keys_structure = [ 1, 31, 8, 24]; 37 | primaryKey = "1*3"; 38 | 39 | //***************************************************************************** 40 | //******************************* DHT SECTION ******************************** 41 | //***************************************************************************** 42 | 43 | /** 44 | * key_mask 45 | * neighbors 46 | */ 47 | dht_key_mask_length = 1; 48 | dht_key_mask_offset = 0; 49 | neighbors : 50 | ( 51 | { 52 | ip = "localhost"; 53 | port = 31851; 54 | local = 1; 55 | }, 56 | { 57 | ip = "localhost"; 58 | port = 31850; 59 | keys = { start = "0", end = "255"} 60 | }, 61 | ); 62 | 63 | //************************************ EOF ************************************ 64 | -------------------------------------------------------------------------------- /apps/mist/mist.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "config.h" 27 | 28 | using namespace std; 29 | namespace po = boost::program_options; 30 | 31 | int main(int argc, char **argv) { 32 | string configFile; 33 | DaqDB::Options options; 34 | 35 | po::options_description argumentsDescription{"Options"}; 36 | argumentsDescription.add_options()("help,h", "Print help messages")( 37 | "config-file,c", 38 | po::value(&configFile)->default_value("mist.cfg"), 39 | "Configuration file"); 40 | 41 | po::variables_map parsedArguments; 42 | try { 43 | po::store(po::parse_command_line(argc, argv, argumentsDescription), 44 | parsedArguments); 45 | 46 | if (parsedArguments.count("help")) { 47 | std::cout << argumentsDescription << endl; 48 | return 0; 49 | } 50 | po::notify(parsedArguments); 51 | } catch (po::error &parserError) { 52 | cerr << "Invalid arguments: " << parserError.what() << endl << endl; 53 | cerr << argumentsDescription << endl; 54 | return -1; 55 | } 56 | 57 | initKvsOptions(options, configFile); 58 | 59 | asio::io_service io_service; 60 | asio::signal_set signals(io_service, SIGINT, SIGTERM); 61 | signals.async_wait(boost::bind(&asio::io_service::stop, &io_service)); 62 | 63 | try { 64 | DaqDB::KVStoreBase::Open(options); 65 | } catch (DaqDB::OperationFailedException &e) { 66 | cerr << "Failed to create KVStore: " << e.what() << endl; 67 | return -1; 68 | } 69 | cout << "DaqDB server running" << endl; 70 | 71 | io_service.run(); 72 | // cleanup code 73 | cout << "Exiting gracefully" << endl; 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /cmake/BoostTestHelpers.cmake: -------------------------------------------------------------------------------- 1 | function(add_boost_test SOURCE_FILE_NAME) 2 | get_filename_component(TEST_EXECUTABLE_NAME ${SOURCE_FILE_NAME} NAME_WE) 3 | 4 | add_executable(${TEST_EXECUTABLE_NAME} ${SOURCE_FILE_NAME}) 5 | set(Dpdk_LIBRARIES -Wl,--whole-archive dpdk -Wl,--no-whole-archive) 6 | target_link_libraries(${TEST_EXECUTABLE_NAME} ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} 7 | daqdb pmemobj ${Dpdk_LIBRARIES} dl numa 8 | ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) 9 | 10 | file(READ "${SOURCE_FILE_NAME}" SOURCE_FILE_CONTENTS) 11 | string(REGEX MATCHALL "BOOST_AUTO_TEST_CASE\\( *([A-Za-z_0-9]+) *\\)" 12 | FOUND_TESTS ${SOURCE_FILE_CONTENTS}) 13 | 14 | foreach(HIT ${FOUND_TESTS}) 15 | string(REGEX REPLACE ".*\\( *([A-Za-z_0-9]+) *\\).*" "\\1" TEST_NAME ${HIT}) 16 | 17 | add_test(NAME "${TEST_EXECUTABLE_NAME}.${TEST_NAME}" 18 | COMMAND ${TEST_EXECUTABLE_NAME} --run_test=${TEST_NAME} --log_level=all --catch_system_error=yes) 19 | endforeach() 20 | 21 | string(REGEX MATCHALL "BOOST_FIXTURE_TEST_CASE\\(([A-Za-z_0-9]+), [A-Za-z_0-9:]+\\)" 22 | FOUND_TESTS_F ${SOURCE_FILE_CONTENTS}) 23 | 24 | foreach(HIT ${FOUND_TESTS_F}) 25 | string(REGEX REPLACE "BOOST_FIXTURE_TEST_CASE\\(([A-Za-z_0-9]+), [A-Za-z_0-9:]+\\).*" "\\1" TEST_NAME ${HIT}) 26 | 27 | add_test(NAME "${TEST_EXECUTABLE_NAME}.${TEST_NAME}" 28 | COMMAND ${TEST_EXECUTABLE_NAME} --run_test=${TEST_NAME} --log_level=all --catch_system_error=yes) 29 | endforeach() 30 | 31 | endfunction() 32 | -------------------------------------------------------------------------------- /cmake/CleanAll.cmake: -------------------------------------------------------------------------------- 1 | set(ROOT_DAQDB_DIR ${CMAKE_CURRENT_LIST_DIR}/..) 2 | set(cmake_generated bin 3 | CMakeCache.txt 4 | cmake_install.cmake 5 | Makefile 6 | CMakeFiles 7 | Testing 8 | CTestTestfile.cmake 9 | DartConfiguration.tcl 10 | ) 11 | set(folders_to_clean . apps apps/minidaq apps/mist 12 | examples examples/basic examples/cli_node examples/fabric_node 13 | tests tests/unit tests/functional 14 | third-party third-party/eRPC third-party/libconfig) 15 | 16 | file(REMOVE_RECURSE ${ROOT_DAQDB_DIR}/bin) 17 | foreach(file ${cmake_generated}) 18 | foreach(folder ${folders_to_clean}) 19 | if (EXISTS ${ROOT_DAQDB_DIR}/${folder}/${file}) 20 | file(REMOVE_RECURSE ${ROOT_DAQDB_DIR}/${folder}/${file}) 21 | endif() 22 | endforeach(folder) 23 | endforeach(file) 24 | -------------------------------------------------------------------------------- /cmake/FindConfig++.cmake: -------------------------------------------------------------------------------- 1 | FIND_PATH(CONFIG++_INCLUDE_DIR libconfig.h++ /usr/include /usr/local/include) 2 | 3 | FIND_LIBRARY(CONFIG++_LIBRARY NAMES config++ PATH /usr/lib /usr/local/lib) 4 | 5 | IF (CONFIG++_INCLUDE_DIR AND CONFIG++_LIBRARY) 6 | SET(CONFIG++_FOUND TRUE) 7 | ENDIF ( CONFIG++_INCLUDE_DIR AND CONFIG++_LIBRARY) 8 | 9 | IF (CONFIG++_FOUND) 10 | IF (NOT CONFIG++_FIND_QUIETLY) 11 | MESSAGE(STATUS "Found Config++: ${CONFIG++_LIBRARY}") 12 | ENDIF (NOT CONFIG++_FIND_QUIETLY) 13 | ELSE(CONFIG++_FOUND) 14 | IF (Config++_FIND_REQUIRED) 15 | IF(NOT CONFIG++_INCLUDE_DIR) 16 | MESSAGE(FATAL_ERROR "Could not find LibConfig++ header file!") 17 | ENDIF(NOT CONFIG++_INCLUDE_DIR) 18 | 19 | IF(NOT CONFIG++_LIBRARY) 20 | MESSAGE(FATAL_ERROR "Could not find LibConfig++ library file!") 21 | ENDIF(NOT CONFIG++_LIBRARY) 22 | ENDIF (Config++_FIND_REQUIRED) 23 | ENDIF (CONFIG++_FOUND) 24 | -------------------------------------------------------------------------------- /doc/network_setup_guide.md: -------------------------------------------------------------------------------- 1 | # Network setup guide 2 | 3 | ### Mellanox cards setup guide 4 | ConnectX-4 or newer Mellanox Ethernet NICs are supported. 5 | 6 | Following steps should be performed to run DaqDB with this network configuration. 7 | * [Build and install kernel with PMEM and OFED support](#Build-and-install-kernel-with-PMEM-and-OFED-support) 8 | * [Install Mellanox OFED driver](#Install-Mellanox-OFED-driver) 9 | * [Set Ethernet mode](Set-Ethernet-mode) 10 | 11 | ##### Build and install kernel with PMEM and OFED support 12 | 13 | This section can be skipped for Fedora 28. 14 | 15 | Kernel config file can be taken from [here](config/config_4_15.txt). 16 | 17 | Kernel building and installation may be done as below: 18 | ``` 19 | wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.15.tar.xz 20 | tar xvf linux-4.15.tar.xz 21 | cd linux-4.15 22 | cp .config 23 | make oldconfig 24 | make -j `nproc` && make modules_install && make install 25 | yum install rpm-build -y 26 | make rpm-pkg 27 | rpm -iUv ~/rpmbuild/RPMS/x86_64/kernel-headers-4.15.0-1.x86_64.rpm 28 | ``` 29 | Update kernel boot options e.g. 30 | ``` 31 | vim /etc/default/grub 32 | ... 33 | GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet" 34 | ... 35 | 36 | grub2-mkconfig -o /etc/grub2-efi.cfg 37 | ``` 38 | _Note: The highest version that may be used is 4.15 39 | e.g. kernel version 4.17 doesn't support Mellanox OFED._ 40 | 41 | 42 | ##### Install Mellanox OFED driver 43 | See [here](http://www.mellanox.com/downloaders/mlnx_en_downloader/downloader.html#) for correct version. Following steps for CentOS 7.6: 44 | 45 | ``` 46 | wget http://www.mellanox.com/downloads/ofed/MLNX_EN-4.5-1.0.1.0/mlnx-en-4.5-1.0.1.0-rhel7.6-x86_64.tgz 47 | tar zxf mlnx-en-4.5-1.0.1.0-rhel7.6-x86_64.tgz 48 | cd mlnx-en-4.5-1.0.1.0-rhel7.6-x86_64 49 | ./install --add-kernel-support --dpdk 50 | ``` 51 | _Note: It may be necessary to install some extra packages e.g createrepo, elfutils_ 52 | 53 | ##### Set Ethernet mode 54 | ``` 55 | wget http://www.mellanox.com/downloads/MFT/mft-4.11.0-103-x86_64-rpm.tgz 56 | tar zxvf mft-4.11.0-103-x86_64-rpm.tgz 57 | cd mft-4.11.0-103-x86_64-rpm 58 | ./install.sh 59 | ``` 60 | follow [Getting Started with ConnectX-5 100Gb/s Adapters for Linux](https://community.mellanox.com/s/article/getting-started-with-connectx-5-100gb-s-adapters-for-linux) 61 | 62 | Depends on network card version e.g. 63 | ``` 64 | mst start 65 | mlxconfig -d /dev/mst/mt4119_pciconf0 set LINK_TYPE_P1=2 66 | ifconfig ens801f0 15.15.15.5/24 up 67 | ``` -------------------------------------------------------------------------------- /doc/user_guides.md: -------------------------------------------------------------------------------- 1 | # User guides 2 | 3 | [Network setup guide](network_setup_guide.md) -------------------------------------------------------------------------------- /examples/basic/.gitignore: -------------------------------------------------------------------------------- 1 | basic 2 | -------------------------------------------------------------------------------- /examples/basic/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | project(basic) 4 | 5 | include(FindPkgConfig) 6 | find_package(PkgConfig) 7 | find_package(Threads REQUIRED) 8 | 9 | set(CMAKE_CXX_STANDARD 14) 10 | 11 | set(ROOT_DAQDB_DIR ${PROJECT_SOURCE_DIR}/../..) 12 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${ROOT_DAQDB_DIR}/bin) 13 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${ROOT_DAQDB_DIR}/bin) 14 | 15 | set(3RDPARTY ${ROOT_DAQDB_DIR}/third-party) 16 | set(Dpdk_LIBRARIES -Wl,--whole-archive dpdk -Wl,--no-whole-archive) 17 | 18 | file(GLOB BASIC_SOURCES *.cpp) 19 | add_executable(basic ${BASIC_SOURCES}) 20 | target_link_libraries(basic ${Boost_LIBRARIES} ${Dpdk_LIBRARIES} daqdb pmemobj dl 21 | numa ${CMAKE_THREAD_LIBS_INIT} ) 22 | -------------------------------------------------------------------------------- /examples/clinode/.gitignore: -------------------------------------------------------------------------------- 1 | cli_node 2 | -------------------------------------------------------------------------------- /examples/clinode/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | project(clinode) 4 | 5 | include(FindPkgConfig) 6 | find_package(PkgConfig) 7 | find_package(Boost REQUIRED COMPONENTS program_options log log_setup system filesystem thread) 8 | find_package(Threads REQUIRED) 9 | 10 | set(CMAKE_CXX_STANDARD 14) 11 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBOOST_LOG_DYN_LINK") 12 | 13 | set(ROOT_DAQDB_DIR ${PROJECT_SOURCE_DIR}/../..) 14 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${ROOT_DAQDB_DIR}/bin) 15 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${ROOT_DAQDB_DIR}/bin) 16 | 17 | set(3RDPARTY ${ROOT_DAQDB_DIR}/third-party) 18 | 19 | include_directories(linenoise) 20 | add_library(linenoise SHARED linenoise/linenoise.c linenoise/linenoise.h) 21 | 22 | file(GLOB CLINODE_SOURCES ${EXAMPLES}/clinode/*.cpp ${EXAMPLES}/clinode/*.h) 23 | add_executable(clinode ${CLINODE_SOURCES}) 24 | 25 | configure_file(clinode.cfg.in 26 | ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/clinode.cfg.sample COPYONLY) 27 | 28 | set(Dpdk_LIBRARIES -Wl,--whole-archive dpdk -Wl,--no-whole-archive) 29 | target_link_libraries(clinode ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} 30 | ${Dpdk_LIBRARIES} pmem daqdb linenoise pmemobj dl numa) 31 | -------------------------------------------------------------------------------- /examples/clinode/config.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | #include "config.h" 20 | 21 | const std::string DEFAULT_PMEM_POOL_PATH = "/mnt/pmem/pool.pm"; 22 | const size_t DEFAULT_PMEM_POOL_SIZE = 8ull * 1024 * 1024 * 1024; 23 | const size_t DEFAULT_PMEM_ALLOC_UNIT_SIZE = 1024; 24 | 25 | const size_t DEFAULT_OFFLOAD_ALLOC_UNIT_SIZE = 16384; 26 | 27 | void initKvsOptions(DaqDB::Options &options, const std::string &configFile) { 28 | options.runtime.logFunc = [](std::string msg) { 29 | BOOST_LOG_SEV(lg::get(), bt::debug) << msg << std::flush; 30 | }; 31 | 32 | /* Set default values */ 33 | options.dht.id = 0; 34 | 35 | options.pmem.poolPath = DEFAULT_PMEM_POOL_PATH; 36 | options.pmem.totalSize = DEFAULT_PMEM_POOL_SIZE; 37 | options.pmem.allocUnitSize = DEFAULT_PMEM_ALLOC_UNIT_SIZE; 38 | 39 | options.key.field(0, sizeof(CliNodeKey::eventId), true); 40 | options.key.field(1, sizeof(CliNodeKey::detectorId)); 41 | options.key.field(2, sizeof(CliNodeKey::componentId)); 42 | 43 | options.offload.allocUnitSize = DEFAULT_OFFLOAD_ALLOC_UNIT_SIZE; 44 | 45 | if (boost::filesystem::exists(configFile)) { 46 | std::stringstream errorMsg; 47 | if (!DaqDB::readConfiguration(configFile, options, errorMsg)) { 48 | BOOST_LOG_SEV(lg::get(), bt::error) << errorMsg.str(); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /examples/clinode/config.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include 22 | 23 | #include "debug.h" 24 | #include 25 | 26 | struct __attribute__((packed)) CliNodeKey { 27 | uint8_t eventId[5]; 28 | uint8_t detectorId; 29 | uint16_t componentId; 30 | }; 31 | 32 | void initKvsOptions(DaqDB::Options &options, const std::string &configFile); 33 | -------------------------------------------------------------------------------- /examples/clinode/debug.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | namespace logging = boost::log; 30 | namespace bt = logging::trivial; 31 | namespace attrs = boost::log::attributes; 32 | namespace keywords = boost::log::keywords; 33 | namespace src = boost::log::sources; 34 | 35 | BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT( 36 | lg, src::severity_logger_mt) 37 | -------------------------------------------------------------------------------- /examples/clinode/nodeCli.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | namespace { 25 | const unsigned int consoleHintColor = 35; // dark red 26 | }; 27 | 28 | namespace DaqDB { 29 | 30 | /*! 31 | * Dragon shell interpreter. 32 | * Created for test purposes - to allow performing quick testing of the node. 33 | */ 34 | class nodeCli { 35 | public: 36 | explicit nodeCli(std::shared_ptr &spDragonSrv); 37 | virtual ~nodeCli(); 38 | 39 | /*! 40 | * Waiting for user input, executes defined commands 41 | * 42 | * @return false if user choose "quit" command, otherwise true 43 | */ 44 | int operator()(); 45 | 46 | private: 47 | void _cmdGet(const std::string &strLine); 48 | void _cmdGetAsync(const std::string &strLine); 49 | void _cmdPut(const std::string &strLine); 50 | void _cmdPutAsync(const std::string &strLine); 51 | void _cmdUpdate(const std::string &strLine); 52 | void _cmdUpdateAsync(const std::string &strLine); 53 | void _cmdRemove(const std::string &strLine); 54 | void _cmdStatus(); 55 | void _cmdNeighbors(); 56 | 57 | DaqDB::Key _strToKey(const std::string &key); 58 | DaqDB::Value _strToValue(const std::string &valStr); 59 | DaqDB::Value _allocValue(const DaqDB::Key &key, const std::string &valStr); 60 | 61 | /** 62 | * @return true if key is NOT correct 63 | */ 64 | inline bool _isInvalidKey(const std::string &key) { 65 | return ((key.size() == 0) || 66 | (key.size() > sizeof(CliNodeKey::eventId))); 67 | } 68 | 69 | DaqDB::PrimaryKeyAttribute 70 | _getKeyAttrs(unsigned char start, const std::vector &cmdAttrs); 71 | DaqDB::PrimaryKeyAttribute 72 | _getKeyAttr(unsigned char start, const std::vector &cmdAttrs); 73 | 74 | std::shared_ptr _spKVStore; 75 | std::vector _statusMsgs; 76 | }; 77 | } // namespace DaqDB 78 | -------------------------------------------------------------------------------- /include/config/KVStoreConfig.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | 22 | namespace DaqDB { 23 | bool readConfiguration(const std::string &configFile, DaqDB::Options &options); 24 | bool readConfiguration(const std::string &configFile, DaqDB::Options &options, 25 | std::stringstream &ss); 26 | 27 | } // namespace DaqDB 28 | -------------------------------------------------------------------------------- /include/daqdb/KVPair.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include "Key.h" 20 | #include "Value.h" 21 | 22 | namespace DaqDB { 23 | 24 | class KVPair { 25 | public: 26 | template T key() const { 27 | return *reinterpret_cast(key()); 28 | } 29 | 30 | Key key() const { return Key(); } 31 | 32 | Value value() const { return Value(); } 33 | 34 | size_t keySize(); 35 | size_t size() const; 36 | }; 37 | 38 | } // namespace DaqDB 39 | -------------------------------------------------------------------------------- /include/daqdb/Key.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include 22 | 23 | namespace DaqDB { 24 | 25 | class Key { 26 | public: 27 | Key() : attr(KeyValAttribute::NOT_BUFFERED), _data(nullptr), _size(0) {} 28 | Key(char *data, size_t size) 29 | : _data(data), _size(size), attr(KeyValAttribute::NOT_BUFFERED) {} 30 | Key(char *data, size_t size, KeyValAttribute attr) 31 | : _data(data), _size(size), attr(attr) {} 32 | char *data() { return _data; } 33 | 34 | /** 35 | * @return true if allocated inside KVS 36 | */ 37 | inline bool isKvsBuffered() const { 38 | return (attr & KeyValAttribute::KVS_BUFFERED); 39 | }; 40 | 41 | inline const char *data() const { return _data; } 42 | inline size_t size() const { return _size; } 43 | 44 | protected: 45 | KeyValAttribute attr; 46 | char *_data; 47 | size_t _size; 48 | }; 49 | 50 | } // namespace DaqDB 51 | -------------------------------------------------------------------------------- /include/daqdb/Types.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include "Status.h" 22 | 23 | namespace DaqDB { 24 | 25 | typedef unsigned int NodeId; 26 | 27 | #define FUNC_NOT_IMPLEMENTED \ 28 | NotImplementedException("function: " + std::string(__func__) + " [" + \ 29 | std::string(__FILE__) + ":" + \ 30 | std::to_string(__LINE__) + "]") 31 | 32 | #define FUNC_NOT_SUPPORTED \ 33 | NotSupportedFuncException("function: " + std::string(__func__) + " [" + \ 34 | std::string(__FILE__) + ":" + \ 35 | std::to_string(__LINE__) + "]") 36 | 37 | class NotImplementedException : public std::logic_error { 38 | public: 39 | explicit NotImplementedException(const std::string &what) 40 | : logic_error("Not Implemented: " + what) {} 41 | 42 | NotImplementedException() : logic_error("Not Implemented") {} 43 | }; 44 | 45 | class NotSupportedFuncException : public std::logic_error { 46 | public: 47 | explicit NotSupportedFuncException(const std::string &what) 48 | : logic_error("Not Supported: " + what) {} 49 | 50 | NotSupportedFuncException() : logic_error("Not Supported") {} 51 | }; 52 | 53 | class OperationFailedException : public std::runtime_error { 54 | public: 55 | OperationFailedException(Status s, const std::string &msg = "") 56 | : runtime_error(msg), _status(s) { 57 | set_what(); 58 | } 59 | explicit OperationFailedException(const std::string &msg = "") 60 | : runtime_error(msg), _status(UNKNOWN_ERROR) { 61 | set_what(); 62 | } 63 | OperationFailedException(int errnum, const std::string &msg = "") 64 | : runtime_error(msg), _status(errnum) { 65 | set_what(); 66 | } 67 | 68 | virtual const char *what() const noexcept { return _what.c_str(); } 69 | 70 | Status status() { return _status; } 71 | Status _status; 72 | std::string _what; 73 | 74 | private: 75 | void set_what() { 76 | _what = runtime_error::what(); 77 | 78 | if (!_status.ok() && 79 | _what.find(_status.to_string()) == std::string::npos) { 80 | _what += ": " + _status.to_string(); 81 | } 82 | } 83 | }; 84 | 85 | class QueueFullException : public std::runtime_error { 86 | public: 87 | QueueFullException() : runtime_error("Queue full") {} 88 | }; 89 | 90 | } // namespace DaqDB 91 | -------------------------------------------------------------------------------- /include/daqdb/Value.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | namespace DaqDB { 22 | 23 | class Value { 24 | public: 25 | Value() : attr(KeyValAttribute::NOT_BUFFERED), _data(nullptr), _size(0) {} 26 | Value(char *data, size_t size) 27 | : attr(KeyValAttribute::NOT_BUFFERED), _data(data), _size(size) {} 28 | Value(char *data, size_t size, KeyValAttribute attr) 29 | : _data(data), _size(size), attr(attr) {} 30 | char *data() { return _data; } 31 | inline const char *data() const { return _data; } 32 | inline size_t size() const { return _size; } 33 | inline bool isKvsBuffered() const { 34 | return (attr & KeyValAttribute::KVS_BUFFERED); 35 | }; 36 | inline Value &operator=(const Value &r) { 37 | if (&r == this) 38 | return *this; 39 | _data = r._data; 40 | _size = r._size; 41 | attr = r.attr; 42 | return *this; 43 | } 44 | 45 | protected: 46 | KeyValAttribute attr; 47 | char *_data; 48 | size_t _size; 49 | }; 50 | } 51 | -------------------------------------------------------------------------------- /lib/KVStoreBase.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | #ifndef THIN_LIB 20 | #include /* net/if.h (put before linux/if.h) */ 21 | #endif 22 | 23 | #include /* include linux/if.h */ 24 | 25 | namespace DaqDB { 26 | 27 | KVStoreBase *KVStoreBase::Open(const Options &options) { 28 | 29 | if (options.mode == OperationalMode::STORAGE) { 30 | #ifndef THIN_LIB 31 | return KVStore::Open(options); 32 | #else 33 | throw OperationFailedException(); 34 | #endif 35 | 36 | } else { 37 | return KVStoreThin::Open(options); 38 | } 39 | } 40 | 41 | } // namespace DaqDB 42 | -------------------------------------------------------------------------------- /lib/common/AllocStrategy.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | namespace DaqDB { 20 | class AllocStrategy { 21 | public: 22 | AllocStrategy() = default; 23 | virtual ~AllocStrategy() = default; 24 | virtual AllocStrategy *copy() const = 0; 25 | virtual unsigned int 26 | preallocateCount() const = 0; // # of preallocated objects per pool 27 | virtual unsigned int 28 | incrementQuant() const = 0; // Alloc increment when pool count is 0 29 | virtual unsigned int 30 | decrementQuant() const = 0; // Dealloc decrement when count > prealloc 31 | virtual unsigned int 32 | minIncQuant() const = 0; // Min increment in one go, smooths out growth 33 | virtual unsigned int 34 | maxIncQuant() const = 0; // Max increment in one go, smooths out growth 35 | virtual unsigned int 36 | minDecQuant() const = 0; // Min decrement in one go, smooths out decrese 37 | virtual unsigned int 38 | maxDecQuant() const = 0; // Max decrement in one go, smoots out decrease 39 | 40 | private: 41 | AllocStrategy(const AllocStrategy &right); 42 | AllocStrategy &operator=(const AllocStrategy &right); 43 | }; 44 | } // namespace DaqDB 45 | -------------------------------------------------------------------------------- /lib/common/ClassAlloc.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "ClassAlloc.h" 18 | #include 19 | 20 | void *getNewPtr(size_t size_, size_t inc_) { 21 | #ifdef _MM_DEBUG_ 22 | #ifndef _MM_GMP_ON_ 23 | std::cout << "::new(size_t size_, size_t inc_) " 24 | << " size_: " << size_ << " inc_: " << inc_ << endl 25 | << flush; 26 | #else 27 | fprintf(stderr, "::new(size_t size_, size_t inc_) size_: %d inc_: %d\n", 28 | size_, inc_); 29 | fflush(stderr); 30 | #endif 31 | #endif 32 | 33 | #ifndef _MM_GMP_ON_ 34 | return ::new char[size_ + inc_]; 35 | #else 36 | return (char *)::malloc(size_ + inc_) + inc_; 37 | #endif 38 | } 39 | -------------------------------------------------------------------------------- /lib/common/ClassAlloc.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | using namespace std; 23 | 24 | void *getNewPtr(size_t siz_, size_t inc_); 25 | 26 | namespace DaqDB { 27 | 28 | /* 29 | * ClassAlloc template is a default class allocator, see GeneralPool.h 30 | * User-defined classes may opt to use their own allocators, implementing 31 | * user-defined allocation strategies 32 | * When instantiated with a user-defined class, it'll be reposible for 33 | * allocating and constructing instances and destroying and deleting them 34 | */ 35 | template class ClassAlloc { 36 | public: 37 | static Z *New(unsigned int padd_); 38 | static void Delete(Z *obj_); 39 | static unsigned int objectSize(); 40 | static const char *getName(); 41 | 42 | private: 43 | ClassAlloc(const ClassAlloc &right); 44 | ClassAlloc &operator=(const ClassAlloc &right); 45 | }; 46 | 47 | template inline Z *ClassAlloc::New(unsigned int padd_) { 48 | #ifdef _MM_DEBUG_ 49 | #ifndef _MM_GMP_ON_ 50 | cout << " ClassAlloc::New, padd_: " << padd_ 51 | << " sizeof(Z): " << sizeof(Z) << endl 52 | << flush; 53 | #else 54 | fprintf(stderr, " ClassAlloc::New, padd_: %d sizeof(Z): %d\n", padd_, 55 | sizeof(Z)); 56 | fflush(stderr); 57 | #endif 58 | #endif 59 | 60 | return ::new (getNewPtr(sizeof(Z), padd_)) Z; 61 | } 62 | 63 | template inline void ClassAlloc::Delete(Z *obj_) {} 64 | 65 | template inline unsigned int ClassAlloc::objectSize() { 66 | return (unsigned int)sizeof(Z); 67 | } 68 | 69 | template inline const char *ClassAlloc::getName() { 70 | static const type_info &ti = typeid(Z); 71 | 72 | #ifdef _MM_DEBUG_ 73 | #ifndef _MM_GMP_ON_ 74 | cout << "NAME: " << ti.name() << endl << flush; 75 | #else 76 | fprintf(stderr, "NAME: %s\n", ti.name()); 77 | #endif 78 | #endif 79 | 80 | return ti.name(); 81 | } 82 | } // namespace DaqDB 83 | -------------------------------------------------------------------------------- /lib/common/ClassMemoryAlloc.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | using namespace std; 23 | #include 24 | 25 | namespace DaqDB { 26 | 27 | /* 28 | * ClassMemoryAlloc template is an example class allocator with built-in 29 | * standard new operator User-defined classes may opt to use their own 30 | * allocators, implementing user-defined allocation strategies When instantiated 31 | * with a user-defined class, it'll be reposible for allocating and constructing 32 | * instances and destroying and deleting them 33 | */ 34 | template class ClassMemoryAlloc { 35 | public: 36 | static void *New(unsigned int padd_); 37 | static void Delete(void *obj_); 38 | static unsigned int objectSize(); 39 | static const char *getName(); 40 | 41 | private: 42 | ClassMemoryAlloc(const ClassMemoryAlloc &right); 43 | ClassMemoryAlloc &operator=(const ClassMemoryAlloc &right); 44 | }; 45 | 46 | template inline void *ClassMemoryAlloc::New(unsigned int padd_) { 47 | #ifdef _MM_DEBUG_ 48 | #ifndef _MM_GMP_ON_ 49 | cout << " ClassMemoryAlloc::New, padd_: " << padd_ 50 | << " sizeof(W): " << sizeof(W) << endl 51 | << flush; 52 | #else 53 | fprintf(stderr, " ClassMemoryAlloc::New, padd_: %d sizeof(W): %d\n", 54 | padd_, sizeof(W)); 55 | fflush(stderr); 56 | #endif 57 | #endif 58 | 59 | #ifndef _MM_GMP_ON_ 60 | return ::new char[padd_ + sizeof(W)]; 61 | #else 62 | return (char *)::malloc(padd_ + sizeof(W)) + padd_; 63 | #endif 64 | } 65 | 66 | template inline void ClassMemoryAlloc::Delete(void *obj_) {} 67 | 68 | template inline unsigned int ClassMemoryAlloc::objectSize() { 69 | return (unsigned int)sizeof(W); 70 | } 71 | 72 | template inline const char *ClassMemoryAlloc::getName() { 73 | static const type_info &ti = typeid(W); 74 | 75 | #ifdef _MM_DEBUG_ 76 | #ifndef _MM_GMP_ON_ 77 | cout << "NAME: " << ti.name() << endl << flush; 78 | #else 79 | fprintf(stderr, "NAME: %s\n", ti.name()); 80 | #endif 81 | #endif 82 | 83 | return ti.name(); 84 | } 85 | } // namespace DaqDB 86 | -------------------------------------------------------------------------------- /lib/common/DefaultAllocStrategy.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "DefaultAllocStrategy.h" 18 | 19 | namespace DaqDB { 20 | 21 | DefaultAllocStrategy::DefaultAllocStrategy(const DefaultAllocStrategy &right) {} 22 | 23 | AllocStrategy *DefaultAllocStrategy::copy() const { 24 | return new DefaultAllocStrategy(*this); 25 | } 26 | 27 | unsigned int DefaultAllocStrategy::preallocateCount() const { 28 | return defaultPreallocCount; 29 | } 30 | 31 | unsigned int DefaultAllocStrategy::incrementQuant() const { 32 | return defaultIncCount; 33 | } 34 | 35 | unsigned int DefaultAllocStrategy::decrementQuant() const { 36 | return defaultDecCount; 37 | } 38 | 39 | unsigned int DefaultAllocStrategy::minIncQuant() const { 40 | return defaultMinIncQuant; 41 | } 42 | 43 | unsigned int DefaultAllocStrategy::maxIncQuant() const { 44 | return defaultMaxIncQuant; 45 | } 46 | 47 | unsigned int DefaultAllocStrategy::minDecQuant() const { 48 | return defaultMinDecQuant; 49 | } 50 | 51 | unsigned int DefaultAllocStrategy::maxDecQuant() const { 52 | return defaultMaxDecQuant; 53 | } 54 | } // namespace DaqDB 55 | -------------------------------------------------------------------------------- /lib/common/DefaultAllocStrategy.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include "AllocStrategy.h" 20 | 21 | namespace DaqDB { 22 | class DefaultAllocStrategy : public AllocStrategy { 23 | public: 24 | DefaultAllocStrategy() = default; 25 | virtual ~DefaultAllocStrategy() = default; 26 | virtual AllocStrategy *copy() const; 27 | virtual unsigned int preallocateCount() const; 28 | virtual unsigned int incrementQuant() const; 29 | virtual unsigned int decrementQuant() const; 30 | virtual unsigned int minIncQuant() const; 31 | virtual unsigned int maxIncQuant() const; 32 | virtual unsigned int minDecQuant() const; 33 | virtual unsigned int maxDecQuant() const; 34 | 35 | private: 36 | DefaultAllocStrategy(const DefaultAllocStrategy &right); 37 | DefaultAllocStrategy &operator=(const DefaultAllocStrategy &right); 38 | 39 | static const unsigned int defaultPreallocCount = 0; 40 | static const unsigned int defaultIncCount = 320; 41 | static const unsigned int defaultDecCount = 0; 42 | static const unsigned int defaultMinIncQuant = 4; 43 | static const unsigned int defaultMaxIncQuant = 10; 44 | static const unsigned int defaultMinDecQuant = 0; 45 | static const unsigned int defaultMaxDecQuant = 0; 46 | }; 47 | } // namespace DaqDB 48 | -------------------------------------------------------------------------------- /lib/common/GeneralPoolBase.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | #include "GeneralPoolBase.h" 21 | #include "PoolManager.h" 22 | 23 | namespace DaqDB { 24 | unsigned short GeneralPoolBase::idGener = 1; 25 | 26 | GeneralPoolBase::GeneralPoolBase(unsigned short id_, const char *name_) 27 | : stackTraceFile(0), userId(id_) { 28 | // set the id 29 | { 30 | WriteLock w_lock(generMutex); 31 | id = GeneralPoolBase::idGener++; 32 | } 33 | 34 | // set the name 35 | if (name_) { 36 | strncpy(name, name_, sizeof(name) - 1); 37 | name[sizeof(name) - 1] = '\0'; 38 | } else { 39 | name[0] = '\0'; 40 | } 41 | 42 | // initialize rttiName 43 | rttiName[0] = '\0'; 44 | 45 | // register with the PoolManager 46 | PoolManager &pm = PoolManager::getInstance(); 47 | pm.registerPool(this); 48 | } 49 | 50 | GeneralPoolBase::~GeneralPoolBase() { 51 | // unregister with the PoolManager 52 | PoolManager &pm = PoolManager::getInstance(); 53 | pm.unregisterPool(this); 54 | 55 | // close the traceStatsFile 56 | if (stackTraceFile) { 57 | fflush(stackTraceFile); 58 | fclose(stackTraceFile); 59 | } 60 | } 61 | 62 | void GeneralPoolBase::setRttiName(const char *_rttiName) { 63 | strncpy(rttiName, _rttiName, sizeof(rttiName) - 1); 64 | rttiName[sizeof(rttiName) - 1] = '\0'; 65 | } 66 | } // namespace DaqDB 67 | -------------------------------------------------------------------------------- /lib/common/GeneralPoolBase.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | 22 | typedef std::mutex Lock; 23 | typedef std::unique_lock WriteLock; 24 | typedef std::unique_lock ReadLock; 25 | 26 | namespace DaqDB { 27 | class GeneralPoolBase { 28 | public: 29 | GeneralPoolBase(unsigned short id_, const char *name_); 30 | virtual ~GeneralPoolBase(); 31 | virtual void manage() = 0; 32 | virtual void dump() = 0; 33 | virtual void stats(FILE &file_) = 0; 34 | void setRttiName(const char *_rttiName); 35 | const unsigned short getId() const; 36 | const char *getName() const; 37 | const char *getRttiName() const; 38 | const FILE *getStackTraceFile() const; 39 | void setStackTraceFile(FILE *value); 40 | const unsigned short getUserId() const; 41 | 42 | unsigned short id; 43 | char name[32]; 44 | char rttiName[128]; 45 | FILE *stackTraceFile; 46 | 47 | private: 48 | GeneralPoolBase(const GeneralPoolBase &right); 49 | GeneralPoolBase &operator=(const GeneralPoolBase &right); 50 | 51 | static unsigned short idGener; 52 | unsigned short userId; 53 | Lock generMutex; 54 | }; 55 | 56 | inline const unsigned short GeneralPoolBase::getId() const { return id; } 57 | 58 | inline const char *GeneralPoolBase::getName() const { return name; } 59 | 60 | inline const char *GeneralPoolBase::getRttiName() const { return rttiName; } 61 | 62 | inline const FILE *GeneralPoolBase::getStackTraceFile() const { 63 | return stackTraceFile; 64 | } 65 | 66 | inline void GeneralPoolBase::setStackTraceFile(FILE *value) { 67 | stackTraceFile = value; 68 | } 69 | 70 | inline const unsigned short GeneralPoolBase::getUserId() const { 71 | return userId; 72 | } 73 | } // namespace DaqDB 74 | -------------------------------------------------------------------------------- /lib/common/GeneralPoolBucket.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "GeneralPoolBucket.h" 18 | 19 | namespace DaqDB { 20 | #ifdef _MEM_STATS_ 21 | Lock gl_mem_mutex; 22 | #endif 23 | } // namespace DaqDB 24 | // namespace DaqDB 25 | -------------------------------------------------------------------------------- /lib/common/GeneralPoolBuffer.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | using namespace std; 21 | #include 22 | #include 23 | 24 | namespace DaqDB { 25 | const unsigned int MAX_BUFFER_SLOTS = 26 | 1024; // that many buffers we can have maximum 27 | const unsigned int OBJ_PADDING = 28 | sizeof(unsigned int); // each object in memory padded with that many bytes 29 | 30 | const unsigned int BUCKET_SIZE_MASK = 0x00FFFFFF; // bucket size mask 31 | const unsigned int BUCKET_NUMBER_SHIFT = 32 | 24; // bucket number is shifted by 24 bits 33 | const unsigned int BUCKET_NUMBER_MASK = 0x000000FF; // bucket number mask 34 | 35 | template class GeneralPoolBuffer { 36 | public: 37 | GeneralPoolBuffer(unsigned int bucketNum_); 38 | virtual ~GeneralPoolBuffer(); 39 | static void *operator new(size_t size); 40 | static void operator delete(void *object); 41 | void rellocate(const GeneralPoolBuffer *buf_, 42 | unsigned int howMany_); 43 | void zeroOut(unsigned int howMany_); 44 | 45 | T *slots[MAX_BUFFER_SLOTS]; 46 | unsigned int bucketNum; 47 | 48 | private: 49 | GeneralPoolBuffer(const GeneralPoolBuffer &right); 50 | GeneralPoolBuffer & 51 | operator=(const GeneralPoolBuffer &right); 52 | }; 53 | 54 | template 55 | inline GeneralPoolBuffer::GeneralPoolBuffer(unsigned int bucketNum_) 56 | : bucketNum(bucketNum_) { 57 | memset((void *)&slots[0], '\0', (size_t)(MAX_BUFFER_SLOTS * sizeof(T *))); 58 | } 59 | 60 | template 61 | inline GeneralPoolBuffer::~GeneralPoolBuffer() {} 62 | 63 | template 64 | inline void *GeneralPoolBuffer::operator new(size_t size) { 65 | #ifndef _MM_GMP_ON_ 66 | return malloc(size); 67 | #else 68 | return malloc(size); 69 | #endif 70 | } 71 | 72 | template 73 | inline void GeneralPoolBuffer::operator delete(void *object) { 74 | #ifndef _MM_GMP_ON_ 75 | free(object); 76 | #else 77 | free(object); 78 | #endif 79 | } 80 | 81 | template 82 | inline void 83 | GeneralPoolBuffer::rellocate(const GeneralPoolBuffer *buf_, 84 | unsigned int howMany_) { 85 | memcpy((void *)&slots[0], (void *)&buf_->slots[0], 86 | (size_t)(howMany_ * sizeof(T *))); 87 | } 88 | 89 | template 90 | inline void GeneralPoolBuffer::zeroOut(unsigned int howMany_) { 91 | memset((void *)slots, '\0', (size_t)(howMany_ * sizeof(T *))); 92 | } 93 | 94 | } // namespace DaqDB 95 | -------------------------------------------------------------------------------- /lib/common/GlobalMemoryAlloc.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | using namespace std; 23 | #include 24 | 25 | namespace DaqDB { 26 | template class GlobalMemoryAlloc { 27 | public: 28 | virtual ~GlobalMemoryAlloc(); 29 | static void *New(unsigned int padd_); 30 | static void Delete(void *obj_); 31 | static unsigned int objectSize(); 32 | static const char *getName(); 33 | 34 | protected: 35 | GlobalMemoryAlloc(const GlobalMemoryAlloc &right); 36 | GlobalMemoryAlloc &operator=(const GlobalMemoryAlloc &right); 37 | }; 38 | 39 | template inline GlobalMemoryAlloc::~GlobalMemoryAlloc() {} 40 | 41 | template inline void *GlobalMemoryAlloc::New(unsigned int padd_) { 42 | #ifdef _MM_DEBUG_ 43 | #ifndef _MM_GMP_ON_ 44 | cout << " GlobalMemoryAlloc::New, padd_: " << padd_ 45 | << " sizeof(Y): " << sizeof(Y) << endl 46 | << flush; 47 | #else 48 | fprintf(stderr, " GlobalMemoryAlloc::New, padd_: %d sizeof(Y): %d\n", 49 | padd_, sizeof(Y)); 50 | fflush(stderr); 51 | #endif 52 | #endif 53 | 54 | #ifndef _MM_GMP_ON_ 55 | return ::new char[padd_ + sizeof(Y)]; 56 | #else 57 | return (char *)::malloc(padd_ + sizeof(Y)) + padd_; 58 | #endif 59 | } 60 | 61 | template inline void GlobalMemoryAlloc::Delete(void *obj_) {} 62 | 63 | template inline unsigned int GlobalMemoryAlloc::objectSize() { 64 | return (unsigned int)sizeof(Y); 65 | } 66 | 67 | template inline const char *GlobalMemoryAlloc::getName() { 68 | static const type_info &ti = typeid(Y); 69 | 70 | #ifdef _MM_DEBUG_ 71 | #ifndef _MM_GMP_ON_ 72 | cout << "NAME: " << ti.name() << endl << flush; 73 | #else 74 | fprintf(stderr, "NAME: %s\n", ti.name()); 75 | #endif 76 | #endif 77 | 78 | return ti.name(); 79 | } 80 | } // namespace DaqDB 81 | -------------------------------------------------------------------------------- /lib/common/Logger.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "Logger.h" 18 | 19 | namespace DaqDB { 20 | 21 | DaqDB::Logger gLog; 22 | 23 | Logger::Logger() {} 24 | 25 | Logger::~Logger() {} 26 | 27 | void Logger::setLogFunc(const std::function &fn) { 28 | _logFunc = fn; 29 | } 30 | 31 | void Logger::log(std::string msg) { 32 | if (_logFunc) { 33 | _logFunc(msg); 34 | } 35 | } 36 | 37 | } // namespace DaqDB 38 | -------------------------------------------------------------------------------- /lib/common/Logger.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | /** @todo implement logging categories */ 20 | #define DAQ_INFO(msg) gLog.log(msg) 21 | #define DAQ_CRITICAL(msg) gLog.log(msg) 22 | #ifdef DEBUG 23 | #define DAQ_DEBUG(msg) gLog.log(msg) 24 | #else 25 | #define DAQ_DEBUG(msg) 26 | #endif 27 | 28 | #include 29 | 30 | namespace DaqDB { 31 | 32 | class Logger { 33 | public: 34 | Logger(); 35 | virtual ~Logger(); 36 | 37 | void setLogFunc(const std::function &fn); 38 | void log(std::string); 39 | 40 | private: 41 | std::function _logFunc = nullptr; 42 | }; 43 | 44 | extern DaqDB::Logger gLog; 45 | 46 | } // namespace DaqDB 47 | -------------------------------------------------------------------------------- /lib/common/Poller.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include "spdk/io_channel.h" 20 | #include "spdk/queue.h" 21 | 22 | #define DEQUEUE_RING_LIMIT 1024 23 | 24 | namespace DaqDB { 25 | 26 | template class Poller { 27 | public: 28 | Poller(bool _createBuf = true, 29 | spdk_ring_type _rsqRingType = SPDK_RING_TYPE_MP_SC) 30 | : rqstRing(0), requests(new T *[DEQUEUE_RING_LIMIT]), 31 | createBuf(_createBuf), rsqRingType(_rsqRingType) { 32 | if (createBuf == true) { 33 | rqstRing = 34 | spdk_ring_create(rsqRingType, 4096 * 4, SPDK_ENV_SOCKET_ID_ANY); 35 | } 36 | } 37 | virtual ~Poller() { 38 | spdk_ring_free(rqstRing); 39 | delete[] requests; 40 | } 41 | bool init() { 42 | if (createBuf == false) { 43 | rqstRing = 44 | spdk_ring_create(rsqRingType, 4096 * 4, SPDK_ENV_SOCKET_ID_ANY); 45 | return rqstRing ? true : false; 46 | } 47 | return true; 48 | } 49 | virtual bool enqueue(T *rqst) { 50 | size_t count = spdk_ring_enqueue(rqstRing, (void **)&rqst, 1, 0); 51 | return (count == 1); 52 | } 53 | virtual void dequeue(uint32_t cnt = DEQUEUE_RING_LIMIT) { 54 | requestCount = spdk_ring_dequeue( 55 | rqstRing, (void **)&requests[0], 56 | cnt >= DEQUEUE_RING_LIMIT ? DEQUEUE_RING_LIMIT : cnt); 57 | assert(requestCount <= 58 | (cnt >= DEQUEUE_RING_LIMIT ? DEQUEUE_RING_LIMIT : cnt)); 59 | } 60 | size_t count() { return rqstRing ? spdk_ring_count(rqstRing) : 0; } 61 | 62 | virtual void process() = 0; 63 | 64 | virtual void setRunning(int rn) {} 65 | virtual bool isOffloadRunning() { return false; } 66 | virtual void initFreeList() {} 67 | virtual uint32_t canQueue() { return 0; } 68 | 69 | struct spdk_ring *rqstRing; 70 | unsigned short requestCount = 0; 71 | T **requests; 72 | spdk_ring_type rsqRingType; 73 | bool createBuf; 74 | }; 75 | 76 | } // namespace DaqDB 77 | -------------------------------------------------------------------------------- /lib/common/PoolManager.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | using namespace std; 22 | 23 | #include "GeneralPoolBase.h" 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | typedef std::mutex Lock; 30 | typedef std::unique_lock WriteLock; 31 | typedef std::unique_lock ReadLock; 32 | 33 | namespace DaqDB { 34 | class PoolManager { 35 | public: 36 | typedef map> 37 | GeneralPoolMap; 38 | 39 | public: 40 | ~PoolManager(); 41 | static void start(PoolManager *arg); 42 | static PoolManager &getInstance(); 43 | void registerPool(GeneralPoolBase *pool_); 44 | void unregisterPool(GeneralPoolBase *pool_); 45 | void dump(); 46 | 47 | #ifdef _MEM_STATS_ 48 | char *printDateTime(const time_t &dtm); 49 | #endif 50 | 51 | private: 52 | PoolManager(); 53 | 54 | static PoolManager *instance; 55 | Lock mutex; 56 | GeneralPoolMap pools; 57 | static Lock instMutex; 58 | 59 | std::thread *collector; 60 | static const int defaultSleepInterval = 5; 61 | 62 | #ifdef _MEM_STATS_ 63 | FILE *statsFile; 64 | int statsInterval; 65 | bool statsOn; 66 | static const int defaultStatsInterval = 5; 67 | #endif 68 | }; 69 | } // namespace DaqDB 70 | -------------------------------------------------------------------------------- /lib/dht/DhtNode.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "DhtNode.h" 18 | 19 | namespace DaqDB { 20 | 21 | DhtNode::DhtNode() : state(DhtNodeState::NODE_INIT) {} 22 | 23 | } // namespace DaqDB 24 | -------------------------------------------------------------------------------- /lib/dht/DhtNode.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | namespace DaqDB { 24 | 25 | enum class DhtNodeState : std::uint8_t { 26 | NODE_INIT = 0, 27 | NODE_READY, 28 | NODE_NOT_RESPONDING 29 | }; 30 | 31 | const int ERPC_SESSION_NOT_SET = -1; 32 | 33 | /*! 34 | * Class that defines interface for DHT 35 | */ 36 | class DhtNode { 37 | public: 38 | DhtNode(); 39 | 40 | /** 41 | * @return eRPC session id for this node 42 | */ 43 | inline int getSessionId() const { return _sessionId; }; 44 | 45 | /** 46 | * @return IP address for this node 47 | */ 48 | inline const std::string &getIp() const { return _ip; }; 49 | 50 | /** 51 | * @return Port number for this node 52 | */ 53 | inline unsigned short getPort() const { return _port; }; 54 | 55 | /** 56 | * @param portOffset offset that will be added to the node port 57 | * @return URI with IP and port for this node 58 | */ 59 | inline const std::string getUri() const { 60 | return boost::str(boost::format("%1%:%2%") % getIp() % 61 | std::to_string(getPort())); 62 | }; 63 | 64 | void setIp(const std::string &ip) { _ip = ip; }; 65 | void setPort(unsigned short port) { _port = port; }; 66 | 67 | /** 68 | * @param id eRPC session id 69 | */ 70 | void setSessionId(int id) { _sessionId = id; }; 71 | 72 | inline unsigned int getStart() { return _start; } 73 | inline unsigned int getEnd() { return _end; } 74 | inline void setStart(unsigned int start) { _start = start; }; 75 | inline void setEnd(unsigned int end) { _end = end; }; 76 | 77 | std::atomic state; 78 | 79 | private: 80 | std::string _ip = ""; 81 | int _sessionId = ERPC_SESSION_NOT_SET; 82 | 83 | unsigned short _port = 0; 84 | 85 | // @TODO jradtke replace with other key mapping structures 86 | unsigned int _start = 0; 87 | unsigned int _end = 0; 88 | }; 89 | 90 | } // namespace DaqDB 91 | -------------------------------------------------------------------------------- /lib/dht/DhtServer.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include /* net/if.h (put before linux/if.h) */ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | namespace DaqDB { 32 | 33 | enum class DhtServerState : std::uint8_t { 34 | DHT_SERVER_INIT = 0, 35 | DHT_SERVER_READY, 36 | DHT_SERVER_ERROR, 37 | DHT_SERVER_STOPPED 38 | }; 39 | 40 | struct DhtServerCtx { 41 | void *rpc; 42 | KVStore *kvs; 43 | }; 44 | 45 | class DhtServer { 46 | public: 47 | DhtServer(DhtCore *dhtCore, KVStore *kvs, uint8_t numWorkerThreads = 1, 48 | uint8_t baseCoreId = 0); 49 | ~DhtServer(); 50 | 51 | /** 52 | * Prints DHT status. 53 | * @return DHT status 54 | * e.g. "DHT server: localhost:31850 55 | * DHT server: active" 56 | * 57 | */ 58 | std::string printStatus(); 59 | /** 60 | * Prints DHT neighbors. 61 | * @return string with list of peer storage nodes 62 | */ 63 | std::string printNeighbors(); 64 | 65 | void serve(void); 66 | 67 | inline unsigned int getId() { 68 | return _dhtCore->getLocalNode()->getSessionId(); 69 | } 70 | inline const std::string getIp() { 71 | return _dhtCore->getLocalNode()->getIp(); 72 | } 73 | inline unsigned int getPort() { 74 | return _dhtCore->getLocalNode()->getPort(); 75 | } 76 | 77 | std::atomic keepRunning; 78 | std::atomic state; 79 | 80 | private: 81 | void _serve(void); 82 | void _serveWorker(unsigned int workerId); 83 | 84 | erpc::Nexus *_nexus; 85 | KVStore *_kvs; 86 | DhtCore *_dhtCore; 87 | std::thread *_thread; 88 | 89 | uint8_t _workerThreadsNumber; 90 | uint8_t _baseCoreId; 91 | std::vector _workerThreads; 92 | }; 93 | 94 | } // namespace DaqDB 95 | -------------------------------------------------------------------------------- /lib/dht/DhtServerLoopback.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "DhtServer.h" 18 | #include "DhtTypes.h" 19 | #include 20 | 21 | #include "DhtServerLoopback.h" 22 | 23 | namespace DaqDB { 24 | 25 | void erpcLoopbackReqGetHandler(erpc::ReqHandle *req_handle, void *ctx) { 26 | auto serverCtx = reinterpret_cast(ctx); 27 | auto rpc = reinterpret_cast *>(serverCtx->rpc); 28 | 29 | erpc::MsgBuffer *resp = &req_handle->pre_resp_msgbuf; 30 | rpc->resize_msg_buffer(resp, sizeof(DaqdbDhtResult)); 31 | 32 | DaqdbDhtResult *result = reinterpret_cast(resp->buf); 33 | result->msgSize = 0; 34 | result->status = StatusCode::OK; 35 | 36 | rpc->enqueue_response(req_handle, resp); 37 | } 38 | 39 | void erpcLoopbackReqPutHandler(erpc::ReqHandle *req_handle, void *ctx) { 40 | auto serverCtx = reinterpret_cast(ctx); 41 | auto rpc = reinterpret_cast *>(serverCtx->rpc); 42 | 43 | erpc::MsgBuffer *resp = &req_handle->pre_resp_msgbuf; 44 | rpc->resize_msg_buffer(resp, sizeof(DaqdbDhtResult)); 45 | 46 | DaqdbDhtResult *result = reinterpret_cast(resp->buf); 47 | result->msgSize = 0; 48 | result->status = StatusCode::OK; 49 | 50 | rpc->enqueue_response(req_handle, resp); 51 | } 52 | 53 | void erpcLoopbackReqRemoveHandler(erpc::ReqHandle *req_handle, void *ctx) { 54 | auto serverCtx = reinterpret_cast(ctx); 55 | auto rpc = reinterpret_cast *>(serverCtx->rpc); 56 | 57 | erpc::MsgBuffer *resp = &req_handle->pre_resp_msgbuf; 58 | rpc->resize_msg_buffer(resp, sizeof(DaqdbDhtResult)); 59 | 60 | DaqdbDhtResult *result = reinterpret_cast(resp->buf); 61 | result->msgSize = 0; 62 | result->status = StatusCode::OK; 63 | 64 | rpc->enqueue_response(req_handle, resp); 65 | } 66 | 67 | void erpcLoopbackReqGetAnyHandler(erpc::ReqHandle *req_handle, void *ctx) { 68 | auto serverCtx = reinterpret_cast(ctx); 69 | auto rpc = reinterpret_cast *>(serverCtx->rpc); 70 | 71 | erpc::MsgBuffer *resp = &req_handle->pre_resp_msgbuf; 72 | rpc->resize_msg_buffer(resp, sizeof(DaqdbDhtResult)); 73 | 74 | DaqdbDhtResult *result = reinterpret_cast(resp->buf); 75 | result->msgSize = 0; 76 | result->status = StatusCode::OK; 77 | 78 | rpc->enqueue_response(req_handle, resp); 79 | } 80 | 81 | } // namespace DaqDB 82 | -------------------------------------------------------------------------------- /lib/dht/DhtServerLoopback.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | namespace DaqDB { 22 | void erpcLoopbackReqGetHandler(erpc::ReqHandle *req_handle, void *ctx); 23 | 24 | void erpcLoopbackReqPutHandler(erpc::ReqHandle *req_handle, void *ctx); 25 | 26 | void erpcLoopbackReqRemoveHandler(erpc::ReqHandle *req_handle, void *ctx); 27 | 28 | void erpcLoopbackReqGetAnyHandler(erpc::ReqHandle *req_handle, void *ctx); 29 | 30 | } // namespace DaqDB 31 | -------------------------------------------------------------------------------- /lib/dht/DhtTypes.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | namespace DaqDB { 22 | 23 | typedef void (*DhtContFunc)(void *appCtx, void *ioCtx); 24 | typedef std::map, DhtNode *> RangeToHost; 25 | 26 | enum class ErpRequestType : std::uint8_t { 27 | ERP_REQUEST_GET = 2, 28 | ERP_REQUEST_GETANY, 29 | ERP_REQUEST_PUT, 30 | ERP_REQUEST_REMOVE 31 | }; 32 | 33 | struct DaqdbDhtMsg { 34 | size_t keySize; 35 | size_t valSize; 36 | // Contains both key and value 37 | char msg[]; 38 | }; 39 | 40 | struct DaqdbDhtResult { 41 | StatusCode status; 42 | size_t msgSize; 43 | // Contains value for get requests 44 | char msg[]; 45 | }; 46 | } // namespace DaqDB 47 | -------------------------------------------------------------------------------- /lib/dht/DhtUtils.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "DhtUtils.h" 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | namespace DaqDB 26 | { 27 | namespace utils 28 | { 29 | 30 | unsigned short 31 | getFreePort(asio::io_service &io_service, const unsigned short backbonePort, bool reuseAddr) 32 | { 33 | auto resultPort = backbonePort; 34 | asio::ip::tcp::acceptor acceptor(io_service); 35 | std::error_code checkPortErrorCode; 36 | 37 | if (backbonePort) { 38 | acceptor.open(asio::ip::tcp::v4(), checkPortErrorCode); 39 | 40 | if (reuseAddr) { 41 | asio::socket_base::reuse_address option(true); 42 | acceptor.set_option(option); 43 | } 44 | 45 | acceptor.bind({asio::ip::tcp::v4(), resultPort}, checkPortErrorCode); 46 | acceptor.close(); 47 | } 48 | if (!backbonePort || checkPortErrorCode) { 49 | acceptor.open(asio::ip::tcp::v4(), checkPortErrorCode); 50 | acceptor.bind({asio::ip::tcp::v4(), 0}, checkPortErrorCode); 51 | resultPort = acceptor.local_endpoint().port(); 52 | acceptor.close(); 53 | } 54 | 55 | return resultPort; 56 | } 57 | 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /lib/dht/DhtUtils.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | namespace DaqDB 22 | { 23 | namespace utils 24 | { 25 | 26 | /*! 27 | * Returns free network port 28 | * @param io_service boost io service 29 | * @param backbonePort prefered port, if not used then function should 30 | * @param reuseAddr allow to reuse an address that is already in use 31 | * return it as a result 32 | */ 33 | unsigned short getFreePort(asio::io_service &io_service, 34 | const unsigned short backbonePort, 35 | bool reuseAddr = false); 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lib/offload/FinalizePoller.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "spdk/bdev.h" 28 | #include "spdk/env.h" 29 | #include "spdk/io_channel.h" 30 | #include "spdk/queue.h" 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | namespace DaqDB { 41 | 42 | typedef Poller FinPoller; 43 | 44 | class FinalizePoller : public FinPoller { 45 | public: 46 | FinalizePoller(); 47 | virtual ~FinalizePoller() = default; 48 | 49 | void process() final; 50 | 51 | enum State { FP_READY = 0, FP_QUIESCING, FP_QUIESCENT }; 52 | 53 | void Quiesce() { _state = FinalizePoller::State::FP_QUIESCING; } 54 | bool isQuiescent() { 55 | return _state == FinalizePoller::State::FP_QUIESCENT ? true : false; 56 | } 57 | 58 | protected: 59 | void _processGet(DeviceTask *task); 60 | void _processUpdate(DeviceTask *task); 61 | void _processRemove(DeviceTask *task); 62 | 63 | private: 64 | std::atomic _state; 65 | }; 66 | 67 | } // namespace DaqDB 68 | -------------------------------------------------------------------------------- /lib/offload/OffloadFreeList.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | namespace DaqDB { 26 | 27 | using pmem::obj::p; 28 | using pmem::obj::persistent_ptr; 29 | using pmem::obj::pool; 30 | using pmem::obj::pool_base; 31 | using pmem::obj::make_persistent; 32 | using pmem::obj::delete_persistent; 33 | using pmem::obj::transaction; 34 | 35 | const uint32_t numSlots = 8; 36 | 37 | class OffloadFreeList { 38 | 39 | /* entry in the list */ 40 | struct FreeLba { 41 | persistent_ptr next; 42 | p lba; 43 | }; 44 | 45 | public: 46 | OffloadFreeList() {} 47 | ~OffloadFreeList() {} 48 | 49 | void push(pool_base &pop, int64_t value); 50 | void pushBlock(pool_base &pop, int64_t value, uint32_t slot); 51 | int64_t get(pool_base &pop); 52 | int64_t getBlock(pool_base &pop, int64_t *lbas, uint32_t lbasSize, 53 | uint32_t slot); 54 | void putBlock(pool_base &pop, int64_t *lbas, uint32_t lbasSize, 55 | uint32_t slot); 56 | void clear(pool_base &pop); 57 | void clearBlock(pool_base &pop, uint32_t slot); 58 | void show(void) const; 59 | void showBlock(uint32_t slot) const; 60 | 61 | uint64_t maxLba = 0; 62 | 63 | private: 64 | 65 | persistent_ptr _head; 66 | persistent_ptr _tail; 67 | persistent_ptr _heads[numSlots]; 68 | persistent_ptr _tails[numSlots]; 69 | }; 70 | 71 | } 72 | -------------------------------------------------------------------------------- /lib/offload/OffloadLbaAlloc.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2020 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | namespace DaqDB { 20 | 21 | class OffloadLbaAlloc { 22 | public: 23 | OffloadLbaAlloc(bool create, std::string filename, uint64_t blockCnt, 24 | uint64_t avgBlkPerLba); 25 | ~OffloadLbaAlloc() = default; 26 | 27 | struct LbaBucket { 28 | LbaBucket() : level(0) {} 29 | ~LbaBucket() = default; 30 | 31 | static const uint32_t lbasSize = 1024; 32 | uint32_t sizeBracket; 33 | int64_t lbas[lbasSize]; 34 | uint32_t level; 35 | 36 | int64_t get(); 37 | void put(int64_t lba); 38 | }; 39 | 40 | int64_t getLba(size_t ioSize); 41 | void putLba(int64_t lba, size_t ioSize); 42 | 43 | protected: 44 | int64_t getBlock(LbaBucket &bucket, size_t ioSize); 45 | void putBlock(LbaBucket &bucket, size_t ioSize); 46 | 47 | private: 48 | static const uint32_t _maxBuckets = 8; 49 | LbaBucket buckets[_maxBuckets]; 50 | 51 | const char *poolLayout = "queue"; 52 | const unsigned int poolFreelistSize = 1ULL * 1024 * 1024 * 1024; 53 | const int pollMode = (S_IWUSR | S_IRUSR); 54 | pool _offloadFreeList; 55 | OffloadFreeList *freeLbaList = nullptr; 56 | }; 57 | 58 | } // namespace DaqDB 59 | -------------------------------------------------------------------------------- /lib/offload/OffloadPoller.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include "spdk/bdev.h" 30 | #include "spdk/env.h" 31 | #include "spdk/io_channel.h" 32 | #include "spdk/queue.h" 33 | 34 | #include "OffloadFreeList.h" 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | namespace DaqDB { 43 | 44 | class OffloadPoller : public Poller { 45 | public: 46 | OffloadPoller(RTreeEngine *rtree, SpdkCore *_spdkCore); 47 | virtual ~OffloadPoller(); 48 | 49 | void process() final; 50 | virtual int64_t getFreeLba(); 51 | 52 | void initFreeList(); 53 | 54 | virtual SpdkDevice *getBdev() { return spdkCore->spBdev; } 55 | virtual SpdkBdevCtx *getBdevCtx() { return spdkCore->spBdev->getBdevCtx(); } 56 | virtual spdk_bdev_desc *getBdevDesc() { 57 | return spdkCore->spBdev->getBdevCtx()->bdev_desc; 58 | } 59 | virtual spdk_io_channel *getBdevIoChannel() { 60 | return spdkCore->spBdev->getBdevCtx()->io_channel; 61 | } 62 | 63 | RTreeEngine *rtree; 64 | SpdkCore *spdkCore; 65 | 66 | OffloadFreeList *freeLbaList = nullptr; 67 | 68 | std::atomic isRunning; 69 | 70 | void signalReady(); 71 | bool waitReady(); 72 | 73 | virtual void setRunning(int rn) { isRunning = rn; } 74 | virtual bool isOffloadRunning() { return isRunning; } 75 | 76 | private: 77 | 78 | void _processGet(OffloadRqst *rqst); 79 | void _processUpdate(OffloadRqst *rqst); 80 | void _processRemove(OffloadRqst *rqst); 81 | 82 | StatusCode _getValCtx(const OffloadRqst *rqst, ValCtx &valCtx) const; 83 | 84 | inline void _rqstClb(const OffloadRqst *rqst, StatusCode status) { 85 | if (rqst->clb) 86 | rqst->clb(nullptr, status, rqst->key, rqst->keySize, nullptr, 0); 87 | } 88 | 89 | pool _offloadFreeList; 90 | 91 | const static char *pmemFreeListFilename; 92 | }; 93 | 94 | } // namespace DaqDB 95 | -------------------------------------------------------------------------------- /lib/offload/config-bdev.spdk: -------------------------------------------------------------------------------- 1 | offload_unit_alloc_size = 1024 2 | offload_dev_name = "example_offload" 3 | offload_dev_type = "bdev" 4 | offload_nvme_addr = "0000:89:00.0" 5 | offload_nvme_name = "Nvme1" 6 | 7 | -------------------------------------------------------------------------------- /lib/offload/config-jbod.spdk: -------------------------------------------------------------------------------- 1 | offload_unit_alloc_size = 1024 2 | offload_dev_name = "example_offload_jbod" 3 | offload_dev_type = "jbod" 4 | devices = { 5 | dev1 = {offload_nvme_addr = "0000:89:00.0"; offload_nvme_name = "Nvme1";}; 6 | dev2 = {offload_nvme_addr = "0000:8a:00.0"; offload_nvme_name = "Nvme2";}; 7 | dev3 = {offload_nvme_addr = "0000:8b:00.0"; offload_nvme_name = "Nvme3";}; 8 | dev4 = {offload_nvme_addr = "0000:8c:00.0"; offload_nvme_name = "Nvme4";}; 9 | }; 10 | 11 | -------------------------------------------------------------------------------- /lib/offload/config-raid0.spdk: -------------------------------------------------------------------------------- 1 | offload_unit_alloc_size = 1024 2 | offload_raid0_stripe_size = 128 3 | offload_dev_name = "example_offload_raid0" 4 | offload_dev_type = "raid0" 5 | devices = { 6 | dev1 = {offload_nvme_addr = "0000:88:00.0"; offload_nvme_name = "Nvme1";}; 7 | dev2 = {offload_nvme_addr = "0000:89:00.0"; offload_nvme_name = "Nvme2";}; 8 | dev3 = {offload_nvme_addr = "0000:8a:00.0"; offload_nvme_name = "Nvme3";}; 9 | dev4 = {offload_nvme_addr = "0000:8c:00.0"; offload_nvme_name = "Nvme4";}; 10 | }; 11 | 12 | -------------------------------------------------------------------------------- /lib/pmem/PmemPoller.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include "spdk/env.h" 24 | #include "spdk/io_channel.h" 25 | #include "spdk/queue.h" 26 | 27 | #include "../offload/OffloadPoller.h" 28 | #include "RTreeEngine.h" 29 | #include 30 | #include 31 | 32 | #define DEQUEUE_RING_LIMIT 1024 33 | 34 | namespace DaqDB { 35 | 36 | enum class RqstOperation : std::int8_t { NONE = 0, GET, PUT, UPDATE }; 37 | using PmemRqst = Rqst; 38 | 39 | class PmemPoller : public Poller { 40 | public: 41 | PmemPoller(RTreeEngine *rtree, const size_t cpuCore = 0); 42 | virtual ~PmemPoller(); 43 | 44 | void process() final; 45 | void startThread(); 46 | 47 | OffloadPoller *offloadPoller = nullptr; 48 | 49 | std::atomic isRunning; 50 | RTreeEngine *rtree; 51 | 52 | private: 53 | void _threadMain(void); 54 | 55 | void _processGet(const PmemRqst *rqst); 56 | void _processPut(const PmemRqst *rqst); 57 | void _processTransfer(const PmemRqst *rqst); 58 | 59 | inline void _rqstClb(const PmemRqst *rqst, StatusCode status) { 60 | if (rqst->clb) 61 | rqst->clb(nullptr, status, rqst->key, rqst->keySize, nullptr, 0); 62 | } 63 | inline void _rqstClb(const PmemRqst *rqst, StatusCode status, Value &val) { 64 | if (rqst->clb) 65 | rqst->clb(nullptr, status, rqst->key, rqst->keySize, val.data(), 66 | val.size()); 67 | } 68 | 69 | inline bool _valOffloaded(ValCtx &valCtx) { 70 | return valCtx.location == LOCATIONS::DISK; 71 | } 72 | inline bool _valInPmem(ValCtx &valCtx) { 73 | return valCtx.location == LOCATIONS::PMEM; 74 | } 75 | 76 | std::thread *_thread; 77 | size_t _cpuCore = 0; 78 | }; 79 | 80 | } // namespace DaqDB 81 | -------------------------------------------------------------------------------- /lib/pmem/RTreeEngine.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "RTreeEngine.h" 18 | //#include "RTree.h" 19 | #include "ARTree.h" 20 | namespace DaqDB { 21 | RTreeEngine *RTreeEngine::Open(const string &path, // path to persistent pool 22 | size_t size, size_t allocUnitSize) { 23 | // return new DaqDB::RTree(path, size, allocUnitSize); 24 | return new DaqDB::ARTree(path, size, allocUnitSize); 25 | } 26 | 27 | void RTreeEngine::Close(RTreeEngine *kv) {} // close storage engine 28 | } // namespace DaqDB 29 | -------------------------------------------------------------------------------- /lib/pmem/RTreeEngine.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include "daqdb/Status.h" 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | 31 | using std::string; 32 | using std::to_string; 33 | 34 | enum LOCATIONS { EMPTY, PMEM, DISK }; 35 | 36 | namespace DaqDB { 37 | 38 | struct PciAddr { 39 | uint32_t domain; 40 | uint8_t bus; 41 | uint8_t dev; 42 | uint8_t func; 43 | } __attribute__((packed)); 44 | 45 | inline bool operator==(const struct PciAddr &l, const struct PciAddr &r) { 46 | return l.domain == r.domain && l.bus == r.bus && l.dev == r.dev && 47 | l.func == r.func; 48 | } 49 | 50 | struct DeviceAddr { 51 | uint64_t lba; 52 | union BusAddr { 53 | uint64_t busAddr; 54 | struct PciAddr pciAddr; 55 | } busAddr __attribute__((packed)); 56 | }; 57 | 58 | class RTreeEngine { 59 | public: 60 | static RTreeEngine *Open(const string &path, // path to persistent pool 61 | size_t size, // size used when creating pool 62 | size_t allocUnitSize); // allocation unit size 63 | virtual ~RTreeEngine(){}; 64 | static void Close(RTreeEngine *kv); // close storage engine 65 | 66 | virtual string Engine() = 0; // engine identifier 67 | virtual size_t SetKeySize(size_t req_size) = 0; 68 | virtual void Get(const char *key, int32_t keybytes, void **value, 69 | size_t *size, uint8_t *location) = 0; 70 | virtual void Get(const char *key, void **value, size_t *size, 71 | uint8_t *location) = 0; 72 | virtual uint64_t GetTreeSize() = 0; 73 | virtual uint8_t GetTreeDepth() = 0; 74 | virtual uint64_t GetLeafCount() = 0; 75 | virtual void Put(const char *key, // copy value from std::string 76 | char *value) = 0; 77 | virtual void Put(const char *key, int32_t keybytes, const char *value, 78 | int32_t valuebytes) = 0; 79 | virtual void Remove(const char *key) = 0; // remove value for key 80 | virtual void AllocValueForKey(const char *key, size_t size, 81 | char **value) = 0; 82 | virtual void AllocateAndUpdateValueWrapper(const char *key, size_t size, 83 | const DeviceAddr *devAddr) = 0; 84 | }; 85 | } // namespace DaqDB 86 | -------------------------------------------------------------------------------- /lib/primary/PrimaryKeyBase.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | namespace DaqDB { 21 | 22 | static uint64_t modulo(const uint8_t *arr, int size, uint64_t div) { 23 | uint64_t val = 0; 24 | while (--size >= 0) 25 | val |= arr[size] << size; 26 | return val % div; 27 | } 28 | 29 | PrimaryKeyBase::PrimaryKeyBase(const DaqDB::Options &options) 30 | : _keySize(0), _pKeySize(0), _pKeyOffset(0) { 31 | DAQ_INFO("Initializing Primary Key Base Engine"); 32 | 33 | for (size_t i = 0; i < options.key.nfields(); i++) { 34 | if (options.key.field(i).isPrimary) { 35 | _pKeySize = options.key.field(i).size; 36 | _pKeyOffset = _keySize; 37 | } 38 | _keySize += options.key.field(i).size; 39 | } 40 | 41 | DAQ_INFO(" Total key size: " + std::to_string(_keySize)); 42 | DAQ_INFO(" Primary key size: " + std::to_string(_pKeySize)); 43 | DAQ_INFO(" Primary key offset: " + std::to_string(_pKeyOffset)); 44 | 45 | _localNodeId = options.dht.id; 46 | _nNodes = options.dht.neighbors.size(); 47 | DAQ_INFO(" Local node ID: " + std::to_string(_localNodeId)); 48 | DAQ_INFO(" Total number of nodes: " + std::to_string(_nNodes)); 49 | if (_pKeySize > sizeof(uint64_t)) 50 | throw OperationFailedException(NOT_SUPPORTED); 51 | } 52 | 53 | PrimaryKeyBase::~PrimaryKeyBase() {} 54 | 55 | void PrimaryKeyBase::dequeueNext(Key &key) { throw FUNC_NOT_SUPPORTED; } 56 | 57 | void PrimaryKeyBase::enqueueNext(const Key &Key) { 58 | // don't throw exception, just do nothing 59 | } 60 | 61 | bool PrimaryKeyBase::isLocal(const Key &key) { 62 | bool local = false; 63 | const uint8_t *pKeyPtr = 64 | reinterpret_cast(key.data() + _pKeyOffset); 65 | local = modulo(pKeyPtr, _pKeySize, _nNodes) == _localNodeId; 66 | DAQ_DEBUG("Primary key is local: " + std::to_string(local)); 67 | return local; 68 | } 69 | 70 | } // namespace DaqDB 71 | -------------------------------------------------------------------------------- /lib/primary/PrimaryKeyBase.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | namespace DaqDB { 24 | 25 | class PrimaryKeyBase : public DaqDB::PrimaryKeyEngine { 26 | public: 27 | PrimaryKeyBase(const DaqDB::Options &options); 28 | virtual ~PrimaryKeyBase(); 29 | void dequeueNext(Key &key); 30 | void enqueueNext(const Key &key); 31 | bool isLocal(const Key &key); 32 | 33 | protected: 34 | int _keySize; 35 | int _pKeySize; 36 | int _pKeyOffset; 37 | 38 | private: 39 | uint32_t _localNodeId; 40 | uint32_t _nNodes; 41 | }; 42 | 43 | } // namespace DaqDB 44 | -------------------------------------------------------------------------------- /lib/primary/PrimaryKeyEngine.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | namespace DaqDB { 24 | 25 | PrimaryKeyEngine *PrimaryKeyEngine::open(const DaqDB::Options &options) { 26 | DAQ_INFO("Initializing Primary Key Engine"); 27 | if (options.runtime.maxReadyKeys) 28 | return new DaqDB::PrimaryKeyNextQueue(options); 29 | else 30 | return new DaqDB::PrimaryKeyBase(options); 31 | } 32 | 33 | PrimaryKeyEngine::~PrimaryKeyEngine() {} 34 | 35 | } // namespace DaqDB 36 | -------------------------------------------------------------------------------- /lib/primary/PrimaryKeyEngine.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | 22 | namespace DaqDB { 23 | 24 | class PrimaryKeyEngine { 25 | public: 26 | static PrimaryKeyEngine *open(const DaqDB::Options &options); 27 | virtual ~PrimaryKeyEngine(); 28 | virtual void dequeueNext(Key &key) = 0; 29 | virtual void enqueueNext(const Key &key) = 0; 30 | virtual bool isLocal(const Key &key) = 0; 31 | }; 32 | } // namespace DaqDB 33 | -------------------------------------------------------------------------------- /lib/primary/PrimaryKeyNextQueue.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "spdk/bdev.h" 18 | #include "spdk/env.h" 19 | #include "spdk/queue.h" 20 | #include "spdk/thread.h" 21 | 22 | #include 23 | #include 24 | 25 | namespace DaqDB { 26 | 27 | PrimaryKeyNextQueue::PrimaryKeyNextQueue(const DaqDB::Options &options) 28 | : PrimaryKeyBase(options) { 29 | DAQ_INFO("Initializing NextQueue for primary keys of size " + 30 | std::to_string(options.runtime.maxReadyKeys)); 31 | _readyKeys = 32 | spdk_ring_create(SPDK_RING_TYPE_MP_MC, options.runtime.maxReadyKeys, 33 | SPDK_ENV_SOCKET_ID_ANY); 34 | if (!_readyKeys) { 35 | DAQ_CRITICAL("Cannnot create SPDK ring for ready keys"); 36 | throw OperationFailedException(SPDK_ALLOCATION_ERROR); 37 | } 38 | } 39 | 40 | PrimaryKeyNextQueue::~PrimaryKeyNextQueue() { 41 | char *pKeyBuff; 42 | while ( 43 | spdk_ring_dequeue(_readyKeys, reinterpret_cast(&pKeyBuff), 1)) 44 | delete[] pKeyBuff; 45 | spdk_ring_free(_readyKeys); 46 | } 47 | 48 | char *PrimaryKeyNextQueue::_createPKeyBuff(const char *srcKeyBuff) { 49 | char *pKeyBuff = new char[_pKeySize]; 50 | std::memcpy(pKeyBuff, srcKeyBuff + _pKeyOffset, _pKeySize); 51 | return pKeyBuff; 52 | } 53 | 54 | void PrimaryKeyNextQueue::dequeueNext(Key &key) { 55 | char *pKeyBuff; 56 | int cnt = 57 | spdk_ring_dequeue(_readyKeys, reinterpret_cast(&pKeyBuff), 1); 58 | if (!cnt) 59 | throw OperationFailedException(Status(KEY_NOT_FOUND)); 60 | std::memset(key.data(), 0, _keySize); 61 | std::memcpy(key.data() + _pKeyOffset, pKeyBuff, _pKeySize); 62 | delete[] pKeyBuff; 63 | } 64 | 65 | void PrimaryKeyNextQueue::enqueueNext(const Key &key) { 66 | if (!isLocal(key)) 67 | return; 68 | char *pKeyBuff = _createPKeyBuff(key.data()); 69 | int cnt = 70 | spdk_ring_enqueue(_readyKeys, reinterpret_cast(&pKeyBuff), 1, 0); 71 | if (!cnt) { 72 | delete[] pKeyBuff; 73 | throw OperationFailedException(QUEUE_FULL_ERROR); 74 | } 75 | } 76 | 77 | } // namespace DaqDB 78 | -------------------------------------------------------------------------------- /lib/primary/PrimaryKeyNextQueue.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | namespace DaqDB { 24 | 25 | class PrimaryKeyNextQueue : public DaqDB::PrimaryKeyBase { 26 | public: 27 | PrimaryKeyNextQueue(const DaqDB::Options &options); 28 | virtual ~PrimaryKeyNextQueue(); 29 | void dequeueNext(Key &key); 30 | void enqueueNext(const Key &key); 31 | 32 | private: 33 | char *_createPKeyBuff(const char *srcKeyBuff); 34 | 35 | struct spdk_ring *_readyKeys; 36 | }; 37 | 38 | } // namespace DaqDB 39 | -------------------------------------------------------------------------------- /lib/spdk/BdevStats.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include "BdevStats.h" 25 | 26 | namespace DaqDB { 27 | 28 | /* 29 | * BdevStats 30 | */ 31 | std::ostringstream &BdevStats::formatWriteBuf(std::ostringstream &buf, 32 | const char *bdev_addr) { 33 | buf << "bdev_addr[" << bdev_addr << "] write_compl_cnt[" << write_compl_cnt 34 | << "] write_err_cnt[" << write_err_cnt << "] outs_io_cnt[" 35 | << outstanding_io_cnt << "]"; 36 | return buf; 37 | } 38 | 39 | std::ostringstream &BdevStats::formatReadBuf(std::ostringstream &buf, 40 | const char *bdev_addr) { 41 | buf << "bdev_addr[" << bdev_addr << "] read_compl_cnt[" << read_compl_cnt 42 | << "] read_err_cnt[" << read_err_cnt << "] outs_io_cnt[" 43 | << outstanding_io_cnt << "]"; 44 | return buf; 45 | } 46 | 47 | void BdevStats::printWritePer(std::ostream &os, const char *bdev_addr) { 48 | if (!(write_compl_cnt % quant_per)) { 49 | std::ostringstream buf; 50 | char time_buf[128]; 51 | time_t now = time(0); 52 | strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S.000", 53 | localtime(&now)); 54 | os << formatWriteBuf(buf, bdev_addr).str() << " " << time_buf 55 | << std::endl; 56 | } 57 | } 58 | 59 | void BdevStats::printReadPer(std::ostream &os, const char *bdev_addr) { 60 | if (!(read_compl_cnt % quant_per)) { 61 | std::ostringstream buf; 62 | char time_buf[128]; 63 | time_t now = time(0); 64 | strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S.000", 65 | localtime(&now)); 66 | os << formatReadBuf(buf, bdev_addr).str() << " " << time_buf 67 | << std::endl; 68 | } 69 | } 70 | 71 | } // namespace DaqDB 72 | -------------------------------------------------------------------------------- /lib/spdk/BdevStats.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include "spdk/bdev.h" 25 | 26 | #include "Rqst.h" 27 | #include "SpdkConf.h" 28 | #include "SpdkDevice.h" 29 | #include 30 | #include 31 | 32 | namespace DaqDB { 33 | 34 | struct BdevStats { 35 | uint64_t write_compl_cnt; 36 | uint64_t write_err_cnt; 37 | uint64_t read_compl_cnt; 38 | uint64_t read_err_cnt; 39 | bool periodic = true; 40 | uint64_t quant_per = (1 << 18); 41 | uint64_t outstanding_io_cnt; 42 | 43 | BdevStats() 44 | : write_compl_cnt(0), write_err_cnt(0), read_compl_cnt(0), 45 | read_err_cnt(0), outstanding_io_cnt(0) {} 46 | std::ostringstream &formatWriteBuf(std::ostringstream &buf, 47 | const char *bdev_addr); 48 | std::ostringstream &formatReadBuf(std::ostringstream &buf, 49 | const char *bdev_addr); 50 | void printWritePer(std::ostream &os, const char *bdev_addr); 51 | void printReadPer(std::ostream &os, const char *bdev_addr); 52 | }; 53 | 54 | } // namespace DaqDB 55 | -------------------------------------------------------------------------------- /lib/spdk/SpdkBdevFactory.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | #include 20 | 21 | #include "SpdkBdev.h" 22 | #include "SpdkBdevFactory.h" 23 | #include "SpdkConf.h" 24 | #include "SpdkDevice.h" 25 | #include "SpdkJBODBdev.h" 26 | #include "SpdkRAID0Bdev.h" 27 | #include 28 | 29 | namespace DaqDB { 30 | 31 | SpdkDevice *SpdkBdevFactory::getBdev(SpdkDeviceClass typ) { 32 | switch (typ) { 33 | case SpdkDeviceClass::BDEV: 34 | return new SpdkBdev; 35 | break; // never reached 36 | case SpdkDeviceClass::JBOD: 37 | return new SpdkJBODBdev; 38 | break; // never reached 39 | case SpdkDeviceClass::RAID0: 40 | return new SpdkRAID0Bdev; 41 | break; // never reached 42 | } 43 | return 0; 44 | } 45 | 46 | } // namespace DaqDB 47 | -------------------------------------------------------------------------------- /lib/spdk/SpdkBdevFactory.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include "Rqst.h" 20 | #include "SpdkBdev.h" 21 | #include "SpdkConf.h" 22 | #include "SpdkDevice.h" 23 | #include "SpdkJBODBdev.h" 24 | #include "SpdkRAID0Bdev.h" 25 | 26 | namespace DaqDB { 27 | 28 | class SpdkBdevFactory { 29 | public: 30 | SpdkBdevFactory() = default; 31 | ~SpdkBdevFactory() = default; 32 | 33 | static SpdkDevice *getBdev(SpdkDeviceClass typ); 34 | }; 35 | 36 | } // namespace DaqDB 37 | -------------------------------------------------------------------------------- /lib/spdk/SpdkConf.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | 23 | #include "SpdkConf.h" 24 | 25 | namespace DaqDB { 26 | 27 | SpdkConf::SpdkConf(const OffloadOptions &_offloadOptions) 28 | : _devType(_offloadOptions.devType), _name(_offloadOptions.name), 29 | _raid0StripeSize(_offloadOptions.raid0StripeSize), _bdev(0), 30 | _bdevNum(-1) { 31 | copyDevs(_offloadOptions._devs); 32 | } 33 | 34 | SpdkConf::SpdkConf(SpdkConfDevType devType, std::string name, 35 | size_t raid0StripeSize) 36 | : _devType(devType), _name(name), _raid0StripeSize(raid0StripeSize) {} 37 | 38 | struct PciAddr SpdkConf::parsePciAddr(const std::string &nvmeAddr) { 39 | struct PciAddr addr; 40 | int ret = sscanf(nvmeAddr.c_str(), "%x:%X:%X.%X", &addr.domain, &addr.bus, 41 | &addr.dev, &addr.func); 42 | if (ret != 4) 43 | memset(&addr, 0xff, sizeof(addr)); 44 | return addr; 45 | } 46 | 47 | void SpdkConf::copyDevs(const std::vector &_offloadDevs) { 48 | for (auto d : _offloadDevs) { 49 | _devs.push_back(SpdkBdevConf{d.devName, d.nvmeAddr, 50 | parsePciAddr(d.nvmeAddr), d.nvmeName}); 51 | } 52 | } 53 | 54 | const std::string &SpdkConf::getBdevNvmeName() const { 55 | return _devs[0].nvmeName; 56 | } 57 | 58 | const std::string &SpdkConf::getBdevNvmeAddr() const { 59 | return _devs[0].nvmeAddr; 60 | } 61 | 62 | struct PciAddr SpdkConf::getBdevSpdkPciAddr() const { 63 | return _devs[0].pciAddr; 64 | } 65 | 66 | SpdkConf &SpdkConf::operator=(const SpdkConf &_r) { 67 | if (this == &_r) 68 | return *this; 69 | this->_devType = _r._devType; 70 | this->_name = _r._name; 71 | this->_devs = _r._devs; 72 | this->_bdevNum = _r._bdevNum; 73 | return *this; 74 | } 75 | 76 | void SpdkConf::addDev(SpdkBdevConf dev) { _devs.push_back(dev); } 77 | 78 | } // namespace DaqDB 79 | -------------------------------------------------------------------------------- /lib/spdk/SpdkConf.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include "RTreeEngine.h" 20 | 21 | namespace DaqDB { 22 | 23 | typedef OffloadDevType SpdkConfDevType; 24 | 25 | struct SpdkBdevConf { 26 | std::string devName = ""; 27 | std::string nvmeAddr = ""; 28 | struct PciAddr pciAddr; 29 | std::string nvmeName = ""; 30 | }; 31 | 32 | /* 33 | * Encapsulates Spdk config 34 | */ 35 | class SpdkConf { 36 | public: 37 | SpdkConf(const OffloadOptions &_offloadOptions); 38 | SpdkConf(SpdkConfDevType devType, std::string name, size_t raid0StripeSize); 39 | ~SpdkConf() = default; 40 | 41 | SpdkConf &operator=(const SpdkConf &_r); 42 | 43 | struct PciAddr parsePciAddr(const std::string &nvmeAddr); 44 | void copyDevs(const std::vector &_offloadDevs); 45 | 46 | const std::string &getBdevNvmeName() const; 47 | const std::string &getBdevNvmeAddr() const; 48 | struct PciAddr getBdevSpdkPciAddr() const; 49 | 50 | SpdkConfDevType getSpdkConfDevType() const { return _devType; } 51 | void setSpdkConfDevType(SpdkConfDevType devType) { _devType = devType; } 52 | std::string getName() { return _name; } 53 | void setName(std::string &name) { _name = name; } 54 | size_t getRaid0StripeSize() { return _raid0StripeSize; } 55 | void setRaid0StripeSize(size_t raid0StripeSize) { 56 | _raid0StripeSize = raid0StripeSize; 57 | } 58 | struct spdk_bdev *getBdev() const { 59 | return _bdev; 60 | } 61 | void setBdev(struct spdk_bdev *bdev) { _bdev = bdev; } 62 | const std::vector &getDevs() const { return _devs; } 63 | void addDev(SpdkBdevConf dev); 64 | int getBdevNum() const { return _bdevNum; } 65 | void setBdevNum(int bdevNum) { _bdevNum = bdevNum; } 66 | 67 | private: 68 | SpdkConfDevType _devType; 69 | std::string _name; 70 | size_t _raid0StripeSize; 71 | std::vector _devs; 72 | struct spdk_bdev *_bdev; 73 | int _bdevNum; 74 | }; 75 | 76 | } // namespace DaqDB 77 | -------------------------------------------------------------------------------- /lib/spdk/SpdkCore.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | namespace DaqDB { 20 | 21 | const std::string SPDK_APP_ENV_NAME = "DaqDB"; 22 | const std::string DEFAULT_SPDK_CONF_FILE = "spdk.conf"; 23 | 24 | enum class SpdkState : std::uint8_t { 25 | SPDK_INIT = 0, 26 | SPDK_READY, 27 | SPDK_ERROR, 28 | SPDK_STOPPED 29 | }; 30 | 31 | using namespace std; 32 | namespace bf = boost::filesystem; 33 | 34 | class SpdkCore { 35 | public: 36 | SpdkCore(OffloadOptions _offloadOptions); 37 | ~SpdkCore(); 38 | 39 | /** 40 | * SPDK requires passing configuration through file. 41 | * This function creates temporary configuration file 42 | * in format supported by SPDK. 43 | * 44 | * @return false when cannot create the file or there are no NVMe devices in 45 | * _offloadOptions, true otherwise 46 | */ 47 | bool createConfFile(void); 48 | void removeConfFile(void); 49 | bool isOffloadEnabled() { 50 | if (state == SpdkState::SPDK_READY) 51 | return spBdev->isOffloadEnabled(); 52 | else 53 | return false; 54 | } 55 | bool spdkEnvInit(void); 56 | SpdkDevice *getBdev(void) { return spBdev; } 57 | bool isSpdkReady() { 58 | return state == SpdkState::SPDK_READY ? true : false; 59 | } 60 | bool isBdevFound() { 61 | return state == SpdkState::SPDK_READY && spBdev->isBdevFound() == true; 62 | } 63 | void restoreSignals(); 64 | 65 | std::atomic state; 66 | SpdkDevice *spBdev; 67 | OffloadOptions offloadOptions; 68 | Poller *poller; 69 | 70 | const static char *spdkHugepageDirname; 71 | 72 | void signalReady(); 73 | bool waitReady(); 74 | void setPoller(Poller *pol) { poller = pol; } 75 | static int spdkCoreMainLoop(SpdkCore *spdkCore); 76 | 77 | /* 78 | * Callback function called by SPDK spdk_app_start in the context of an SPDK 79 | * thread. 80 | */ 81 | static void spdkStart(void *arg); 82 | void startSpdk(); 83 | 84 | private: 85 | std::thread *_spdkThread; 86 | std::thread *_loopThread; 87 | bool _ready; 88 | 89 | size_t _cpuCore; 90 | SpdkConf _spdkConf; 91 | std::string _confFile; 92 | 93 | std::mutex _syncMutex; 94 | std::condition_variable _cv; 95 | 96 | inline bool isNvmeInOptions() { 97 | return offloadOptions._devs.size() ? true : false; 98 | } 99 | inline std::string getName() { return offloadOptions.name; } 100 | 101 | void _spdkThreadMain(void); 102 | }; 103 | 104 | } // namespace DaqDB 105 | -------------------------------------------------------------------------------- /lib/spdk/SpdkIoEngine.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "spdk/conf.h" 26 | #include "spdk/cpuset.h" 27 | #include "spdk/env.h" 28 | #include "spdk/event.h" 29 | #include "spdk/ftl.h" 30 | #include "spdk/log.h" 31 | #include "spdk/queue.h" 32 | #include "spdk/stdinc.h" 33 | #include "spdk/thread.h" 34 | 35 | #include "BdevStats.h" 36 | #include "SpdkBdev.h" 37 | #include "SpdkIoEngine.h" 38 | #include 39 | #include 40 | 41 | namespace DaqDB { 42 | 43 | SpdkIoEngine::SpdkIoEngine() : Poller(true, SPDK_RING_TYPE_SP_SC) {} 44 | 45 | void SpdkIoEngine::process() { 46 | if (requestCount > 0) { 47 | for (unsigned short RqstIdx = 0; RqstIdx < requestCount; RqstIdx++) { 48 | DeviceTask *task = requests[RqstIdx]; 49 | task->routing = false; 50 | SpdkBdev *bdev = reinterpret_cast(task->bdev); 51 | switch (task->op) { 52 | case OffloadOperation::GET: { 53 | bool ret = bdev->read(task); 54 | if (ret != true) { 55 | rqstClb(task->rqst, StatusCode::UNKNOWN_ERROR); 56 | OffloadRqst::getPool.put(task->rqst); 57 | } 58 | } break; 59 | case OffloadOperation::UPDATE: { 60 | bool ret = bdev->write(task); 61 | if (ret != true) { 62 | rqstClb(task->rqst, StatusCode::UNKNOWN_ERROR); 63 | OffloadRqst::updatePool.put(task->rqst); 64 | } 65 | } break; 66 | case OffloadOperation::REMOVE: { 67 | bool ret = bdev->remove(task); 68 | if (ret != true) { 69 | rqstClb(task->rqst, StatusCode::UNKNOWN_ERROR); 70 | OffloadRqst::removePool.put(task->rqst); 71 | } 72 | } break; 73 | default: 74 | break; 75 | } 76 | } 77 | requestCount = 0; 78 | } 79 | } 80 | 81 | } // namespace DaqDB 82 | -------------------------------------------------------------------------------- /lib/spdk/SpdkIoEngine.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SpdkIoEngine.h 3 | * 4 | * Created on: Dec 17, 2019 5 | * Author: parallels 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "spdk/bdev.h" 19 | #include "spdk/env.h" 20 | #include "spdk/io_channel.h" 21 | #include "spdk/queue.h" 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | namespace DaqDB { 28 | 29 | class OffloadPoller; 30 | 31 | class SpdkIoEngine : public Poller { 32 | public: 33 | SpdkIoEngine(); 34 | virtual ~SpdkIoEngine() = default; 35 | 36 | void process() final; 37 | inline void rqstClb(const OffloadRqst *rqst, StatusCode status) { 38 | if (rqst->clb) 39 | rqst->clb(nullptr, status, rqst->key, rqst->keySize, nullptr, 0); 40 | } 41 | }; 42 | 43 | } // namespace DaqDB 44 | -------------------------------------------------------------------------------- /lib/spdk/SpdkRAID0Bdev.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "SpdkRAID0Bdev.h" 18 | #include 19 | 20 | namespace DaqDB { 21 | 22 | SpdkDeviceClass SpdkRAID0Bdev::bdev_class = SpdkDeviceClass::RAID0; 23 | 24 | SpdkRAID0Bdev::SpdkRAID0Bdev() : isRunning(0) {} 25 | 26 | bool SpdkRAID0Bdev::read(DeviceTask *task) { return true; } 27 | 28 | bool SpdkRAID0Bdev::write(DeviceTask *task) { return true; } 29 | 30 | bool SpdkRAID0Bdev::remove(DeviceTask *task) { return true; } 31 | 32 | int SpdkRAID0Bdev::reschedule(DeviceTask *task) { return 0; } 33 | 34 | void SpdkRAID0Bdev::deinit() {} 35 | 36 | bool SpdkRAID0Bdev::init(const SpdkConf &conf) { return true; } 37 | 38 | void SpdkRAID0Bdev::initFreeList() {} 39 | 40 | int64_t SpdkRAID0Bdev::getFreeLba(size_t ioSize) { return -1; } 41 | 42 | void SpdkRAID0Bdev::putFreeLba(const DeviceAddr *devAddr, size_t ioSize) {} 43 | 44 | void SpdkRAID0Bdev::enableStats(bool en) {} 45 | 46 | void SpdkRAID0Bdev::setMaxQueued(uint32_t io_cache_size, uint32_t blk_size) { 47 | IoBytesMaxQueued = io_cache_size * 128; 48 | } 49 | 50 | } // namespace DaqDB 51 | -------------------------------------------------------------------------------- /lib/spdk/SpdkRAID0Bdev.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include "spdk/bdev.h" 24 | 25 | #include "Rqst.h" 26 | #include "SpdkConf.h" 27 | #include "SpdkDevice.h" 28 | #include 29 | #include 30 | 31 | namespace DaqDB { 32 | 33 | class SpdkRAID0Bdev : public SpdkDevice { 34 | public: 35 | SpdkRAID0Bdev(void); 36 | ~SpdkRAID0Bdev() = default; 37 | 38 | /** 39 | * Initialize RAID0 devices. 40 | * 41 | * @return if this RAID0 devices successfully configured and opened, false 42 | * otherwise 43 | */ 44 | virtual bool init(const SpdkConf &conf); 45 | virtual void deinit(); 46 | virtual void initFreeList(); 47 | virtual int64_t getFreeLba(size_t ioSize); 48 | virtual void putFreeLba(const DeviceAddr *devAddr, size_t ioSize); 49 | 50 | /* 51 | * SpdkDevice virtual interface 52 | */ 53 | virtual bool read(DeviceTask *task); 54 | virtual bool write(DeviceTask *task); 55 | virtual bool remove(DeviceTask *task); 56 | virtual int reschedule(DeviceTask *task); 57 | 58 | virtual void enableStats(bool en); 59 | virtual size_t getOptimalSize(size_t size) { return 0; } 60 | virtual size_t getAlignedSize(size_t size) { return 0; } 61 | virtual uint32_t getSizeInBlk(size_t &size) { return 0; } 62 | virtual void setReady() {} 63 | virtual bool isOffloadEnabled() { return true; } 64 | virtual bool isBdevFound() { return true; } 65 | virtual void IOQuiesce() {} 66 | virtual bool isIOQuiescent() { return true; } 67 | virtual void IOAbort() {} 68 | virtual uint32_t canQueue() { return 1024; } 69 | virtual SpdkBdevCtx *getBdevCtx() { return &spBdevCtx; } 70 | virtual uint64_t getBlockOffsetForLba(uint64_t lba) { 71 | return lba * blkNumForLba; 72 | } 73 | virtual void setBlockNumForLba(uint64_t blk_num_flba) { 74 | blkNumForLba = blk_num_flba; 75 | } 76 | virtual void setMaxQueued(uint32_t io_cache_size, uint32_t blk_size); 77 | virtual uint32_t getBlockSize() { return spBdevCtx.blk_size; } 78 | virtual uint32_t getIoPoolSize() { return spBdevCtx.io_pool_size; } 79 | virtual uint32_t getIoCacheSize() { return spBdevCtx.io_cache_size; } 80 | virtual void setRunning(int running) { isRunning = running; } 81 | virtual bool IsRunning(int running) { return isRunning; } 82 | 83 | static SpdkDeviceClass bdev_class; 84 | 85 | private: 86 | std::atomic isRunning; 87 | }; 88 | 89 | } // namespace DaqDB 90 | -------------------------------------------------------------------------------- /scripts/autogen_isal.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | OLD_PATH=$PATH 4 | PATH=/usr/bin:$PATH 5 | autoreconf --install --symlink -f 6 | PATH=$OLD_PATH 7 | 8 | libdir() { 9 | echo $(cd $1/$(gcc -print-multi-os-directory); pwd) 10 | } 11 | 12 | args="--prefix=/usr --libdir=$(libdir /usr/lib)" 13 | 14 | echo 15 | echo "----------------------------------------------------------------" 16 | echo "Initialized build system. For a common configuration please run:" 17 | echo "----------------------------------------------------------------" 18 | echo 19 | echo "./configure $args" 20 | echo 21 | -------------------------------------------------------------------------------- /scripts/githooks/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | import subprocess 5 | 6 | script_path = os.path.dirname(os.path.abspath(__file__)) 7 | git_clang_format = os.path.join(script_path, 'git-clang-format') 8 | print git_clang_format 9 | 10 | output = subprocess.check_output([git_clang_format, "--diff"]) 11 | 12 | if output not in ['no modified files to format\n', 'clang-format did not modify any files\n']: 13 | print "Correct issues reported by scripts/githooks/git-clang-format --diff, then commit.\n" 14 | exit(1) 15 | else: 16 | print "No clang-format issues detected.\n" 17 | exit(0) 18 | -------------------------------------------------------------------------------- /scripts/libspdk.mri: -------------------------------------------------------------------------------- 1 | create libspdk.a 2 | addlib build/lib/libspdk_app_rpc.a 3 | addlib build/lib/libspdk_bdev.a 4 | addlib build/lib/libspdk_bdev_error.a 5 | addlib build/lib/libspdk_bdev_gpt.a 6 | addlib build/lib/libspdk_bdev_lvol.a 7 | addlib build/lib/libspdk_bdev_malloc.a 8 | addlib build/lib/libspdk_bdev_null.a 9 | addlib build/lib/libspdk_bdev_nvme.a 10 | addlib build/lib/libspdk_bdev_passthru.a 11 | addlib build/lib/libspdk_bdev_rpc.a 12 | addlib build/lib/libspdk_bdev_split.a 13 | addlib build/lib/libspdk_bdev_virtio.a 14 | addlib build/lib/libspdk_blob.a 15 | addlib build/lib/libspdk_blob_bdev.a 16 | addlib build/lib/libspdk_blobfs.a 17 | addlib build/lib/libspdk_conf.a 18 | addlib build/lib/libspdk_copy.a 19 | addlib build/lib/libspdk_copy_ioat.a 20 | addlib build/lib/libspdk_env_dpdk.a 21 | addlib build/lib/libspdk_vmd.a 22 | addlib build/lib/libspdk_notify.a 23 | addlib build/lib/libspdk_ftl.a 24 | addlib build/lib/libspdk_event.a 25 | addlib build/lib/libspdk_event_bdev.a 26 | addlib build/lib/libspdk_event_copy.a 27 | addlib build/lib/libspdk_event_nbd.a 28 | addlib build/lib/libspdk_event_net.a 29 | addlib build/lib/libspdk_event_nvmf.a 30 | addlib build/lib/libspdk_event_scsi.a 31 | addlib build/lib/libspdk_event_vhost.a 32 | addlib build/lib/libspdk_event_vmd.a 33 | addlib build/lib/libspdk_ioat.a 34 | addlib build/lib/libspdk_json.a 35 | addlib build/lib/libspdk_jsonrpc.a 36 | addlib build/lib/libspdk_log.a 37 | addlib build/lib/libspdk_log_rpc.a 38 | addlib build/lib/libspdk_lvol.a 39 | addlib build/lib/libspdk_nbd.a 40 | addlib build/lib/libspdk_net.a 41 | addlib build/lib/libspdk_nvme.a 42 | addlib build/lib/libspdk_nvmf.a 43 | addlib build/lib/libspdk_rpc.a 44 | addlib build/lib/libspdk_scsi.a 45 | addlib build/lib/libspdk_sock.a 46 | addlib build/lib/libspdk_thread.a 47 | addlib build/lib/libspdk_trace.a 48 | addlib build/lib/libspdk_util.a 49 | addlib build/lib/libspdk_vhost.a 50 | addlib build/lib/libspdk_virtio.a 51 | addlib isa-l/.libs/libisal.a 52 | save 53 | create libdpdk.a 54 | addlib dpdk/build/lib/librte_bus_pci.a 55 | addlib dpdk/build/lib/librte_bus_vdev.a 56 | addlib dpdk/build/lib/librte_eal.a 57 | addlib dpdk/build/lib/librte_ethdev.a 58 | addlib dpdk/build/lib/librte_kvargs.a 59 | addlib dpdk/build/lib/librte_mbuf.a 60 | addlib dpdk/build/lib/librte_mempool.a 61 | addlib dpdk/build/lib/librte_mempool_bucket.a 62 | addlib dpdk/build/lib/librte_mempool_ring.a 63 | addlib dpdk/build/lib/librte_net.a 64 | addlib dpdk/build/lib/librte_pci.a 65 | addlib dpdk/build/lib/librte_ring.a 66 | addlib dpdk/build/lib/librte_vhost.a 67 | addlib dpdk/build/lib/librte_hash.a 68 | addlib dpdk/build/lib/librte_cryptodev.a 69 | addlib dpdk/build/lib/librte_cmdline.a 70 | addlib dpdk/build/lib/librte_meter.a 71 | addlib dpdk/build/lib/librte_compressdev.a 72 | save 73 | end 74 | -------------------------------------------------------------------------------- /scripts/minidaq_run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Example script to run minidaq benchmark. Assumes root privileges. 4 | 5 | # Input arguments 6 | test_time=800 7 | ramp_time=200 8 | iter_time=10 9 | prefix=nth 10 | ncores=17 11 | fogkv_dir=~/FogKV 12 | fogkv_psize=10737418240 13 | fogkv_pfile=/mnt/pmem/fogkv_minidaq.pm 14 | fogkv_poolers=0 15 | fogkv_base_core_id=1 16 | minidaq_iter_arg="--n-ro" 17 | minidaq_node_args="--fragment-size 1024" 18 | iters=(2 4 8 16) 19 | dry_run=0 20 | 21 | # Internal variables 22 | work_dir=`pwd` 23 | results_file=$work_dir/summary.csv 24 | env_file=$work_dir/env.log 25 | minidaq_fogkv_args="--time-test $test_time --time-iter $iter_time --time-ramp $ramp_time\ 26 | --pmem-size $fogkv_psize --n-poolers $fogkv_poolers --base-core-id $fogkv_base_core_id\ 27 | --n-cores $ncores" 28 | minidaq_args="$minidaq_args $minidaq_fogkv_args $minidaq_node_args --out-summary $results_file" 29 | 30 | echo -e "#######################################" 31 | echo -e "########## MINIDAQ BENCHMARK ##########" 32 | echo -e "#######################################" 33 | 34 | # Dump configuration 35 | date=$(date '+%Y%m%d_%H%M%S') 36 | cd $fogkv_dir 37 | echo "System date: $date" > $env_file 38 | echo "Git commit: `git rev-parse HEAD`" >> $env_file 39 | echo "Git tag: `git describe --tags 2> /dev/null`" >> $env_file 40 | cd $work_dir 41 | echo "##### Filesystems #####" >> $env_file 42 | df -h >> $env_file 43 | echo "##### Memory #####" >> $env_file 44 | cat /proc/meminfo >> $env_file 45 | echo "##### CPU #####" >> $env_file 46 | cat /proc/cpuinfo >> $env_file 47 | echo "##### boot #####" >> $env_file 48 | cat /etc/default/grub >> $env_file 49 | echo "##### kernel #####" >> $env_file 50 | uname -a >> $env_file 51 | 52 | # Configure environment 53 | echo -e "[$date] setting environment..." 54 | rm -f *.csv 55 | . $fogkv_dir/scripts/setup_env_lcg.sh 56 | cd $fogkv_dir/bin 57 | export PMEM_IS_PMEM_FORCE=1 58 | export PMEM_NO_FLUSH=1 59 | export PMEMOBJ_CONF="prefault.at_open=1;prefault.at_create=1" 60 | echo "##### environment #####" >> $env_file 61 | printenv >> $env_file 62 | 63 | echo -e "[$date] done\n" 64 | 65 | # Run tests 66 | echo -e "[$date] starting...\n" 67 | echo "##### minidaq #####" >> $env_file 68 | 69 | for i in `seq 0 $((${#iters[*]} - 1))`; do 70 | date=$(date '+%Y%m%d_%H%M%S') 71 | echo -e "[$date] $prefix ${iters[$i]}" 72 | rm -rf $fogkv_pfile 2> /dev/null 73 | test_name=${iters[$i]} 74 | iteration_dir=$work_dir/$prefix${iters[$i]} 75 | args="$minidaq_args --out-prefix $iteration_dir --test-name ${iters[$i]}" 76 | args="$args $minidaq_iter_arg ${iters[$i]}" 77 | echo "./minidaq $args" >> $env_file 78 | if [ $dry_run -ne 0 ] 79 | then 80 | echo "[$date] ./minidaq $args" 81 | else 82 | ./minidaq $args 83 | fi 84 | 85 | echo -e "\n" 86 | done 87 | 88 | cd $work_dir 89 | echo -e "[$date] done" 90 | -------------------------------------------------------------------------------- /scripts/patch_spdk_isal.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | SCRIPT=$(readlink -f $0) 4 | SCRIPTPATH=`dirname $SCRIPT` 5 | 6 | cp $SCRIPTPATH/autogen_isal.sh $SCRIPTPATH/../third-party/spdk/isa-l/autogen.sh 7 | -------------------------------------------------------------------------------- /scripts/pkgdep.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Please run this script as root. 3 | 4 | SYSTEM=`uname -s` 5 | 6 | if [ -s /etc/redhat-release -o -s /etc/centos-release ]; then 7 | # Includes Fedora 8 | yum install cmake boost boost-test boost-devel asio-devel autoconf gtest gtest-devel -y 9 | else 10 | echo "pkgdep: unknown system type." 11 | exit 1 12 | fi 13 | -------------------------------------------------------------------------------- /scripts/prepare_spdk_libs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | SCRIPT=$(readlink -f $0) 5 | SCRIPTPATH=`dirname $SCRIPT` 6 | SPDKPATH=third-party/spdk 7 | 8 | cd $SCRIPTPATH/../$SPDKPATH 9 | ar -M <$SCRIPTPATH/libspdk.mri 10 | cd - 11 | -------------------------------------------------------------------------------- /scripts/setup_env_lcg.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | pushd . > /dev/null 4 | SCRIPT_PATH="${BASH_SOURCE[0]}"; 5 | if ([ -h "${SCRIPT_PATH}" ]) then 6 | while([ -h "${SCRIPT_PATH}" ]) do cd `dirname "$SCRIPT_PATH"`; SCRIPT_PATH=`readlink "${SCRIPT_PATH}"`; done 7 | fi 8 | cd `dirname ${SCRIPT_PATH}` > /dev/null 9 | SCRIPT_PATH=`pwd`; 10 | popd > /dev/null 11 | 12 | SPDKPATH=third-party/spdk 13 | 14 | cvmfs_config probe 15 | 16 | source /cvmfs/sft.cern.ch/lcg/views/setupViews.sh LCG_95 x86_64-centos7-gcc8-opt 17 | 18 | # eRPC requires at least 4096 of 2M hugepages 19 | sudo HUGEMEM=4096 $SCRIPT_PATH/../$SPDKPATH/scripts/setup.sh 20 | -------------------------------------------------------------------------------- /tests/functional/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | project(daqdb_func_tests) 4 | 5 | set(CMAKE_CXX_STANDARD 14) 6 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBOOST_LOG_DYN_LINK") 7 | 8 | include(FindPkgConfig) 9 | find_package(PkgConfig) 10 | find_package(Boost REQUIRED COMPONENTS program_options log log_setup system filesystem thread) 11 | find_package(Threads REQUIRED) 12 | 13 | set(ROOT_DAQDB_DIR ${PROJECT_SOURCE_DIR}/../..) 14 | set(3RDPARTY ${ROOT_DAQDB_DIR}/third-party) 15 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${ROOT_DAQDB_DIR}/bin) 16 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${ROOT_DAQDB_DIR}/bin) 17 | 18 | configure_file(functests.cfg.in 19 | ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/functests.cfg.sample COPYONLY) 20 | 21 | include_directories(${PROJECT_SOURCE_DIR} tests) 22 | file(GLOB_RECURSE FUNCTESTS_SOURCES ${PROJECT_SOURCE_DIR}/*.cpp) 23 | add_executable(functests ${FUNCTESTS_SOURCES}) 24 | 25 | set(Dpdk_LIBRARIES -Wl,--whole-archive dpdk -Wl,--no-whole-archive) 26 | target_link_libraries(functests ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} 27 | pmem daqdb pmemobj dl numa ${Dpdk_LIBRARIES}) 28 | -------------------------------------------------------------------------------- /tests/functional/base_operations.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | DaqDB::Value allocValue(DaqDB::KVStoreBase *kvs, const uint64_t keyId, 28 | const std::string &value); 29 | 30 | const std::string generateValueStr(const size_t valueSize); 31 | 32 | DaqDB::Key allocKey(DaqDB::KVStoreBase *kvs, const uint64_t id); 33 | 34 | bool checkValue(const std::string &expectedValue, DaqDB::Value *value); 35 | 36 | const std::string keyToStr(DaqDB::Key &key); 37 | 38 | const std::string keyToStr(const char *key); 39 | 40 | DaqDB::Value daqdb_get(DaqDB::KVStoreBase *kvs, const uint64_t id); 41 | 42 | void daqdb_put(DaqDB::KVStoreBase *kvs, const uint64_t keyId, 43 | const std::string &value); 44 | 45 | void daqdb_put_value(DaqDB::KVStoreBase *kvs, const uint64_t keyId, 46 | const DaqDB::Value &value); 47 | 48 | void daqdb_update(DaqDB::KVStoreBase *kvs, const uint64_t keyId, 49 | DaqDB::Value &val, const DaqDB::UpdateOptions &options); 50 | 51 | void daqdb_offload(DaqDB::KVStoreBase *kvs, const uint64_t keyId); 52 | 53 | void daqdb_async_offload(DaqDB::KVStoreBase *kvs, const uint64_t keyId, 54 | DaqDB::KVStoreBase::KVStoreBaseCallback cb); 55 | 56 | bool daqdb_remove(DaqDB::KVStoreBase *kvs, const uint64_t keyId); 57 | 58 | void daqdb_async_get(DaqDB::KVStoreBase *kvs, const uint64_t keyId, 59 | DaqDB::KVStoreBase::KVStoreBaseCallback cb); 60 | 61 | void daqdb_async_put(DaqDB::KVStoreBase *kvs, const uint64_t keyId, 62 | const std::string &value, 63 | DaqDB::KVStoreBase::KVStoreBaseCallback cb); 64 | 65 | void daqdb_async_put_value(DaqDB::KVStoreBase *kvs, const uint64_t keyId, 66 | const DaqDB::Value &value, 67 | DaqDB::KVStoreBase::KVStoreBaseCallback cb); 68 | 69 | void daqdb_async_update(DaqDB::KVStoreBase *kvs, const uint64_t keyId, 70 | DaqDB::Value &val, 71 | DaqDB::KVStoreBase::KVStoreBaseCallback cb); 72 | -------------------------------------------------------------------------------- /tests/functional/config.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | #include "config.h" 20 | 21 | const std::string DEFAULT_PMEM_POOL_PATH = "/mnt/pmem/pool.pm"; 22 | const size_t DEFAULT_PMEM_POOL_SIZE = 8ull * 1024 * 1024 * 1024; 23 | const size_t DEFAULT_PMEM_ALLOC_UNIT_SIZE = 8; 24 | 25 | const size_t DEFAULT_OFFLOAD_ALLOC_UNIT_SIZE = 16384; 26 | 27 | bool initKvsOptions(DaqDB::Options &options, const std::string &configFile) { 28 | options.runtime.logFunc = [](std::string msg) { 29 | BOOST_LOG_SEV(lg::get(), bt::debug) << msg << std::flush; 30 | }; 31 | 32 | /* Set default values */ 33 | options.dht.id = 0; 34 | 35 | options.pmem.poolPath = DEFAULT_PMEM_POOL_PATH; 36 | options.pmem.totalSize = DEFAULT_PMEM_POOL_SIZE; 37 | options.pmem.allocUnitSize = DEFAULT_PMEM_ALLOC_UNIT_SIZE; 38 | 39 | options.key.field(0, sizeof(FuncTestKey::eventId), true); 40 | options.key.field(1, sizeof(FuncTestKey::detectorId)); 41 | options.key.field(2, sizeof(FuncTestKey::componentId)); 42 | 43 | options.offload.allocUnitSize = DEFAULT_OFFLOAD_ALLOC_UNIT_SIZE; 44 | 45 | if (boost::filesystem::exists(configFile)) { 46 | std::stringstream errorMsg; 47 | if (!DaqDB::readConfiguration(configFile, options, errorMsg)) { 48 | BOOST_LOG_SEV(lg::get(), bt::error) << errorMsg.str(); 49 | return false; 50 | } 51 | } else { 52 | return false; 53 | } 54 | return true; 55 | } 56 | -------------------------------------------------------------------------------- /tests/functional/config.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include "debug.h" 22 | #include 23 | #include 24 | 25 | struct __attribute__((packed)) FuncTestKey { 26 | uint8_t eventId[5]; 27 | uint8_t detectorId; 28 | uint16_t componentId; 29 | }; 30 | 31 | bool initKvsOptions(DaqDB::Options &options, const std::string &configFile); 32 | -------------------------------------------------------------------------------- /tests/functional/debug.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #define DAQDB_INFO BOOST_LOG_SEV(lg::get(), bt::info) 30 | 31 | using boost::format; 32 | 33 | namespace logging = boost::log; 34 | namespace bt = logging::trivial; 35 | namespace attrs = boost::log::attributes; 36 | namespace keywords = boost::log::keywords; 37 | namespace src = boost::log::sources; 38 | 39 | BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT( 40 | lg, src::severity_logger_mt) 41 | -------------------------------------------------------------------------------- /tests/functional/functests.cfg.in: -------------------------------------------------------------------------------- 1 | //***************************************************************************** 2 | //******************************* MAIN SECTION ******************************** 3 | //***************************************************************************** 4 | 5 | /** 6 | * pmem_path - location of file created on top of persistent memory 7 | * enabled filesystem 8 | * pmem_size - total size of the persistent memory pool to use 9 | * alloc_unit_size - unit allocation size for the values stored in DaqDB 10 | */ 11 | pmem_path = "/mnt/pmem/pool.pm"; 12 | pmem_size = 8589934592L; 13 | alloc_unit_size = 16384; 14 | 15 | /** 16 | * logging_level - valid parameters: 17 | * logging_level = "DEBUG"; 18 | * logging_level = "FATAL"; 19 | */ 20 | logging_level = "DEBUG"; 21 | 22 | //***************************************************************************** 23 | //******************************* DHT SECTION ******************************** 24 | //***************************************************************************** 25 | 26 | dht_key_mask_length = 1; 27 | dht_key_mask_offset = 5; 28 | neighbors : ({ 29 | ip = "localhost"; 30 | port = 31850; 31 | local = 1; 32 | keys = { start = "0", end = "255" } 33 | }, ); 34 | 35 | //***************************************************************************** 36 | //***************************** OFFLOAD SECTION ******************************* 37 | //***************************************************************************** 38 | 39 | /** 40 | * offload_unit_alloc_size 41 | * offload_nvme_addr 42 | * e.g. "0000:88:00.0" 43 | * offload_nvme_name 44 | * e.g. "Nvme0" 45 | * offload_dev_type 46 | * e.g. "bdev", "jbod" 47 | * when off_dev_type = "jbod" devices must be specified 48 | * e.g. devices = { 49 | * dev1 = {offload_nvme_addr = "0000:89:00.0"; offload_nvme_name = "Nvme1";}; 50 | * dev2 = {offload_nvme_addr = "0000:8a:00.0"; offload_nvme_name = "Nvme2";}; 51 | * dev3 = {offload_nvme_addr = "0000:8b:00.0"; offload_nvme_name = "Nvme3";}; 52 | * dev4 = {offload_nvme_addr = "0000:8c:00.0"; offload_nvme_name = "Nvme4";}; 53 | * }; 54 | */ 55 | offload_unit_alloc_size = 16384; 56 | offload_nvme_addr = "0000:89:00.0"; 57 | offload_nvme_name = "Nvme1"; 58 | offload_dev_type = "bdev" 59 | 60 | //************************************ EOF ************************************ 61 | -------------------------------------------------------------------------------- /tests/functional/tests/tests.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | bool testSyncOperations(DaqDB::KVStoreBase *kvs); 22 | bool testAsyncOperations(DaqDB::KVStoreBase *kvs); 23 | bool testSyncOffloadOperations(DaqDB::KVStoreBase *kvs); 24 | bool testAsyncOffloadOperations(DaqDB::KVStoreBase *kvs); 25 | bool testSyncOffloadExtOperations(DaqDB::KVStoreBase *kvs); 26 | bool testAsyncOffloadExtOperations(DaqDB::KVStoreBase *kvs); 27 | bool testDhtConnect(DaqDB::KVStoreBase *kvs); 28 | bool testValueSizes(DaqDB::KVStoreBase *kvs); 29 | bool testMultiplePuts(DaqDB::KVStoreBase *kvs); 30 | -------------------------------------------------------------------------------- /tests/functional/tests/tests_dht.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include "tests.h" 25 | #include 26 | #include 27 | 28 | using namespace std; 29 | using namespace DaqDB; 30 | 31 | static const unsigned int TESTCLIENT_PORT = 31852; 32 | 33 | bool testDhtConnect(KVStoreBase *kvs) { 34 | bool result = true; 35 | 36 | DhtOptions options; 37 | DhtNeighbor local; 38 | local.ip = "localhost"; 39 | local.port = TESTCLIENT_PORT; 40 | local.local = true; 41 | options.maskLength = 8; 42 | options.maskOffset = 0; 43 | 44 | DhtNeighbor neighbor; 45 | neighbor.ip = "localhost"; 46 | neighbor.port = 31850; 47 | neighbor.keyRange.start = "0"; 48 | neighbor.keyRange.end = "255"; 49 | 50 | options.neighbors.push_back(&local); 51 | options.neighbors.push_back(&neighbor); 52 | 53 | auto serverStatus = kvs->getProperty("daqdb.dht.status"); 54 | if (serverStatus.find("DHT server: inactive") != std::string::npos) { 55 | DAQDB_INFO << "DHT server not started" << flush; 56 | return false; 57 | } 58 | 59 | auto core = new DhtCore(options); 60 | core->initNexus(); 61 | core->initClient(); 62 | if (core->getClient()->state == DhtClientState::DHT_CLIENT_READY) { 63 | DAQDB_INFO << "DHT client started successfully" << flush; 64 | } else { 65 | DAQDB_INFO << "Can not start DHT client" << flush; 66 | return false; 67 | } 68 | auto neighborNode = core->getNeighbors()->front(); 69 | auto connected = core->getClient()->ping(*neighborNode); 70 | if (!connected) { 71 | DAQDB_INFO << "Can not connect to neighbor" << flush; 72 | return false; 73 | } 74 | 75 | return result; 76 | } 77 | -------------------------------------------------------------------------------- /tests/functional/tests/tests_val_size.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | #include 20 | 21 | #include "tests.h" 22 | #include 23 | #include 24 | 25 | using namespace std; 26 | using namespace DaqDB; 27 | 28 | bool static checkValuePutGet(KVStoreBase *kvs, uint64_t keyId, 29 | size_t valueSize) { 30 | bool result = true; 31 | auto val = generateValueStr(valueSize); 32 | daqdb_put(kvs, keyId, val); 33 | 34 | auto resultVal = daqdb_get(kvs, keyId); 35 | if (!checkValue(val, &resultVal)) { 36 | result = false; 37 | } 38 | 39 | auto removeResult = daqdb_remove(kvs, keyId); 40 | if (!removeResult) { 41 | result = false; 42 | DAQDB_INFO << format("Error: Cannot remove a key [%1%]") % keyId; 43 | } 44 | return result; 45 | } 46 | 47 | bool testValueSizes(KVStoreBase *kvs) { 48 | bool result = true; 49 | uint64_t expectedKey = 111; 50 | 51 | vector valSizes = { 1, 8, 16, 32, 52 | 64, 127, 128, 129, 53 | 255, 256, 512, 1023, 54 | 1024, 1025, 2 * 1024, 4 * 1024, 55 | 8 * 1024, 10240, 16 * 1024, 32 * 1024, 56 | 64 * 1024, 69632, 128 * 1024 }; 57 | 58 | for (auto valSize : valSizes) { 59 | if (!checkValuePutGet(kvs, expectedKey++, valSize)) { 60 | return false; 61 | } 62 | } 63 | return result; 64 | } 65 | -------------------------------------------------------------------------------- /tests/functional_thin/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | project(daqdb_thin_func_tests) 4 | 5 | set(CMAKE_CXX_STANDARD 14) 6 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBOOST_LOG_DYN_LINK") 7 | 8 | include(FindPkgConfig) 9 | find_package(PkgConfig) 10 | find_package(Boost REQUIRED COMPONENTS program_options log log_setup system filesystem thread) 11 | find_package(Threads REQUIRED) 12 | 13 | set(ROOT_DAQDB_DIR ${PROJECT_SOURCE_DIR}/../..) 14 | set(3RDPARTY ${ROOT_DAQDB_DIR}/third-party) 15 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${ROOT_DAQDB_DIR}/bin) 16 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${ROOT_DAQDB_DIR}/bin) 17 | 18 | configure_file(functests_thin.cfg.in 19 | ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/functests_thin.cfg.sample COPYONLY) 20 | configure_file(functests_thin_clinode.cfg.in 21 | ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/functests_thin_clinode.cfg.sample COPYONLY) 22 | file(COPY functests_thin.sh 23 | DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} 24 | FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ 25 | GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) 26 | 27 | include_directories(${PROJECT_SOURCE_DIR} tests) 28 | file(GLOB_RECURSE FUNCTESTS_THIN_SOURCES ${PROJECT_SOURCE_DIR}/*.cpp) 29 | add_executable(functests_thin ${FUNCTESTS_THIN_SOURCES}) 30 | 31 | set(Dpdk_LIBRARIES -Wl,--whole-archive dpdk -Wl,--no-whole-archive) 32 | target_link_libraries(functests_thin ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} 33 | ${Dpdk_LIBRARIES} dl daqdb_thin) 34 | -------------------------------------------------------------------------------- /tests/functional_thin/base_operations.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | DaqDB::Value allocValue(DaqDB::KVStoreBase *kvs, const uint64_t id, 26 | const std::string &value); 27 | 28 | DaqDB::Value allocValue(DaqDB::KVStoreBase *kvs, const DaqDB::Key &key, 29 | const std::string &value); 30 | 31 | const std::string generateValueStr(const size_t valueSize); 32 | 33 | DaqDB::Key allocKey(DaqDB::KVStoreBase *kvs, const uint64_t id); 34 | 35 | bool checkValue(const std::string &expectedValue, DaqDB::Value *value); 36 | 37 | const std::string keyToStr(DaqDB::Key &key); 38 | 39 | const std::string keyToStr(const char *key); 40 | 41 | DaqDB::Value remote_get(DaqDB::KVStoreBase *kvs, const uint64_t id); 42 | 43 | void remote_put(DaqDB::KVStoreBase *kvs, const uint64_t id, 44 | const std::string &value); 45 | 46 | bool remote_remove(DaqDB::KVStoreBase *kvs, const uint64_t id); 47 | -------------------------------------------------------------------------------- /tests/functional_thin/config.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | #include "config.h" 20 | 21 | bool initKvsOptions(DaqDB::Options &options, const std::string &configFile) { 22 | options.runtime.logFunc = [](std::string msg) { 23 | BOOST_LOG_SEV(lg::get(), bt::debug) << msg << std::flush; 24 | }; 25 | 26 | /* Set default values */ 27 | options.dht.id = 0; 28 | options.key.field(0, sizeof(FuncTestKey::runId)); 29 | options.key.field(1, sizeof(FuncTestKey::subdetectorId)); 30 | options.key.field(2, sizeof(FuncTestKey::eventId), true); 31 | 32 | if (boost::filesystem::exists(configFile)) { 33 | std::stringstream errorMsg; 34 | if (!DaqDB::readConfiguration(configFile, options, errorMsg)) { 35 | BOOST_LOG_SEV(lg::get(), bt::error) << errorMsg.str(); 36 | return false; 37 | } 38 | } else { 39 | return false; 40 | } 41 | return true; 42 | } 43 | -------------------------------------------------------------------------------- /tests/functional_thin/config.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include 22 | 23 | #include "debug.h" 24 | #include 25 | 26 | struct __attribute__((packed)) FuncTestKey { 27 | FuncTestKey() : eventId(0), subdetectorId(0), runId(0) {}; 28 | FuncTestKey(uint64_t e, uint16_t s, uint16_t r) 29 | : eventId(e), subdetectorId(s), runId(r) {} 30 | uint16_t runId; 31 | uint16_t subdetectorId; 32 | uint64_t eventId; 33 | }; 34 | 35 | bool initKvsOptions(DaqDB::Options &options, const std::string &configFile); 36 | -------------------------------------------------------------------------------- /tests/functional_thin/debug.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #define DAQDB_INFO BOOST_LOG_SEV(lg::get(), bt::info) 31 | 32 | using boost::format; 33 | 34 | namespace logging = boost::log; 35 | namespace bt = logging::trivial; 36 | namespace attrs = boost::log::attributes; 37 | namespace keywords = boost::log::keywords; 38 | namespace src = boost::log::sources; 39 | 40 | BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT( 41 | lg, src::severity_logger_mt) 42 | -------------------------------------------------------------------------------- /tests/functional_thin/functests_thin.cfg.in: -------------------------------------------------------------------------------- 1 | //***************************************************************************** 2 | //******************************* MAIN SECTION ******************************** 3 | //***************************************************************************** 4 | 5 | /** 6 | * mode - operational mode of this DaqDB instance. Valid parameters: 7 | * storage - this instance will accept and store internally data 8 | * satellite - this instance will accept and forward all data to 9 | * one of the storage nodes 10 | */ 11 | mode = "satellite"; 12 | 13 | /** 14 | * logging_level - valid parameters: 15 | * logging_level = "DEBUG"; 16 | * logging_level = "FATAL"; 17 | */ 18 | logging_level = "DEBUG"; 19 | 20 | //***************************************************************************** 21 | //******************************* DHT SECTION ******************************** 22 | //***************************************************************************** 23 | 24 | dht_key_mask_length = 1; 25 | dht_key_mask_offset = 5; 26 | neighbors : ( 27 | { 28 | ip = "localhost"; 29 | port = 31852; 30 | local = 1; 31 | }, 32 | { 33 | // daqdb peer required to perform functional tests for "thin" mode 34 | ip = "localhost"; 35 | port = 31850; 36 | keys = { start = "0", end = "255" }; 37 | }, 38 | ); 39 | 40 | //************************************ EOF ************************************ 41 | -------------------------------------------------------------------------------- /tests/functional_thin/functests_thin.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | clinode=${CLINODE:-./clinode} 4 | clinode_conf=${CLINODE_CONF:-functests_thin_clinode.cfg} 5 | functests=${FUNCTESTS_THIN:-./functests_thin} 6 | functests_conf=${FUNCTESTS_THIN_CONF:-functests_thin.cfg} 7 | 8 | 9 | run_server() { 10 | $clinode -c $clinode_conf & 11 | if [ $? -ne 0 ]; then 12 | echo "ERROR: $clinode returned non-zero exit status" 13 | exit 1 14 | fi 15 | } 16 | 17 | kill_server() { 18 | echo "Killing $clinode" 19 | kill $! 20 | if [ $? -ne 0 ]; then 21 | echo "ERROR: pkill returned non-zero exit status" 22 | exit 1 23 | fi 24 | } 25 | 26 | run_functests_thin() { 27 | $functests -c $functests_conf 28 | if [ $? -ne 0 ]; then 29 | echo "ERROR: $functests returned non-zero exit status" 30 | kill_server 31 | exit 1 32 | fi 33 | } 34 | 35 | if [ ! -f "$clinode" ] && [ ! $(command -v "$clinode") ]; then 36 | echo "No such file or directory: $clinode" 37 | exit 1 38 | fi 39 | 40 | if [ ! -f "$functests" ] && [ ! $(command -v "$functests") ]; then 41 | echo "No such file or directory: $functests" 42 | exit 1 43 | fi 44 | 45 | trap kill_server SIGINT SIGTERM 46 | 47 | echo "Starting server ..." 48 | run_server 49 | 50 | sleep 15 51 | 52 | echo "Executing tests" 53 | run_functests_thin 54 | 55 | kill_server -------------------------------------------------------------------------------- /tests/functional_thin/functests_thin_clinode.cfg.in: -------------------------------------------------------------------------------- 1 | //***************************************************************************** 2 | //******************************* MAIN SECTION ******************************** 3 | //***************************************************************************** 4 | 5 | /** 6 | * mode - operational mode of this DaqDB instance. Valid parameters: 7 | * storage - this instance will accept and store internally data 8 | * satellite - this instance will accept and forward all data to 9 | * one of the storage nodes 10 | */ 11 | mode = "storage"; 12 | 13 | /** 14 | * pmem_path - location of file created on top of persistent memory 15 | * enabled filesystem 16 | * pmem_size - total size of the persistent memory pool to use 17 | * alloc_unit_size - unit allocation size for the values stored in DaqDB 18 | */ 19 | pmem_path = "/mnt/pmem/pool.pm"; 20 | pmem_size = 8589934592L; 21 | alloc_unit_size = 16384; 22 | 23 | /** 24 | * logging_level - valid parameters: 25 | * logging_level = "DEBUG"; 26 | * logging_level = "FATAL"; 27 | */ 28 | logging_level = "DEBUG"; 29 | 30 | //***************************************************************************** 31 | //******************************* DHT SECTION ******************************** 32 | //***************************************************************************** 33 | 34 | /** 35 | * key_mask 36 | * neighbors 37 | */ 38 | dht_key_mask_length = 1; 39 | dht_key_mask_offset = 5; 40 | neighbors : ({ 41 | ip = "localhost"; 42 | port = 31850; 43 | local = 1; 44 | keys = {start = "0", end = "255"}; 45 | }, ); 46 | 47 | //***************************************************************************** 48 | //***************************** OFFLOAD SECTION ******************************* 49 | //***************************************************************************** 50 | 51 | /** 52 | * offload_unit_alloc_size 53 | * offload_nvme_addr 54 | * e.g. "0000:88:00.0" 55 | * offload_nvme_name 56 | * e.g. "Nvme0" 57 | */ 58 | offload_unit_alloc_size = 16384; 59 | offload_nvme_addr = ""; 60 | offload_nvme_name = ""; 61 | 62 | //************************************ EOF ************************************ 63 | -------------------------------------------------------------------------------- /tests/functional_thin/tests/tests.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include "debug.h" 20 | #include 21 | 22 | /** 23 | * Verifies connection to remote DAQDB node (defined in configuration file) 24 | */ 25 | bool testRemotePeerConnect(DaqDB::KVStoreBase *kvs, DaqDB::Options *options); 26 | 27 | /** 28 | * Verifies single PUT and GET operation performed on remote DAQDB peer 29 | * node. 30 | */ 31 | bool testPutGetSequence(DaqDB::KVStoreBase *kvs, DaqDB::Options *options); 32 | 33 | /** 34 | * Verifies various value sizes for single PUT and GET operation performed on 35 | * remote DAQDB peer. 36 | */ 37 | bool testValueSizes(DaqDB::KVStoreBase *kvs, DaqDB::Options *options); 38 | 39 | bool testMultithredingPutGet(DaqDB::KVStoreBase *kvs, DaqDB::Options *options); 40 | -------------------------------------------------------------------------------- /tests/functional_thin/tests/tests_base.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "boost/algorithm/string.hpp" 18 | 19 | #include "tests.h" 20 | 21 | #include "../base_operations.h" 22 | #include 23 | #include 24 | 25 | using namespace std; 26 | using namespace DaqDB; 27 | 28 | bool testRemotePeerConnect(KVStoreBase *kvs, DaqDB::Options *options) { 29 | bool result = true; 30 | 31 | DhtOptions clientOptions; 32 | clientOptions.maskLength = 1; 33 | clientOptions.maskOffset = 0; 34 | for (auto node : options->dht.neighbors) { 35 | if (node->local) { 36 | auto local = new DhtNeighbor(); 37 | local->ip = node->ip; 38 | local->port = node->port + 1; 39 | local->local = true; 40 | clientOptions.neighbors.push_back(local); 41 | } else { 42 | clientOptions.neighbors.push_back(node); 43 | } 44 | } 45 | 46 | auto core = new DhtCore(clientOptions); 47 | core->initNexus(); 48 | core->initClient(); 49 | if (core->getClient()->state == DhtClientState::DHT_CLIENT_READY) { 50 | DAQDB_INFO << "DHT client started successfully" << flush; 51 | } else { 52 | DAQDB_INFO << "Can not start DHT client" << flush; 53 | return false; 54 | } 55 | auto neighborNode = core->getNeighbors()->front(); 56 | auto connected = core->getClient()->ping(*neighborNode); 57 | if (!connected) { 58 | DAQDB_INFO << "Can not connect to neighbor" << flush; 59 | return false; 60 | } 61 | 62 | for (auto node : clientOptions.neighbors) 63 | if (node->local) 64 | delete node; 65 | 66 | return result; 67 | } 68 | 69 | bool testPutGetSequence(KVStoreBase *kvs, DaqDB::Options *options) { 70 | bool result = true; 71 | 72 | const string val = "daqdb"; 73 | const uint64_t keyId = 1000; 74 | 75 | remote_put(kvs, keyId, val); 76 | 77 | auto resultVal = remote_get(kvs, keyId); 78 | if (!checkValue(val, &resultVal)) { 79 | result = false; 80 | } 81 | 82 | auto removeResult = remote_remove(kvs, keyId); 83 | DAQDB_INFO << format("Remote Remove: [%1%]") % keyId; 84 | if (!removeResult) { 85 | result = false; 86 | DAQDB_INFO << format("Error: Cannot remove a key [%1%]") % keyId; 87 | } 88 | 89 | return result; 90 | } 91 | -------------------------------------------------------------------------------- /tests/functional_thin/tests/tests_multithreading.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | #include "../base_operations.h" 21 | #include "tests.h" 22 | 23 | using namespace std; 24 | using namespace DaqDB; 25 | 26 | bool threadTask(KVStoreBase *kvs, uint64_t keyId) { 27 | bool result = true; 28 | const string val = "daqdb"; 29 | 30 | remote_put(kvs, keyId, val); 31 | 32 | auto resultVal = remote_get(kvs, keyId); 33 | if (!checkValue(val, &resultVal)) { 34 | result = false; 35 | } 36 | 37 | auto removeResult = remote_remove(kvs, keyId); 38 | if (!removeResult) { 39 | result = false; 40 | } 41 | 42 | return result; 43 | } 44 | 45 | bool testMultithredingPutGet(KVStoreBase *kvs, Options *options) { 46 | bool result = true; 47 | 48 | future future1 = async(launch::async, threadTask, kvs, 12345); 49 | future future2 = async(launch::async, threadTask, kvs, 54321); 50 | 51 | if (!(future1.get() && future2.get())) { 52 | result = false; 53 | } 54 | return result; 55 | } 56 | -------------------------------------------------------------------------------- /tests/functional_thin/tests/tests_val_size.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "../base_operations.h" 18 | #include "tests.h" 19 | 20 | using namespace std; 21 | using namespace DaqDB; 22 | 23 | bool static checkValuePutGet(KVStoreBase *kvs, uint64_t keyId, 24 | size_t valueSize) { 25 | bool result = true; 26 | auto val = generateValueStr(valueSize); 27 | 28 | remote_put(kvs, keyId, val); 29 | 30 | auto resultVal = remote_get(kvs, keyId); 31 | if (!checkValue(val, &resultVal)) { 32 | result = false; 33 | } 34 | 35 | auto removeResult = remote_remove(kvs, keyId); 36 | if (!removeResult) { 37 | result = false; 38 | DAQDB_INFO << format("Error: Cannot remove a key [%1%]") % keyId; 39 | } 40 | 41 | return result; 42 | } 43 | 44 | bool testValueSizes(KVStoreBase *kvs, DaqDB::Options *options) { 45 | bool result = true; 46 | 47 | uint64_t expectedKey = 200; 48 | 49 | vector valSizes = {8, 16, 32, 64, 127, 128, 50 | 129, 255, 256, 512, 1023, 1024, 51 | 1025, 2048, 4096, 8192, 10240, 16384}; 52 | 53 | for (auto valSize : valSizes) { 54 | if (!checkValuePutGet(kvs, expectedKey++, valSize)) { 55 | return false; 56 | } 57 | } 58 | 59 | return result; 60 | } 61 | -------------------------------------------------------------------------------- /tests/unit/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | project(daqdb_unit_test) 4 | 5 | include(CTest) 6 | include(FindPkgConfig) 7 | find_package(PkgConfig) 8 | 9 | include(BoostTestHelpers) 10 | 11 | set(CMAKE_CXX_STANDARD 14) 12 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBOOST_TEST_DYN_LINK") 13 | 14 | find_package(Boost REQUIRED COMPONENTS unit_test_framework program_options system filesystem) 15 | find_package(Threads REQUIRED) 16 | 17 | include_directories(mock) 18 | 19 | add_boost_test(dht/DhtCoreTest.cpp) 20 | add_boost_test(dht/DhtClientTest.cpp) 21 | add_boost_test(dht/DhtNodeTest.cpp) 22 | add_boost_test(dht/DhtUtilsTest.cpp) 23 | add_boost_test(pmem/PmemPollerTest.cpp) 24 | add_boost_test(offload/OffloadPollerTest.cpp) 25 | add_boost_test(offload/OffloadFreeListTest.cpp) 26 | -------------------------------------------------------------------------------- /tests/unit/dht/DhtCoreTest.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #define BOOST_TEST_MAIN 18 | #include 19 | 20 | #include "../../lib/dht/DhtCore.cpp" 21 | #include 22 | 23 | namespace ut = boost::unit_test; 24 | 25 | using namespace std; 26 | using namespace fakeit; 27 | using namespace DaqDB; 28 | 29 | /** 30 | * Test verified if getClient function initializes DhtClient per caller thread. 31 | */ 32 | BOOST_AUTO_TEST_CASE(VerifyGetClient) { 33 | Mock dhtCoreMock; 34 | Mock dhtClientMock; 35 | 36 | DhtClient &dhtClient = dhtClientMock.get(); 37 | DhtCore &dhtCore = dhtCoreMock.get(); 38 | 39 | When(Method(dhtCoreMock, initClient)).AlwaysReturn(); 40 | 41 | dhtCore.setClient(nullptr); 42 | dhtCore.getClient(); 43 | Verify(Method(dhtCoreMock, initClient)).Exactly(1); 44 | 45 | dhtCore.setClient(&dhtClient); 46 | auto result = dhtCore.getClient(); 47 | VerifyNoOtherInvocations(Method(dhtCoreMock, initClient)); 48 | BOOST_CHECK_EQUAL(&dhtClient, result); 49 | } 50 | -------------------------------------------------------------------------------- /tests/unit/dht/DhtNodeTest.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "../../lib/dht/DhtNode.h" 18 | 19 | #define BOOST_TEST_MAIN 20 | #include 21 | 22 | namespace ut = boost::unit_test; 23 | 24 | BOOST_AUTO_TEST_CASE(TestNodeConstr) { 25 | DaqDB::DhtNode *dhtNode = new DaqDB::DhtNode(); 26 | 27 | BOOST_CHECK(dhtNode->state == DaqDB::DhtNodeState::NODE_INIT); 28 | 29 | delete dhtNode; 30 | } 31 | 32 | BOOST_AUTO_TEST_CASE(TestSessionIdSetting) { 33 | DaqDB::DhtNode *dhtNode = new DaqDB::DhtNode(); 34 | int expectedSessionId; 35 | 36 | dhtNode->setSessionId(expectedSessionId); 37 | 38 | BOOST_CHECK_EQUAL(dhtNode->getSessionId(), expectedSessionId); 39 | 40 | delete dhtNode; 41 | } 42 | 43 | BOOST_AUTO_TEST_CASE(TestNodeAddr) { 44 | DaqDB::DhtNode *dhtNode = new DaqDB::DhtNode(); 45 | const std::string expectedId = "10.1.0.1"; 46 | unsigned short expectedPort = 50000; 47 | 48 | dhtNode->setIp(expectedId); 49 | dhtNode->setPort(expectedPort); 50 | 51 | BOOST_CHECK(dhtNode->getIp() == expectedId); 52 | BOOST_CHECK_EQUAL(dhtNode->getPort(), expectedPort); 53 | 54 | BOOST_CHECK(dhtNode->getUri() == 55 | expectedId + ":" + std::to_string(expectedPort)); 56 | 57 | delete dhtNode; 58 | } 59 | 60 | BOOST_AUTO_TEST_CASE(TestStartSetting) { 61 | DaqDB::DhtNode *dhtNode = new DaqDB::DhtNode(); 62 | unsigned int expectedStart = 5; 63 | 64 | dhtNode->setStart(expectedStart); 65 | 66 | BOOST_CHECK_EQUAL(dhtNode->getStart(), expectedStart); 67 | 68 | delete dhtNode; 69 | } 70 | 71 | BOOST_AUTO_TEST_CASE(TestEndSetting) { 72 | DaqDB::DhtNode *dhtNode = new DaqDB::DhtNode(); 73 | unsigned int expectedEnd = 10; 74 | 75 | dhtNode->setEnd(expectedEnd); 76 | 77 | BOOST_CHECK_EQUAL(dhtNode->getEnd(), expectedEnd); 78 | 79 | delete dhtNode; 80 | } 81 | -------------------------------------------------------------------------------- /tests/unit/dht/DhtUtilsTest.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019 Intel Corporation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "../../lib/dht/DhtUtils.h" 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | #define BOOST_TEST_MAIN 26 | #include 27 | 28 | namespace ut = boost::unit_test; 29 | 30 | namespace { 31 | const unsigned short reservedPortsEnd = 1024; 32 | const unsigned short sshProtocolPort = 22; 33 | 34 | std::error_code isPortFree(asio::io_service &io_service, 35 | const unsigned short portToTest) { 36 | asio::ip::tcp::acceptor acceptor(io_service); 37 | std::error_code checkPortErrorCode; 38 | 39 | acceptor.open(asio::ip::tcp::v4(), checkPortErrorCode); 40 | acceptor.bind( { asio::ip::tcp::v4(), portToTest }, checkPortErrorCode); 41 | acceptor.close(); 42 | return checkPortErrorCode; 43 | } 44 | 45 | unsigned short getRandomPortNumber() { 46 | std::random_device rd; 47 | 48 | auto gen = std::bind( 49 | std::uniform_int_distribution<>(reservedPortsEnd + 1, USHRT_MAX), 50 | std::default_random_engine(rd())); 51 | 52 | return gen(); 53 | } 54 | } 55 | 56 | /** 57 | * Test if Dht::utils::getFreePort give free port as result when no default. 58 | */ 59 | BOOST_AUTO_TEST_CASE(GenRandomPort) { 60 | asio::io_service io_service; 61 | 62 | auto resultPort = DaqDB::utils::getFreePort(io_service, 0); 63 | 64 | BOOST_CHECK_GT(resultPort, reservedPortsEnd); 65 | auto isFreeResult = isPortFree(io_service, resultPort); 66 | BOOST_CHECK(isFreeResult.value() == 0); 67 | } 68 | 69 | /** 70 | * Test if Dht::utils::getFreePort give free port as result when default is given but it is already used 71 | */ 72 | BOOST_AUTO_TEST_CASE(GenRandomPort_DefaultIsUsed) { 73 | asio::io_service io_service; 74 | 75 | auto portThatIsOpened = sshProtocolPort; 76 | 77 | auto resultPort = DaqDB::utils::getFreePort(io_service, portThatIsOpened, false); 78 | 79 | BOOST_CHECK_GT(resultPort, reservedPortsEnd); 80 | auto isFreeResult = isPortFree(io_service, resultPort); 81 | BOOST_CHECK(isFreeResult.value() == 0); 82 | BOOST_CHECK_NE(resultPort, portThatIsOpened); 83 | } 84 | 85 | /** 86 | * Test if Dht::utils::getFreePort give free port as result when default is given. 87 | */ 88 | BOOST_AUTO_TEST_CASE(GenRandomPort_DefaultNotUsed) { 89 | asio::io_service io_service; 90 | 91 | auto freePort = getRandomPortNumber(); 92 | auto resultPort = DaqDB::utils::getFreePort(io_service, freePort, true); 93 | 94 | BOOST_CHECK_GT(resultPort, reservedPortsEnd); 95 | auto isFreeResult = isPortFree(io_service, resultPort); 96 | BOOST_CHECK(isFreeResult.value() == 0); 97 | BOOST_CHECK_EQUAL(resultPort, freePort); 98 | } 99 | -------------------------------------------------------------------------------- /tests/unit/mock/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Eran Pe'er 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /third-party/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | project(third-party) 4 | 5 | set(ROOT_DAQDB_DIR ${PROJECT_SOURCE_DIR}/..) 6 | set(DAQDB_BIN_DIR ${ROOT_DAQDB_DIR}/bin) 7 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${DAQDB_BIN_DIR}) 8 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${DAQDB_BIN_DIR}) 9 | 10 | ############################################################################### 11 | # Dependencies - External projects 12 | ############################################################################### 13 | 14 | if(NOT THIN_LIB) 15 | include(pmdk.cmake) 16 | include(spdk.cmake) 17 | else(NOT THIN_LIB) 18 | if(NOT ERPC_RAW_TRANSPORT) 19 | include(spdk.cmake) 20 | endif(NOT ERPC_RAW_TRANSPORT) 21 | endif(NOT THIN_LIB) 22 | 23 | include(erpc.cmake) 24 | include(libconfig.cmake) 25 | 26 | ############################################################################### 27 | # Dependencies - Libraries 28 | ############################################################################### 29 | 30 | # hdrhistogram 31 | set(HDRHISTOGRAM ${PROJECT_SOURCE_DIR}/HdrHistogram_c) 32 | set(HDRHISTOGRAM_INCLUDES ${HDRHISTOGRAM}/src) 33 | set(HDRHISTOGRAM_INCLUDES_EXPORT ${HDRHISTOGRAM_INCLUDES} PARENT_SCOPE) 34 | include_directories(${HDRHISTOGRAM_INCLUDES}) 35 | file(GLOB_RECURSE HDRHISTOGRAM_SOURCES ${HDRHISTOGRAM}/src/*.c) 36 | add_library(hdr_histogram SHARED ${HDRHISTOGRAM_SOURCES}) 37 | 38 | ############################################################################### 39 | # Custom Targets 40 | ############################################################################### 41 | 42 | # Cleanup tasks 43 | add_custom_target(clean-dep) 44 | if(NOT THIN_LIB) 45 | add_dependencies(clean-dep libpmdk_clean) 46 | add_dependencies(clean-dep libspdk_clean) 47 | endif() 48 | -------------------------------------------------------------------------------- /third-party/erpc.cmake: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | include(ExternalProject) 4 | 5 | set(DPDK_PATH ${PROJECT_SOURCE_DIR}/spdk/dpdk/build) 6 | 7 | ExternalProject_Add(project_erpc 8 | PREFIX ${PROJECT_SOURCE_DIR}/eRPC 9 | SOURCE_DIR ${PROJECT_SOURCE_DIR}/eRPC 10 | BUILD_IN_SOURCE ${PROJECT_SOURCE_DIR}/eRPC 11 | CMAKE_ARGS -DPERF=ON -DTRANSPORT=${ERPC_TRANSPORT_MODE} -DLTO=OFF -DCMAKE_PREFIX_PATH=${DPDK_PATH} -DCMAKE_POSITION_INDEPENDENT_CODE=ON 12 | BUILD_COMMAND ${CMAKE_MAKE_PROGRAM} 13 | INSTALL_COMMAND "" 14 | DEPENDS project_spdk 15 | ) 16 | add_library(liberpc STATIC IMPORTED GLOBAL) 17 | set_target_properties(liberpc PROPERTIES IMPORTED_LOCATION 18 | ${PROJECT_SOURCE_DIR}/eRPC/build/liberpc.a) 19 | add_dependencies(liberpc project_erpc) 20 | -------------------------------------------------------------------------------- /third-party/libconfig.cmake: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | include(ExternalProject) 4 | 5 | set(LIBCONFIG_INCLUDES_EXPORT ${PROJECT_SOURCE_DIR}/libconfig/lib PARENT_SCOPE) 6 | ExternalProject_Add(project_libconfig 7 | PREFIX ${PROJECT_SOURCE_DIR}/libconfig 8 | SOURCE_DIR ${PROJECT_SOURCE_DIR}/libconfig 9 | BUILD_IN_SOURCE ${PROJECT_SOURCE_DIR}/libconfig 10 | CMAKE_ARGS -DBUILD_EXAMPLES=OFF -DBUILD_TESTS=OFF 11 | BUILD_COMMAND ${CMAKE_MAKE_PROGRAM} 12 | INSTALL_COMMAND ${CMAKE_COMMAND} -E copy_if_different 13 | ${PROJECT_SOURCE_DIR}/libconfig/out/liblibconfig++.so 14 | ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/liblibconfig++.so 15 | ) 16 | add_library(libconfig STATIC IMPORTED GLOBAL) 17 | add_dependencies(libconfig project_libconfig) 18 | set_target_properties(libconfig PROPERTIES IMPORTED_LOCATION 19 | ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/liblibconfig++.so) -------------------------------------------------------------------------------- /third-party/pmdk.cmake: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | include(ExternalProject) 4 | 5 | if (CMAKE_BUILD_TYPE STREQUAL "Debug") 6 | MESSAGE(STATUS "Enabling PMDK debug mode.") 7 | set(PMDK_SOURCE_DIR ${PROJECT_SOURCE_DIR}/pmdk/src/debug) 8 | else (CMAKE_BUILD_TYPE STREQUAL "Debug") 9 | MESSAGE(STATUS "Enabling PMDK release mode.") 10 | set(PMDK_SOURCE_DIR ${PROJECT_SOURCE_DIR}/pmdk/lib) 11 | endif (CMAKE_BUILD_TYPE STREQUAL "Debug") 12 | 13 | if(SANITIZE) 14 | MESSAGE(STATUS "Enabling PMDK sanitize mode") 15 | set(PMDK_CXX_FLAGS "-g -fsanitize=address") 16 | set(PMDK_LINK_FLAGS "-fsanitize=address") 17 | else(SANITIZE) 18 | MESSAGE(STATUS "Disabling PMDK sanitize mode") 19 | set(PMDK_CXX_FLAGS "") 20 | set(PMDK_LINK_FLAGS "") 21 | endif(SANITIZE) 22 | 23 | include_directories(pmdk/src/include) 24 | ExternalProject_Add(project_pmdk 25 | PREFIX ${PROJECT_SOURCE_DIR}/pmdk 26 | SOURCE_DIR ${PROJECT_SOURCE_DIR}/pmdk 27 | BUILD_IN_SOURCE ${PROJECT_SOURCE_DIR}/pmdk 28 | CONFIGURE_COMMAND "" 29 | BUILD_COMMAND ${CMAKE_MAKE_PROGRAM} EXTRA_LDFLAGS=${PMDK_LINK_FLAGS} EXTRA_CFLAGS=${PMDK_CXX_FLAGS} NDCTL_ENABLE=n install prefix=${PROJECT_SOURCE_DIR}/pmdk 30 | INSTALL_COMMAND ${CMAKE_COMMAND} -E copy_if_different 31 | ${PMDK_SOURCE_DIR}/libpmem.so 32 | ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libpmem.so.1 && 33 | ${CMAKE_COMMAND} -E copy_if_different 34 | ${PMDK_SOURCE_DIR}/libpmemobj.so 35 | ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libpmemobj.so.1 36 | ) 37 | add_library(pmem SHARED IMPORTED GLOBAL) 38 | add_dependencies(pmem project_pmdk) 39 | set_target_properties(pmem PROPERTIES IMPORTED_LOCATION 40 | ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libpmem.so.1) 41 | add_library(pmemobj SHARED IMPORTED GLOBAL) 42 | add_dependencies(pmemobj project_pmdk) 43 | set_target_properties(pmemobj PROPERTIES IMPORTED_LOCATION 44 | ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libpmemobj.so.1) 45 | 46 | add_custom_target(libpmdk_clean 47 | COMMAND ${CMAKE_MAKE_PROGRAM} NDCTL_ENABLE=n clean 48 | WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/pmdk 49 | ) 50 | -------------------------------------------------------------------------------- /third-party/spdk.cmake: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | include(ExternalProject) 4 | 5 | ExternalProject_Add(project_spdk 6 | PREFIX ${PROJECT_SOURCE_DIR}/spdk 7 | SOURCE_DIR ${PROJECT_SOURCE_DIR}/spdk 8 | PATCH_COMMAND ${ROOT_DAQDB_DIR}/scripts/patch_spdk_isal.sh 9 | BUILD_IN_SOURCE ${PROJECT_SOURCE_DIR}/spdk 10 | CONFIGURE_COMMAND "./configure" "--with-isal" 11 | BUILD_COMMAND ${CMAKE_MAKE_PROGRAM} 12 | INSTALL_COMMAND ${ROOT_DAQDB_DIR}/scripts/prepare_spdk_libs.sh 13 | ) 14 | add_library(spdk STATIC IMPORTED GLOBAL) 15 | set_property(TARGET spdk PROPERTY IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/spdk/libspdk.a) 16 | add_dependencies(spdk project_spdk) 17 | add_library(dpdk STATIC IMPORTED GLOBAL) 18 | set_property(TARGET dpdk PROPERTY IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/spdk/libdpdk.a) 19 | add_dependencies(dpdk project_spdk) 20 | 21 | add_custom_target(libspdk_clean 22 | COMMAND ${CMAKE_MAKE_PROGRAM} clean 23 | COMMAND rm -f ${PROJECT_SOURCE_DIR}/spdk/libspdk.a 24 | COMMAND rm -f ${PROJECT_SOURCE_DIR}/spdk/libdpdk.a 25 | WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/spdk 26 | ) 27 | --------------------------------------------------------------------------------