refactor and test ts start search

This commit is contained in:
Green Sky 2024-12-06 14:11:06 +01:00
parent b9a7c75d20
commit ba809eda43
No known key found for this signature in database
4 changed files with 156 additions and 43 deletions

View File

@ -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()

View File

@ -17,7 +17,7 @@
#include <nlohmann/json.hpp>
#include <algorithm>
#include "./ts_find_start.hpp"
#include <iostream>
@ -212,35 +212,15 @@ std::vector<uint8_t> 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<Message::Components::Timestamp>();
// 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

View File

@ -0,0 +1,82 @@
#include "./ts_find_start.hpp"
#include <solanaceae/message3/registry_message_model.hpp>
#include <solanaceae/message3/components.hpp>
#include <cassert>
int main(void) {
Message3Registry msg_reg;
{
std::cout << "TEST empty reg\n";
auto ts_view = msg_reg.view<Message::Components::Timestamp>();
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<Message::Components::Timestamp>(43ul);
auto ts_view = msg_reg.view<Message::Components::Timestamp>();
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<Message::Components::Timestamp>(42ul);
auto ts_view = msg_reg.view<Message::Components::Timestamp>();
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<Message::Components::Timestamp>(41ul);
auto ts_view = msg_reg.view<Message::Components::Timestamp>();
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<Message::Components::Timestamp>(41ul);
Message3Handle msg2{msg_reg, msg_reg.create()};
msg2.emplace<Message::Components::Timestamp>(42ul);
Message3Handle msg3{msg_reg, msg_reg.create()};
msg3.emplace<Message::Components::Timestamp>(43ul);
// see message3/message_time_sort.cpp
msg_reg.sort<Message::Components::Timestamp>([](const auto& lhs, const auto& rhs) -> bool {
return lhs.ts > rhs.ts;
}, entt::insertion_sort{});
auto ts_view = msg_reg.view<Message::Components::Timestamp>();
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;
}

View File

@ -0,0 +1,31 @@
#pragma once
#include <algorithm>
#include <cstdint>
#include <iostream>
// perform binary search to find the first message not newer than ts_start
template<typename View>
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;
}