From ba809eda431156c87ef0869980bdd7a9a38a69ab Mon Sep 17 00:00:00 2001 From: Green Sky Date: Fri, 6 Dec 2024 14:11:06 +0100 Subject: [PATCH] refactor and test ts start search --- CMakeLists.txt | 60 ++++++++++----- solanaceae/ngc_hs2/ngc_hs2_send.cpp | 26 +------ solanaceae/ngc_hs2/test_ts_binarysearch.cpp | 82 +++++++++++++++++++++ solanaceae/ngc_hs2/ts_find_start.hpp | 31 ++++++++ 4 files changed, 156 insertions(+), 43 deletions(-) create mode 100644 solanaceae/ngc_hs2/test_ts_binarysearch.cpp create mode 100644 solanaceae/ngc_hs2/ts_find_start.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 9683e07..e50ab5e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,24 +43,6 @@ target_link_libraries(solanaceae_ngcft1 PUBLIC ######################################## -add_library(solanaceae_ngchs2 - ./solanaceae/ngc_hs2/ngc_hs2_send.hpp - ./solanaceae/ngc_hs2/ngc_hs2_send.cpp - #./solanaceae/ngc_hs2/ngc_hs2_recv.hpp - #./solanaceae/ngc_hs2/ngc_hs2_recv.cpp -) -target_include_directories(solanaceae_ngchs2 PUBLIC .) -target_compile_features(solanaceae_ngchs2 PUBLIC cxx_std_17) -target_link_libraries(solanaceae_ngchs2 PUBLIC - solanaceae_ngcft1 - solanaceae_tox_contacts - solanaceae_message3 - solanaceae_object_store - nlohmann_json::nlohmann_json -) - -######################################## - add_library(solanaceae_sha1_ngcft1 # hacky deps ./solanaceae/ngc_ft1_sha1/mio.hpp @@ -120,8 +102,6 @@ target_link_libraries(solanaceae_sha1_ngcft1 PUBLIC solanaceae_file2 ) -######################################## - option(SOLANACEAE_NGCFT1_SHA1_BUILD_TESTING "Build the solanaceae_ngcft1_sha1 tests" OFF) message("II SOLANACEAE_NGCFT1_SHA1_BUILD_TESTING " ${SOLANACEAE_NGCFT1_SHA1_BUILD_TESTING}) @@ -139,3 +119,43 @@ if (SOLANACEAE_NGCFT1_SHA1_BUILD_TESTING) endif() +######################################## + +add_library(solanaceae_ngchs2 + ./solanaceae/ngc_hs2/ts_find_start.hpp + + ./solanaceae/ngc_hs2/ngc_hs2_send.hpp + ./solanaceae/ngc_hs2/ngc_hs2_send.cpp + + #./solanaceae/ngc_hs2/ngc_hs2_recv.hpp + #./solanaceae/ngc_hs2/ngc_hs2_recv.cpp +) +target_include_directories(solanaceae_ngchs2 PUBLIC .) +target_compile_features(solanaceae_ngchs2 PUBLIC cxx_std_17) +target_link_libraries(solanaceae_ngchs2 PUBLIC + solanaceae_ngcft1 + solanaceae_sha1_ngcft1 # HACK: properly abstract filekind/-id + solanaceae_tox_contacts + solanaceae_message3 + solanaceae_object_store + nlohmann_json::nlohmann_json +) + +option(SOLANACEAE_NGCHS2_BUILD_TESTING "Build the solanaceae_ngchs2 tests" OFF) +message("II SOLANACEAE_NGCHS2_BUILD_TESTING " ${SOLANACEAE_NGCHS2_BUILD_TESTING}) + +if (SOLANACEAE_NGCHS2_BUILD_TESTING) + include(CTest) + + add_executable(test_hs2_ts_binarysearch + ./solanaceae/ngc_hs2/test_ts_binarysearch.cpp + ) + + target_link_libraries(test_hs2_ts_binarysearch PUBLIC + solanaceae_ngchs2 + ) + + add_test(NAME test_hs2_ts_binarysearch COMMAND test_hs2_ts_binarysearch) + +endif() + diff --git a/solanaceae/ngc_hs2/ngc_hs2_send.cpp b/solanaceae/ngc_hs2/ngc_hs2_send.cpp index 2b02df3..5e7d354 100644 --- a/solanaceae/ngc_hs2/ngc_hs2_send.cpp +++ b/solanaceae/ngc_hs2/ngc_hs2_send.cpp @@ -17,7 +17,7 @@ #include -#include +#include "./ts_find_start.hpp" #include @@ -212,35 +212,15 @@ std::vector NGCHS2Send::buildHSFileRange(Contact3Handle c, uint64_t ts_ return {}; } - std::cout << "!!!! starting msg ts search, ts_start:" << ts_start << " ts_end:" << ts_end << "\n"; + //std::cout << "!!!! starting msg ts search, ts_start:" << ts_start << " ts_end:" << ts_end << "\n"; auto ts_view = msg_reg.view(); // we iterate "forward", so from newest to oldest // start is the newest ts - auto ts_start_it = ts_view.end(); // start invalid + const auto ts_start_it = find_start_by_ts(ts_view, ts_start); // end is the oldest ts - // - { // binary search for first value not newer than start ts - // -> first value smaller than start ts - auto res = std::lower_bound( - ts_view.begin(), ts_view.end(), - ts_start, - [&ts_view](const auto& a, const auto& b) { - const auto& [a_comp] = ts_view.get(a); - return a_comp.ts > b; // > bc ts is sorted high to low? - } - ); - - if (res != ts_view.end()) { - const auto& [ts_comp] = ts_view.get(*res); - std::cout << "!!!! first value not newer than start ts is " << ts_comp.ts << "\n"; - ts_start_it = res; - } else { - std::cout << "!!!! no first value not newer than start ts\n"; - } - } // we only search for the start point, because we walk to the end anyway diff --git a/solanaceae/ngc_hs2/test_ts_binarysearch.cpp b/solanaceae/ngc_hs2/test_ts_binarysearch.cpp new file mode 100644 index 0000000..721bfcb --- /dev/null +++ b/solanaceae/ngc_hs2/test_ts_binarysearch.cpp @@ -0,0 +1,82 @@ +#include "./ts_find_start.hpp" + +#include +#include + +#include + +int main(void) { + Message3Registry msg_reg; + + { + std::cout << "TEST empty reg\n"; + auto ts_view = msg_reg.view(); + const auto res = find_start_by_ts(ts_view, 42); + assert(res == ts_view.end()); + } + + { + std::cout << "TEST single msg newer (fail)\n"; + Message3Handle msg{msg_reg, msg_reg.create()}; + msg.emplace(43ul); + + auto ts_view = msg_reg.view(); + const auto res = find_start_by_ts(ts_view, 42); + assert(res == ts_view.end()); + + msg.destroy(); + } + + { + std::cout << "TEST single msg same (succ)\n"; + Message3Handle msg{msg_reg, msg_reg.create()}; + msg.emplace(42ul); + + auto ts_view = msg_reg.view(); + const auto res = find_start_by_ts(ts_view, 42); + assert(res != ts_view.end()); + + msg.destroy(); + } + + { + std::cout << "TEST single msg older (succ)\n"; + Message3Handle msg{msg_reg, msg_reg.create()}; + msg.emplace(41ul); + + auto ts_view = msg_reg.view(); + const auto res = find_start_by_ts(ts_view, 42); + assert(res != ts_view.end()); + + msg.destroy(); + } + + { + std::cout << "TEST multi msg\n"; + Message3Handle msg{msg_reg, msg_reg.create()}; + msg.emplace(41ul); + Message3Handle msg2{msg_reg, msg_reg.create()}; + msg2.emplace(42ul); + Message3Handle msg3{msg_reg, msg_reg.create()}; + msg3.emplace(43ul); + + // see message3/message_time_sort.cpp + msg_reg.sort([](const auto& lhs, const auto& rhs) -> bool { + return lhs.ts > rhs.ts; + }, entt::insertion_sort{}); + + auto ts_view = msg_reg.view(); + auto res = find_start_by_ts(ts_view, 42); + assert(res != ts_view.end()); + assert(*res == msg2); + res++; + assert(*res == msg); + + msg3.destroy(); + msg2.destroy(); + msg.destroy(); + } + + return 0; +} + diff --git a/solanaceae/ngc_hs2/ts_find_start.hpp b/solanaceae/ngc_hs2/ts_find_start.hpp new file mode 100644 index 0000000..6ff86e8 --- /dev/null +++ b/solanaceae/ngc_hs2/ts_find_start.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include +#include + +#include + +// perform binary search to find the first message not newer than ts_start +template +auto find_start_by_ts(const View& view, uint64_t ts_start) { + std::cout << "!!!! starting msg ts search, ts_start:" << ts_start << "\n"; + + // -> first value smaller than start ts + auto res = std::lower_bound( + view.begin(), view.end(), + ts_start, + [&view](const auto& a, const auto& b) { + const auto& [a_comp] = view.get(a); + return a_comp.ts > b; // > bc ts is sorted high to low? + } + ); + + if (res != view.end()) { + const auto& [ts_comp] = view.get(*res); + std::cout << "!!!! first value not newer than start ts is " << ts_comp.ts << "\n"; + } else { + std::cout << "!!!! no first value not newer than start ts\n"; + } + return res; +} +