Compare commits
No commits in common. "5169ddc2cb4203fc38c9ddd10e740e79744103ca" and "476e7b00a478c5114f15a6762f0825a62e837417" have entirely different histories.
5169ddc2cb
...
476e7b00a4
@ -10,7 +10,6 @@
|
|||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
@ -18,8 +17,6 @@
|
|||||||
|
|
||||||
// https://youtu.be/CU2exyhYPfA
|
// https://youtu.be/CU2exyhYPfA
|
||||||
|
|
||||||
// everything assumes a single fragment registry
|
|
||||||
|
|
||||||
namespace Message::Components {
|
namespace Message::Components {
|
||||||
|
|
||||||
// ctx
|
// ctx
|
||||||
@ -35,23 +32,9 @@ namespace Message::Components {
|
|||||||
// all message fragments of this contact
|
// all message fragments of this contact
|
||||||
struct ContactFragments final {
|
struct ContactFragments final {
|
||||||
// kept up-to-date by events
|
// kept up-to-date by events
|
||||||
//entt::dense_set<FragmentID> frags;
|
entt::dense_set<FragmentID> frags;
|
||||||
struct InternalEntry {
|
|
||||||
// indecies into the sorted arrays
|
|
||||||
size_t i_b;
|
|
||||||
size_t i_e;
|
|
||||||
};
|
|
||||||
entt::dense_map<FragmentID, InternalEntry> frags;
|
|
||||||
|
|
||||||
// add 2 sorted contact lists for both range begin and end
|
// add 2 sorted contact lists for both range begin and end
|
||||||
std::vector<FragmentID> sorted_begin;
|
|
||||||
std::vector<FragmentID> sorted_end;
|
|
||||||
|
|
||||||
// api
|
|
||||||
// return true if it was actually inserted
|
|
||||||
bool insert(FragmentHandle frag);
|
|
||||||
bool erase(FragmentID frag);
|
|
||||||
// update? (just erase() + insert())
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// all LOADED message fragments
|
// all LOADED message fragments
|
||||||
@ -95,13 +78,12 @@ void MessageFragmentStore::handleMessage(const Message3Handle& m) {
|
|||||||
if (!m.registry()->ctx().contains<Message::Components::OpenFragments>()) {
|
if (!m.registry()->ctx().contains<Message::Components::OpenFragments>()) {
|
||||||
m.registry()->ctx().emplace<Message::Components::OpenFragments>();
|
m.registry()->ctx().emplace<Message::Components::OpenFragments>();
|
||||||
|
|
||||||
#if 0
|
|
||||||
// TODO: move this to async
|
// TODO: move this to async
|
||||||
// TODO: move this to tick and just respect the dirty
|
// TODO: move this to tick and just respect the dirty
|
||||||
FragmentHandle most_recent_fag;
|
FragmentHandle most_recent_fag;
|
||||||
uint64_t most_recent_ts{0};
|
uint64_t most_recent_ts{0};
|
||||||
if (m.registry()->ctx().contains<Message::Components::ContactFragments>()) {
|
if (m.registry()->ctx().contains<Message::Components::ContactFragments>()) {
|
||||||
for (const auto& [fid, si] : m.registry()->ctx().get<Message::Components::ContactFragments>().frags) {
|
for (const auto fid : m.registry()->ctx().get<Message::Components::ContactFragments>().frags) {
|
||||||
auto fh = _fs.fragmentHandle(fid);
|
auto fh = _fs.fragmentHandle(fid);
|
||||||
if (!static_cast<bool>(fh) || !fh.all_of<FragComp::MessagesTSRange, FragComp::MessagesContact>()) {
|
if (!static_cast<bool>(fh) || !fh.all_of<FragComp::MessagesTSRange, FragComp::MessagesContact>()) {
|
||||||
// TODO: remove at this point?
|
// TODO: remove at this point?
|
||||||
@ -110,7 +92,6 @@ void MessageFragmentStore::handleMessage(const Message3Handle& m) {
|
|||||||
|
|
||||||
const uint64_t f_ts = fh.get<FragComp::MessagesTSRange>().begin;
|
const uint64_t f_ts = fh.get<FragComp::MessagesTSRange>().begin;
|
||||||
if (f_ts > most_recent_ts) {
|
if (f_ts > most_recent_ts) {
|
||||||
// this makes no sense, we retry to load the first fragment on every new message and bail here, bc it was already
|
|
||||||
if (m.registry()->ctx().contains<Message::Components::LoadedContactFragments>()) {
|
if (m.registry()->ctx().contains<Message::Components::LoadedContactFragments>()) {
|
||||||
if (m.registry()->ctx().get<Message::Components::LoadedContactFragments>().frags.contains(fh)) {
|
if (m.registry()->ctx().get<Message::Components::LoadedContactFragments>().frags.contains(fh)) {
|
||||||
continue; // already loaded
|
continue; // already loaded
|
||||||
@ -125,7 +106,6 @@ void MessageFragmentStore::handleMessage(const Message3Handle& m) {
|
|||||||
if (static_cast<bool>(most_recent_fag)) {
|
if (static_cast<bool>(most_recent_fag)) {
|
||||||
loadFragment(*m.registry(), most_recent_fag);
|
loadFragment(*m.registry(), most_recent_fag);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& fuid_open = m.registry()->ctx().get<Message::Components::OpenFragments>().fuid_open;
|
auto& fuid_open = m.registry()->ctx().get<Message::Components::OpenFragments>().fuid_open;
|
||||||
@ -213,7 +193,7 @@ void MessageFragmentStore::handleMessage(const Message3Handle& m) {
|
|||||||
if (!m.registry()->ctx().contains<Message::Components::ContactFragments>()) {
|
if (!m.registry()->ctx().contains<Message::Components::ContactFragments>()) {
|
||||||
m.registry()->ctx().emplace<Message::Components::ContactFragments>();
|
m.registry()->ctx().emplace<Message::Components::ContactFragments>();
|
||||||
}
|
}
|
||||||
m.registry()->ctx().get<Message::Components::ContactFragments>().insert(fh);
|
m.registry()->ctx().get<Message::Components::ContactFragments>().frags.emplace(fh);
|
||||||
|
|
||||||
// loaded contact frag
|
// loaded contact frag
|
||||||
if (!m.registry()->ctx().contains<Message::Components::LoadedContactFragments>()) {
|
if (!m.registry()->ctx().contains<Message::Components::LoadedContactFragments>()) {
|
||||||
@ -272,7 +252,7 @@ void MessageFragmentStore::loadFragment(Message3Registry& reg, FragmentHandle fh
|
|||||||
if (!reg.ctx().contains<Message::Components::ContactFragments>()) {
|
if (!reg.ctx().contains<Message::Components::ContactFragments>()) {
|
||||||
reg.ctx().emplace<Message::Components::ContactFragments>();
|
reg.ctx().emplace<Message::Components::ContactFragments>();
|
||||||
}
|
}
|
||||||
reg.ctx().get<Message::Components::ContactFragments>().insert(fh);
|
reg.ctx().get<Message::Components::ContactFragments>().frags.emplace(fh);
|
||||||
|
|
||||||
// mark loaded
|
// mark loaded
|
||||||
if (!reg.ctx().contains<Message::Components::LoadedContactFragments>()) {
|
if (!reg.ctx().contains<Message::Components::LoadedContactFragments>()) {
|
||||||
@ -555,7 +535,7 @@ float MessageFragmentStore::tick(float time_delta) {
|
|||||||
}
|
}
|
||||||
const auto& loaded_frags = msg_reg->ctx().get<Message::Components::LoadedContactFragments>().frags;
|
const auto& loaded_frags = msg_reg->ctx().get<Message::Components::LoadedContactFragments>().frags;
|
||||||
|
|
||||||
for (const auto& [fid, si] : msg_reg->ctx().get<Message::Components::ContactFragments>().frags) {
|
for (const FragmentID fid : msg_reg->ctx().get<Message::Components::ContactFragments>().frags) {
|
||||||
if (loaded_frags.contains(fid)) {
|
if (loaded_frags.contains(fid)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -565,14 +545,14 @@ float MessageFragmentStore::tick(float time_delta) {
|
|||||||
if (!static_cast<bool>(fh)) {
|
if (!static_cast<bool>(fh)) {
|
||||||
std::cerr << "MFS error: frag is invalid\n";
|
std::cerr << "MFS error: frag is invalid\n";
|
||||||
// WHAT
|
// WHAT
|
||||||
msg_reg->ctx().get<Message::Components::ContactFragments>().erase(fid);
|
msg_reg->ctx().get<Message::Components::ContactFragments>().frags.erase(fid);
|
||||||
return 0.05f;
|
return 0.05f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fh.all_of<FragComp::MessagesTSRange>()) {
|
if (!fh.all_of<FragComp::MessagesTSRange>()) {
|
||||||
std::cerr << "MFS error: frag has no range\n";
|
std::cerr << "MFS error: frag has no range\n";
|
||||||
// ????
|
// ????
|
||||||
msg_reg->ctx().get<Message::Components::ContactFragments>().erase(fid);
|
msg_reg->ctx().get<Message::Components::ContactFragments>().frags.erase(fid);
|
||||||
return 0.05f;
|
return 0.05f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -605,7 +585,7 @@ float MessageFragmentStore::tick(float time_delta) {
|
|||||||
uint64_t frag_oldest_ts {};
|
uint64_t frag_oldest_ts {};
|
||||||
|
|
||||||
// find newest frag in range
|
// find newest frag in range
|
||||||
for (const auto& [fid, si] : msg_reg->ctx().get<Message::Components::ContactFragments>().frags) {
|
for (const FragmentID fid : msg_reg->ctx().get<Message::Components::ContactFragments>().frags) {
|
||||||
// we want to find the last and first fragment of the range (if not all hits are loaded, we did something wrong)
|
// we want to find the last and first fragment of the range (if not all hits are loaded, we did something wrong)
|
||||||
if (!loaded_frags.contains(fid)) {
|
if (!loaded_frags.contains(fid)) {
|
||||||
continue;
|
continue;
|
||||||
@ -721,13 +701,12 @@ FragmentID MessageFragmentStore::fragmentBefore(FragmentID fid) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto& mtsrange = fh.get<FragComp::MessagesTSRange>();
|
const auto& mtsrange = fh.get<FragComp::MessagesTSRange>();
|
||||||
const auto& m_c_id = fh.get<FragComp::MessagesContact>().id;
|
|
||||||
const auto& fuid = fh.get<FragComp::ID>();
|
const auto& fuid = fh.get<FragComp::ID>();
|
||||||
|
|
||||||
FragmentHandle current;
|
FragmentHandle current;
|
||||||
|
|
||||||
auto mts_view = fh.registry()->view<FragComp::MessagesTSRange, FragComp::MessagesContact, FragComp::ID>();
|
auto mts_view = fh.registry()->view<FragComp::MessagesTSRange, FragComp::ID>();
|
||||||
for (const auto& [it_f, it_mtsrange, it_m_c_id, it_fuid] : mts_view.each()) {
|
for (const auto& [it_f, it_mtsrange, it_fuid] : mts_view.each()) {
|
||||||
// before means we compare end, so we dont jump over any
|
// before means we compare end, so we dont jump over any
|
||||||
|
|
||||||
if (it_mtsrange.end > mtsrange.end) {
|
if (it_mtsrange.end > mtsrange.end) {
|
||||||
@ -742,11 +721,6 @@ FragmentID MessageFragmentStore::fragmentBefore(FragmentID fid) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// now we check contact (might be less cheap than range check)
|
|
||||||
if (it_m_c_id.id != m_c_id) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// here we know that "it" is before
|
// here we know that "it" is before
|
||||||
// now we check for the largest, so the closest
|
// now we check for the largest, so the closest
|
||||||
|
|
||||||
@ -782,13 +756,12 @@ FragmentID MessageFragmentStore::fragmentAfter(FragmentID fid) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto& mtsrange = fh.get<FragComp::MessagesTSRange>();
|
const auto& mtsrange = fh.get<FragComp::MessagesTSRange>();
|
||||||
const auto& m_c_id = fh.get<FragComp::MessagesContact>().id;
|
|
||||||
const auto& fuid = fh.get<FragComp::ID>();
|
const auto& fuid = fh.get<FragComp::ID>();
|
||||||
|
|
||||||
FragmentHandle current;
|
FragmentHandle current;
|
||||||
|
|
||||||
auto mts_view = fh.registry()->view<FragComp::MessagesTSRange, FragComp::MessagesContact, FragComp::ID>();
|
auto mts_view = fh.registry()->view<FragComp::MessagesTSRange, FragComp::ID>();
|
||||||
for (const auto& [it_f, it_mtsrange, it_m_c_id, it_fuid] : mts_view.each()) {
|
for (const auto& [it_f, it_mtsrange, it_fuid] : mts_view.each()) {
|
||||||
// after means we compare begin
|
// after means we compare begin
|
||||||
|
|
||||||
if (it_mtsrange.begin < mtsrange.begin) {
|
if (it_mtsrange.begin < mtsrange.begin) {
|
||||||
@ -804,11 +777,6 @@ FragmentID MessageFragmentStore::fragmentAfter(FragmentID fid) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// now we check contact (might be less cheap than range check)
|
|
||||||
if (it_m_c_id.id != m_c_id) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// here we know that "it" is after
|
// here we know that "it" is after
|
||||||
// now we check for the smallest, so the closest
|
// now we check for the smallest, so the closest
|
||||||
|
|
||||||
@ -866,6 +834,8 @@ bool MessageFragmentStore::onEvent(const Fragment::Events::FragmentConstruct& e)
|
|||||||
// TODO: id lookup table, this is very inefficent
|
// TODO: id lookup table, this is very inefficent
|
||||||
for (const auto& [c_it, id_it] : _cr.view<Contact::Components::ID>().each()) {
|
for (const auto& [c_it, id_it] : _cr.view<Contact::Components::ID>().each()) {
|
||||||
if (frag_contact_id == id_it.data) {
|
if (frag_contact_id == id_it.data) {
|
||||||
|
//h.emplace_or_replace<Message::Components::ContactTo>(c_it);
|
||||||
|
//return true;
|
||||||
frag_contact = c_it;
|
frag_contact = c_it;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -880,99 +850,16 @@ bool MessageFragmentStore::onEvent(const Fragment::Events::FragmentConstruct& e)
|
|||||||
auto* msg_reg = _rmm.get(frag_contact);
|
auto* msg_reg = _rmm.get(frag_contact);
|
||||||
if (msg_reg == nullptr) {
|
if (msg_reg == nullptr) {
|
||||||
// msg reg not created yet
|
// msg reg not created yet
|
||||||
// TODO: this is an erroious path
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!msg_reg->ctx().contains<Message::Components::ContactFragments>()) {
|
if (!msg_reg->ctx().contains<Message::Components::ContactFragments>()) {
|
||||||
msg_reg->ctx().emplace<Message::Components::ContactFragments>();
|
msg_reg->ctx().emplace<Message::Components::ContactFragments>();
|
||||||
}
|
}
|
||||||
msg_reg->ctx().get<Message::Components::ContactFragments>().insert(e.e);
|
msg_reg->ctx().get<Message::Components::ContactFragments>().frags.emplace(e.e);
|
||||||
|
|
||||||
_event_check_queue.push(ECQueueEntry{e.e, frag_contact});
|
_event_check_queue.push(ECQueueEntry{e.e, frag_contact});
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Message::Components::ContactFragments::insert(FragmentHandle frag) {
|
|
||||||
if (frags.contains(frag)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// both sorted arrays are sorted ascending
|
|
||||||
// so for insertion we search for the last index that is <= and insert after it
|
|
||||||
// or we search for the first > (or end) and insert before it <---
|
|
||||||
// since equal fragments are UB, we can assume they are only > or <
|
|
||||||
|
|
||||||
size_t begin_index {0};
|
|
||||||
{ // begin
|
|
||||||
const auto pos = std::find_if(
|
|
||||||
sorted_begin.cbegin(),
|
|
||||||
sorted_begin.cend(),
|
|
||||||
[frag](const FragmentID a) -> bool {
|
|
||||||
const auto begin_a = frag.registry()->get<FragComp::MessagesTSRange>(a).begin;
|
|
||||||
const auto begin_frag = frag.get<FragComp::MessagesTSRange>().begin;
|
|
||||||
if (begin_a > begin_frag) {
|
|
||||||
return true;
|
|
||||||
} else if (begin_a < begin_frag) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
// equal ts, we need to fall back to id (id can not be equal)
|
|
||||||
return isLess(frag.get<FragComp::ID>().v, frag.registry()->get<FragComp::ID>(a).v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
begin_index = std::distance(sorted_begin.cbegin(), pos);
|
|
||||||
|
|
||||||
// we need to insert before pos (end is valid here)
|
|
||||||
sorted_begin.insert(pos, frag);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t end_index {0};
|
|
||||||
{ // end
|
|
||||||
const auto pos = std::find_if_not(
|
|
||||||
sorted_end.cbegin(),
|
|
||||||
sorted_end.cend(),
|
|
||||||
[frag](const FragmentID a) -> bool {
|
|
||||||
const auto end_a = frag.registry()->get<FragComp::MessagesTSRange>(a).end;
|
|
||||||
const auto end_frag = frag.get<FragComp::MessagesTSRange>().end;
|
|
||||||
if (end_a > end_frag) {
|
|
||||||
return true;
|
|
||||||
} else if (end_a < end_frag) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
// equal ts, we need to fall back to id (id can not be equal)
|
|
||||||
return isLess(frag.get<FragComp::ID>().v, frag.registry()->get<FragComp::ID>(a).v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
end_index = std::distance(sorted_end.cbegin(), pos);
|
|
||||||
|
|
||||||
// we need to insert before pos (end is valid here)
|
|
||||||
sorted_end.insert(pos, frag);
|
|
||||||
}
|
|
||||||
|
|
||||||
frags.emplace(frag, InternalEntry{begin_index, end_index});
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Message::Components::ContactFragments::erase(FragmentID frag) {
|
|
||||||
auto frags_it = frags.find(frag);
|
|
||||||
if (frags_it == frags.end()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(sorted_begin.size() == sorted_end.size());
|
|
||||||
assert(sorted_begin.size() > frags_it->second.i_b);
|
|
||||||
|
|
||||||
sorted_begin.erase(sorted_begin.begin() + frags_it->second.i_b);
|
|
||||||
sorted_end.erase(sorted_end.begin() + frags_it->second.i_e);
|
|
||||||
|
|
||||||
frags.erase(frags_it);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user