Compare commits
No commits in common. "5169ddc2cb4203fc38c9ddd10e740e79744103ca" and "476e7b00a478c5114f15a6762f0825a62e837417" have entirely different histories.
5169ddc2cb
...
476e7b00a4
@ -10,7 +10,6 @@
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
#include <cassert>
|
||||
@ -18,8 +17,6 @@
|
||||
|
||||
// https://youtu.be/CU2exyhYPfA
|
||||
|
||||
// everything assumes a single fragment registry
|
||||
|
||||
namespace Message::Components {
|
||||
|
||||
// ctx
|
||||
@ -35,23 +32,9 @@ namespace Message::Components {
|
||||
// all message fragments of this contact
|
||||
struct ContactFragments final {
|
||||
// kept up-to-date by events
|
||||
//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;
|
||||
entt::dense_set<FragmentID> frags;
|
||||
|
||||
// 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
|
||||
@ -95,13 +78,12 @@ void MessageFragmentStore::handleMessage(const Message3Handle& m) {
|
||||
if (!m.registry()->ctx().contains<Message::Components::OpenFragments>()) {
|
||||
m.registry()->ctx().emplace<Message::Components::OpenFragments>();
|
||||
|
||||
#if 0
|
||||
// TODO: move this to async
|
||||
// TODO: move this to tick and just respect the dirty
|
||||
FragmentHandle most_recent_fag;
|
||||
uint64_t most_recent_ts{0};
|
||||
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);
|
||||
if (!static_cast<bool>(fh) || !fh.all_of<FragComp::MessagesTSRange, FragComp::MessagesContact>()) {
|
||||
// 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;
|
||||
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().get<Message::Components::LoadedContactFragments>().frags.contains(fh)) {
|
||||
continue; // already loaded
|
||||
@ -125,7 +106,6 @@ void MessageFragmentStore::handleMessage(const Message3Handle& m) {
|
||||
if (static_cast<bool>(most_recent_fag)) {
|
||||
loadFragment(*m.registry(), most_recent_fag);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
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>()) {
|
||||
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
|
||||
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>()) {
|
||||
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
|
||||
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;
|
||||
|
||||
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)) {
|
||||
continue;
|
||||
}
|
||||
@ -565,14 +545,14 @@ float MessageFragmentStore::tick(float time_delta) {
|
||||
if (!static_cast<bool>(fh)) {
|
||||
std::cerr << "MFS error: frag is invalid\n";
|
||||
// WHAT
|
||||
msg_reg->ctx().get<Message::Components::ContactFragments>().erase(fid);
|
||||
msg_reg->ctx().get<Message::Components::ContactFragments>().frags.erase(fid);
|
||||
return 0.05f;
|
||||
}
|
||||
|
||||
if (!fh.all_of<FragComp::MessagesTSRange>()) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -605,7 +585,7 @@ float MessageFragmentStore::tick(float time_delta) {
|
||||
uint64_t frag_oldest_ts {};
|
||||
|
||||
// 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)
|
||||
if (!loaded_frags.contains(fid)) {
|
||||
continue;
|
||||
@ -721,13 +701,12 @@ FragmentID MessageFragmentStore::fragmentBefore(FragmentID fid) {
|
||||
}
|
||||
|
||||
const auto& mtsrange = fh.get<FragComp::MessagesTSRange>();
|
||||
const auto& m_c_id = fh.get<FragComp::MessagesContact>().id;
|
||||
const auto& fuid = fh.get<FragComp::ID>();
|
||||
|
||||
FragmentHandle current;
|
||||
|
||||
auto mts_view = fh.registry()->view<FragComp::MessagesTSRange, FragComp::MessagesContact, FragComp::ID>();
|
||||
for (const auto& [it_f, it_mtsrange, it_m_c_id, it_fuid] : mts_view.each()) {
|
||||
auto mts_view = fh.registry()->view<FragComp::MessagesTSRange, FragComp::ID>();
|
||||
for (const auto& [it_f, it_mtsrange, it_fuid] : mts_view.each()) {
|
||||
// before means we compare end, so we dont jump over any
|
||||
|
||||
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
|
||||
// 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& m_c_id = fh.get<FragComp::MessagesContact>().id;
|
||||
const auto& fuid = fh.get<FragComp::ID>();
|
||||
|
||||
FragmentHandle current;
|
||||
|
||||
auto mts_view = fh.registry()->view<FragComp::MessagesTSRange, FragComp::MessagesContact, FragComp::ID>();
|
||||
for (const auto& [it_f, it_mtsrange, it_m_c_id, it_fuid] : mts_view.each()) {
|
||||
auto mts_view = fh.registry()->view<FragComp::MessagesTSRange, FragComp::ID>();
|
||||
for (const auto& [it_f, it_mtsrange, it_fuid] : mts_view.each()) {
|
||||
// after means we compare 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
|
||||
// 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
|
||||
for (const auto& [c_it, id_it] : _cr.view<Contact::Components::ID>().each()) {
|
||||
if (frag_contact_id == id_it.data) {
|
||||
//h.emplace_or_replace<Message::Components::ContactTo>(c_it);
|
||||
//return true;
|
||||
frag_contact = c_it;
|
||||
break;
|
||||
}
|
||||
@ -880,99 +850,16 @@ bool MessageFragmentStore::onEvent(const Fragment::Events::FragmentConstruct& e)
|
||||
auto* msg_reg = _rmm.get(frag_contact);
|
||||
if (msg_reg == nullptr) {
|
||||
// msg reg not created yet
|
||||
// TODO: this is an erroious path
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!msg_reg->ctx().contains<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});
|
||||
|
||||
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