Compare commits
No commits in common. "dc0af844a13f2c59ec65fba5ad293539fbada36d" and "50db703d78ceaaef43c82e2e4198500d23e1de7e" have entirely different histories.
dc0af844a1
...
50db703d78
21
LICENSE
21
LICENSE
@ -1,21 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2025 Erik Scholz
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
@ -34,7 +34,7 @@ SOLANA_PLUGIN_EXPORT uint32_t solana_plugin_start(struct SolanaAPI* solana_api)
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto* cs = PLUG_RESOLVE_INSTANCE(ContactStore4I);
|
auto* cr = PLUG_RESOLVE_INSTANCE_VERSIONED(Contact3Registry, "1");
|
||||||
auto* rmm = PLUG_RESOLVE_INSTANCE(RegistryMessageModelI);
|
auto* rmm = PLUG_RESOLVE_INSTANCE(RegistryMessageModelI);
|
||||||
auto* os = PLUG_RESOLVE_INSTANCE(ObjectStore2);
|
auto* os = PLUG_RESOLVE_INSTANCE(ObjectStore2);
|
||||||
auto* msnj = PLUG_RESOLVE_INSTANCE(MessageSerializerNJ);
|
auto* msnj = PLUG_RESOLVE_INSTANCE(MessageSerializerNJ);
|
||||||
@ -42,7 +42,7 @@ SOLANA_PLUGIN_EXPORT uint32_t solana_plugin_start(struct SolanaAPI* solana_api)
|
|||||||
// static store, could be anywhere tho
|
// static store, could be anywhere tho
|
||||||
// construct with fetched dependencies
|
// construct with fetched dependencies
|
||||||
g_fsb = std::make_unique<Backends::FilesystemStorage>(*os, "test2_message_store/"); // TODO: use config?
|
g_fsb = std::make_unique<Backends::FilesystemStorage>(*os, "test2_message_store/"); // TODO: use config?
|
||||||
g_mfs = std::make_unique<MessageFragmentStore>(*cs, *rmm, *os, *g_fsb, *g_fsb, *msnj);
|
g_mfs = std::make_unique<MessageFragmentStore>(*cr, *rmm, *os, *g_fsb, *g_fsb, *msnj);
|
||||||
|
|
||||||
// register types
|
// register types
|
||||||
PLUG_PROVIDE_INSTANCE(MessageFragmentStore, plugin_name, g_mfs.get());
|
PLUG_PROVIDE_INSTANCE(MessageFragmentStore, plugin_name, g_mfs.get());
|
||||||
|
@ -28,7 +28,6 @@ add_executable(convert_message_object_store
|
|||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(convert_message_object_store PUBLIC
|
target_link_libraries(convert_message_object_store PUBLIC
|
||||||
solanaceae_contact_impl
|
|
||||||
solanaceae_object_store
|
solanaceae_object_store
|
||||||
solanaceae_object_store_backend_filesystem
|
solanaceae_object_store_backend_filesystem
|
||||||
solanaceae_message_fragment_store
|
solanaceae_message_fragment_store
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
#include <solanaceae/contact/contact_store_impl.hpp>
|
|
||||||
#include <solanaceae/object_store/object_store.hpp>
|
#include <solanaceae/object_store/object_store.hpp>
|
||||||
#include <solanaceae/object_store/backends/filesystem_storage.hpp>
|
#include <solanaceae/object_store/backends/filesystem_storage.hpp>
|
||||||
#include <solanaceae/object_store/meta_components.hpp>
|
#include <solanaceae/object_store/meta_components.hpp>
|
||||||
@ -36,14 +35,14 @@ int main(int argc, const char** argv) {
|
|||||||
Backends::FilesystemStorage fsb_src(os_src, argv[1]);
|
Backends::FilesystemStorage fsb_src(os_src, argv[1]);
|
||||||
Backends::FilesystemStorage fsb_dst(os_dst, argv[2]);
|
Backends::FilesystemStorage fsb_dst(os_dst, argv[2]);
|
||||||
|
|
||||||
ContactStore4Impl cs; // dummy
|
Contact3Registry cr; // dummy
|
||||||
RegistryMessageModelImpl rmm(cs); // dummy
|
RegistryMessageModelImpl rmm(cr); // dummy
|
||||||
// they only exist for the serializers (for now)
|
// they only exist for the serializers (for now)
|
||||||
// TODO: version
|
// TODO: version
|
||||||
MessageSerializerNJ msnj_src{cs, os_src, {}, {}};
|
MessageSerializerNJ msnj_src{cr, os_src, {}, {}};
|
||||||
MessageFragmentStore mfs_src(cs, rmm, os_src, fsb_src, fsb_src, msnj_src);
|
MessageFragmentStore mfs_src(cr, rmm, os_src, fsb_src, fsb_src, msnj_src);
|
||||||
MessageSerializerNJ msnj_dst{cs, os_dst, {}, {}};
|
MessageSerializerNJ msnj_dst{cr, os_dst, {}, {}};
|
||||||
MessageFragmentStore mfs_dst(cs, rmm, os_dst, fsb_dst, fsb_dst, msnj_dst);
|
MessageFragmentStore mfs_dst(cr, rmm, os_dst, fsb_dst, fsb_dst, msnj_dst);
|
||||||
|
|
||||||
// add message fragment store too (adds meta?)
|
// add message fragment store too (adds meta?)
|
||||||
|
|
||||||
|
@ -9,8 +9,6 @@
|
|||||||
#include <solanaceae/util/utils.hpp>
|
#include <solanaceae/util/utils.hpp>
|
||||||
#include <solanaceae/util/time.hpp>
|
#include <solanaceae/util/time.hpp>
|
||||||
|
|
||||||
#include <solanaceae/contact/contact_store_i.hpp>
|
|
||||||
|
|
||||||
#include <solanaceae/contact/components.hpp>
|
#include <solanaceae/contact/components.hpp>
|
||||||
#include <solanaceae/message3/components.hpp>
|
#include <solanaceae/message3/components.hpp>
|
||||||
#include <solanaceae/message3/contact_components.hpp>
|
#include <solanaceae/message3/contact_components.hpp>
|
||||||
@ -39,7 +37,7 @@ namespace ObjectStore::Components {
|
|||||||
|
|
||||||
// cache the contact for faster lookups
|
// cache the contact for faster lookups
|
||||||
struct MessagesContactEntity {
|
struct MessagesContactEntity {
|
||||||
Contact4 e {entt::null};
|
Contact3 e {entt::null};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} // ObjectStore::Component
|
} // ObjectStore::Component
|
||||||
@ -85,8 +83,8 @@ void MessageFragmentStore::handleMessage(const Message3Handle& m) {
|
|||||||
return; // we only handle msg with ts
|
return; // we only handle msg with ts
|
||||||
}
|
}
|
||||||
|
|
||||||
_potentially_dirty_contacts.emplace(m.registry()->ctx().get<Contact4>()); // always mark dirty here
|
_potentially_dirty_contacts.emplace(m.registry()->ctx().get<Contact3>()); // always mark dirty here
|
||||||
_touched_contacts.emplace(m.registry()->ctx().get<Contact4>());
|
_touched_contacts.emplace(m.registry()->ctx().get<Contact3>());
|
||||||
if (m.any_of<Message::Components::ViewCurserBegin, Message::Components::ViewCurserEnd>()) {
|
if (m.any_of<Message::Components::ViewCurserBegin, Message::Components::ViewCurserEnd>()) {
|
||||||
// not an actual message, but we probalby need to check and see if we need to load fragments
|
// not an actual message, but we probalby need to check and see if we need to load fragments
|
||||||
//std::cout << "MFS: new or updated curser\n";
|
//std::cout << "MFS: new or updated curser\n";
|
||||||
@ -208,9 +206,9 @@ void MessageFragmentStore::handleMessage(const Message3Handle& m) {
|
|||||||
new_ts_range.end = msg_ts;
|
new_ts_range.end = msg_ts;
|
||||||
|
|
||||||
{
|
{
|
||||||
const auto msg_reg_contact = m.registry()->ctx().get<Contact4>();
|
const auto msg_reg_contact = m.registry()->ctx().get<Contact3>();
|
||||||
if (_cs.registry().all_of<Contact::Components::ID>(msg_reg_contact)) {
|
if (_cr.all_of<Contact::Components::ID>(msg_reg_contact)) {
|
||||||
fh.emplace<ObjComp::MessagesContact>(_cs.registry().get<Contact::Components::ID>(msg_reg_contact).data);
|
fh.emplace<ObjComp::MessagesContact>(_cr.get<Contact::Components::ID>(msg_reg_contact).data);
|
||||||
} else {
|
} else {
|
||||||
// ? rage quit?
|
// ? rage quit?
|
||||||
}
|
}
|
||||||
@ -366,10 +364,10 @@ void MessageFragmentStore::loadFragment(Message3Registry& reg, ObjectHandle fh)
|
|||||||
Message3 dup_msg {entt::null};
|
Message3 dup_msg {entt::null};
|
||||||
{
|
{
|
||||||
// get comparator from contact
|
// get comparator from contact
|
||||||
if (reg.ctx().contains<Contact4>()) {
|
if (reg.ctx().contains<Contact3>()) {
|
||||||
const auto c = reg.ctx().get<Contact4>();
|
const auto c = reg.ctx().get<Contact3>();
|
||||||
if (_cs.registry().all_of<Contact::Components::MessageIsSame>(c)) {
|
if (_cr.all_of<Contact::Components::MessageIsSame>(c)) {
|
||||||
auto& comp = _cs.registry().get<Contact::Components::MessageIsSame>(c).comp;
|
auto& comp = _cr.get<Contact::Components::MessageIsSame>(c).comp;
|
||||||
// walking EVERY existing message OOF
|
// walking EVERY existing message OOF
|
||||||
// this needs optimizing
|
// this needs optimizing
|
||||||
for (const Message3 other_msg : reg.view<Message::Components::Timestamp, Message::Components::ContactFrom, Message::Components::ContactTo>()) {
|
for (const Message3 other_msg : reg.view<Message::Components::Timestamp, Message::Components::ContactFrom, Message::Components::ContactTo>()) {
|
||||||
@ -506,13 +504,13 @@ bool MessageFragmentStore::syncFragToStorage(ObjectHandle fh, Message3Registry&
|
|||||||
}
|
}
|
||||||
|
|
||||||
MessageFragmentStore::MessageFragmentStore(
|
MessageFragmentStore::MessageFragmentStore(
|
||||||
ContactStore4I& cs,
|
Contact3Registry& cr,
|
||||||
RegistryMessageModelI& rmm,
|
RegistryMessageModelI& rmm,
|
||||||
ObjectStore2& os,
|
ObjectStore2& os,
|
||||||
StorageBackendIMeta& sbm,
|
StorageBackendIMeta& sbm,
|
||||||
StorageBackendIAtomic& sba,
|
StorageBackendIAtomic& sba,
|
||||||
MessageSerializerNJ& scnj
|
MessageSerializerNJ& scnj
|
||||||
) : _cs(cs), _rmm(rmm), _rmm_sr(_rmm.newSubRef(this)), _os(os), _os_sr(_os.newSubRef(this)), _sbm(sbm), _sba(sba), _scnj(scnj) {
|
) : _cr(cr), _rmm(rmm), _rmm_sr(_rmm.newSubRef(this)), _os(os), _os_sr(_os.newSubRef(this)), _sbm(sbm), _sba(sba), _scnj(scnj) {
|
||||||
_rmm_sr
|
_rmm_sr
|
||||||
.subscribe(RegistryMessageModel_Event::message_construct)
|
.subscribe(RegistryMessageModel_Event::message_construct)
|
||||||
.subscribe(RegistryMessageModel_Event::message_updated)
|
.subscribe(RegistryMessageModel_Event::message_updated)
|
||||||
@ -869,17 +867,17 @@ bool MessageFragmentStore::onEvent(const ObjectStore::Events::ObjectConstruct& e
|
|||||||
|
|
||||||
// TODO: are we sure it is a *new* fragment?
|
// TODO: are we sure it is a *new* fragment?
|
||||||
|
|
||||||
Contact4 frag_contact = entt::null;
|
Contact3 frag_contact = entt::null;
|
||||||
{ // get contact
|
{ // get contact
|
||||||
const auto& frag_contact_id = e.e.get<ObjComp::MessagesContact>().id;
|
const auto& frag_contact_id = e.e.get<ObjComp::MessagesContact>().id;
|
||||||
// TODO: id lookup table, this is very inefficent
|
// TODO: id lookup table, this is very inefficent
|
||||||
for (const auto& [c_it, id_it] : _cs.registry().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) {
|
||||||
frag_contact = c_it;
|
frag_contact = c_it;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!_cs.registry().valid(frag_contact)) {
|
if (!_cr.valid(frag_contact)) {
|
||||||
// unkown contact
|
// unkown contact
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -919,23 +917,23 @@ bool MessageFragmentStore::onEvent(const ObjectStore::Events::ObjectUpdate& e) {
|
|||||||
// its also possible it was tagged as empty
|
// its also possible it was tagged as empty
|
||||||
e.e.remove<ObjComp::Ephemeral::MessagesEmptyTag>();
|
e.e.remove<ObjComp::Ephemeral::MessagesEmptyTag>();
|
||||||
|
|
||||||
Contact4 frag_contact = entt::null;
|
Contact3 frag_contact = entt::null;
|
||||||
{ // get contact
|
{ // get contact
|
||||||
// probably cached already
|
// probably cached already
|
||||||
if (e.e.all_of<ObjComp::Ephemeral::MessagesContactEntity>()) {
|
if (e.e.all_of<ObjComp::Ephemeral::MessagesContactEntity>()) {
|
||||||
frag_contact = e.e.get<ObjComp::Ephemeral::MessagesContactEntity>().e;
|
frag_contact = e.e.get<ObjComp::Ephemeral::MessagesContactEntity>().e;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_cs.registry().valid(frag_contact)) {
|
if (!_cr.valid(frag_contact)) {
|
||||||
const auto& frag_contact_id = e.e.get<ObjComp::MessagesContact>().id;
|
const auto& frag_contact_id = e.e.get<ObjComp::MessagesContact>().id;
|
||||||
// TODO: id lookup table, this is very inefficent
|
// TODO: id lookup table, this is very inefficent
|
||||||
for (const auto& [c_it, id_it] : _cs.registry().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) {
|
||||||
frag_contact = c_it;
|
frag_contact = c_it;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!_cs.registry().valid(frag_contact)) {
|
if (!_cr.valid(frag_contact)) {
|
||||||
// unkown contact
|
// unkown contact
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#include <entt/container/dense_map.hpp>
|
#include <entt/container/dense_map.hpp>
|
||||||
#include <entt/container/dense_set.hpp>
|
#include <entt/container/dense_set.hpp>
|
||||||
|
|
||||||
#include <solanaceae/contact/fwd.hpp>
|
#include <solanaceae/contact/contact_model3.hpp>
|
||||||
#include <solanaceae/message3/registry_message_model.hpp>
|
#include <solanaceae/message3/registry_message_model.hpp>
|
||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
@ -50,7 +50,7 @@ class MessageFragmentStore : public RegistryMessageModelEventI, public ObjectSto
|
|||||||
static constexpr const char* version {"3"};
|
static constexpr const char* version {"3"};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ContactStore4I& _cs;
|
Contact3Registry& _cr;
|
||||||
RegistryMessageModelI& _rmm;
|
RegistryMessageModelI& _rmm;
|
||||||
RegistryMessageModelI::SubscriptionReference _rmm_sr;
|
RegistryMessageModelI::SubscriptionReference _rmm_sr;
|
||||||
ObjectStore2& _os;
|
ObjectStore2& _os;
|
||||||
@ -78,21 +78,21 @@ class MessageFragmentStore : public RegistryMessageModelEventI, public ObjectSto
|
|||||||
|
|
||||||
struct ECQueueEntry final {
|
struct ECQueueEntry final {
|
||||||
ObjectHandle fid;
|
ObjectHandle fid;
|
||||||
Contact4 c;
|
Contact3 c;
|
||||||
};
|
};
|
||||||
std::deque<ECQueueEntry> _event_check_queue;
|
std::deque<ECQueueEntry> _event_check_queue;
|
||||||
|
|
||||||
// range changed or fragment loaded.
|
// range changed or fragment loaded.
|
||||||
// we only load a limited number of fragments at once,
|
// we only load a limited number of fragments at once,
|
||||||
// so we need to keep them dirty until nothing was loaded.
|
// so we need to keep them dirty until nothing was loaded.
|
||||||
entt::dense_set<Contact4> _potentially_dirty_contacts;
|
entt::dense_set<Contact3> _potentially_dirty_contacts;
|
||||||
|
|
||||||
// for cleaning up the ctx vars we create
|
// for cleaning up the ctx vars we create
|
||||||
entt::dense_set<Contact4> _touched_contacts;
|
entt::dense_set<Contact3> _touched_contacts;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MessageFragmentStore(
|
MessageFragmentStore(
|
||||||
ContactStore4I& cr,
|
Contact3Registry& cr,
|
||||||
RegistryMessageModelI& rmm,
|
RegistryMessageModelI& rmm,
|
||||||
ObjectStore2& os,
|
ObjectStore2& os,
|
||||||
StorageBackendIMeta& sbm,
|
StorageBackendIMeta& sbm,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user