diff --git a/src/solanaceae/crdtnotes/crdtnotes.hpp b/src/solanaceae/crdtnotes/crdtnotes.hpp index 26b0bb9..0d3dece 100644 --- a/src/solanaceae/crdtnotes/crdtnotes.hpp +++ b/src/solanaceae/crdtnotes/crdtnotes.hpp @@ -37,6 +37,7 @@ class CRDTNotes { struct Frontier { // newest known seq for given agent CRDTAgent agent; uint64_t seq{0}; + uint64_t del_num{0}; }; // RAII lock wrapper diff --git a/src/solanaceae/crdtnotes/crdtnotes_contact_sync_model.hpp b/src/solanaceae/crdtnotes/crdtnotes_contact_sync_model.hpp index 11103e8..3845799 100644 --- a/src/solanaceae/crdtnotes/crdtnotes_contact_sync_model.hpp +++ b/src/solanaceae/crdtnotes/crdtnotes_contact_sync_model.hpp @@ -19,7 +19,7 @@ struct CRDTNotesContactSyncModelI { virtual void SendGossip( ContactHandle4 c, const CRDTNotes::DocID& doc_id, - const std::vector& selected_frontier + const std::vector& frontier ) = 0; // fetch @@ -31,7 +31,7 @@ struct CRDTNotesContactSyncModelI { ) = 0; // action range request - virtual void SendFetchOps( + virtual void SendFetchAddRange( ContactHandle4 c, const CRDTNotes::DocID& doc_id, const CRDTNotes::CRDTAgent& agent, @@ -39,6 +39,12 @@ struct CRDTNotesContactSyncModelI { const uint64_t seq_to ) = 0; + virtual void SendFetchDel( + ContactHandle4 c, + const CRDTNotes::DocID& doc_id, + const CRDTNotes::CRDTAgent& agent + ) = 0; + public: // ops response virtual void SendOps( ContactHandle4 c, diff --git a/src/solanaceae/crdtnotes/crdtnotes_sync.cpp b/src/solanaceae/crdtnotes/crdtnotes_sync.cpp index 08d3303..cde802b 100644 --- a/src/solanaceae/crdtnotes/crdtnotes_sync.cpp +++ b/src/solanaceae/crdtnotes/crdtnotes_sync.cpp @@ -324,7 +324,10 @@ void CRDTNotesSync::onCRDTNSyncEvent(Events::NGCEXT_crdtns_gossip_frontier&& e) void CRDTNotesSync::onCRDTNSyncEvent(Events::NGCEXT_crdtns_fetch_complete_frontier&& e) { } -void CRDTNotesSync::onCRDTNSyncEvent(Events::NGCEXT_crdtns_fetch_op_range&& e) { +void CRDTNotesSync::onCRDTNSyncEvent(Events::NGCEXT_crdtns_fetch_add_range&& e) { +} + +void CRDTNotesSync::onCRDTNSyncEvent(Events::NGCEXT_crdtns_fetch_del&& e) { } void CRDTNotesSync::onCRDTNSyncEvent(Events::NGCEXT_crdtns_ops&& e) { diff --git a/src/solanaceae/crdtnotes/crdtnotes_sync.hpp b/src/solanaceae/crdtnotes/crdtnotes_sync.hpp index 75ac45c..33607e8 100644 --- a/src/solanaceae/crdtnotes/crdtnotes_sync.hpp +++ b/src/solanaceae/crdtnotes/crdtnotes_sync.hpp @@ -27,11 +27,12 @@ namespace Events { // - array [ // - AgentID // - seq (frontier) + // - del_num // - ] struct NGCEXT_crdtns_gossip_frontier { ContactHandle4 c; CRDTNotes::DocID doc_id; - std::vector selected_frontier; + std::vector frontier; }; // - DocID @@ -44,7 +45,7 @@ namespace Events { // - AgentID // - seq_from // - seq_to - struct NGCEXT_crdtns_fetch_op_range { + struct NGCEXT_crdtns_fetch_add_range { ContactHandle4 c; CRDTNotes::DocID doc_id; CRDTNotes::CRDTAgent agent; @@ -52,6 +53,14 @@ namespace Events { uint64_t seq_to; }; + // - DocID + // - AgentID + struct NGCEXT_crdtns_fetch_del { + ContactHandle4 c; + CRDTNotes::DocID doc_id; + CRDTNotes::CRDTAgent agent; + }; + // - DocID // - array [ // - op @@ -76,7 +85,8 @@ struct CRDTNotesEventI { virtual void onCRDTNSyncEvent(Events::NGCEXT_crdtns_gossip&& e) = 0; virtual void onCRDTNSyncEvent(Events::NGCEXT_crdtns_gossip_frontier&& e) = 0; virtual void onCRDTNSyncEvent(Events::NGCEXT_crdtns_fetch_complete_frontier&& e) = 0; - virtual void onCRDTNSyncEvent(Events::NGCEXT_crdtns_fetch_op_range&& e) = 0; + virtual void onCRDTNSyncEvent(Events::NGCEXT_crdtns_fetch_add_range&& e) = 0; + virtual void onCRDTNSyncEvent(Events::NGCEXT_crdtns_fetch_del&& e) = 0; virtual void onCRDTNSyncEvent(Events::NGCEXT_crdtns_ops&& e) = 0; }; @@ -133,7 +143,8 @@ class CRDTNotesSync final : public CRDTNotesEventI { void onCRDTNSyncEvent(Events::NGCEXT_crdtns_gossip&& e) override; void onCRDTNSyncEvent(Events::NGCEXT_crdtns_gossip_frontier&& e) override; void onCRDTNSyncEvent(Events::NGCEXT_crdtns_fetch_complete_frontier&& e) override; - void onCRDTNSyncEvent(Events::NGCEXT_crdtns_fetch_op_range&& e) override; + void onCRDTNSyncEvent(Events::NGCEXT_crdtns_fetch_add_range&& e) override; + void onCRDTNSyncEvent(Events::NGCEXT_crdtns_fetch_del&& e) override; void onCRDTNSyncEvent(Events::NGCEXT_crdtns_ops&& e) override; }; diff --git a/src/solanaceae/crdtnotes_toxsync/crdtnotes_toxsync.cpp b/src/solanaceae/crdtnotes_toxsync/crdtnotes_toxsync.cpp index ba54b1d..9e97259 100644 --- a/src/solanaceae/crdtnotes_toxsync/crdtnotes_toxsync.cpp +++ b/src/solanaceae/crdtnotes_toxsync/crdtnotes_toxsync.cpp @@ -16,6 +16,7 @@ enum class NGCEXT_Event : uint8_t { // - array [ // - AgentID // - seq (frontier) + // - del_num // - ] CRDTN_GOSSIP_FRONTIER, @@ -26,7 +27,11 @@ enum class NGCEXT_Event : uint8_t { // - AgentID // - seq_from // - seq_to - CRDTN_FETCH_OP_RANGE, + CRDTN_FETCH_ADD_RANGE, + + // - DocID + // - AgentID + CRDTN_FETCH_DEL, // - DocID // - array [ @@ -101,7 +106,7 @@ void CRDTNotesToxSync::SendGossip( void CRDTNotesToxSync::SendGossip( ContactHandle4 c, const CRDTNotes::DocID& doc_id, - const std::vector& selected_frontier + const std::vector& frontier ) { if (!c.all_of()) { return; @@ -117,7 +122,7 @@ void CRDTNotesToxSync::SendGossip( } // +32 - for (const auto& [f_id, f_seq] : selected_frontier) { + for (const auto& [f_id, f_seq, del_num] : frontier) { for (const uint8_t v : f_id) { pkg.push_back(v); } @@ -127,8 +132,13 @@ void CRDTNotesToxSync::SendGossip( pkg.push_back((f_seq >> i*8) & 0xff); } // +8 + + for (size_t i = 0; i < sizeof(del_num); i++) { + pkg.push_back((del_num >> i*8) & 0xff); + } + // +8 } - // +40 + // +48 // send const auto& gp = c.get(); @@ -164,7 +174,7 @@ void CRDTNotesToxSync::SendFetchCompleteFrontier( ); } -void CRDTNotesToxSync::SendFetchOps( +void CRDTNotesToxSync::SendFetchAddRange( ContactHandle4 c, const CRDTNotes::DocID& doc_id, const CRDTNotes::CRDTAgent& agent, @@ -177,7 +187,7 @@ void CRDTNotesToxSync::SendFetchOps( std::vector pkg; - pkg.push_back(static_cast(NGCEXT_Event::CRDTN_FETCH_OP_RANGE)); + pkg.push_back(static_cast(NGCEXT_Event::CRDTN_FETCH_ADD_RANGE)); for (const uint8_t v : doc_id) { pkg.push_back(v); @@ -207,6 +217,35 @@ void CRDTNotesToxSync::SendFetchOps( ); } +void CRDTNotesToxSync::SendFetchDel( + ContactHandle4 c, + const CRDTNotes::DocID& doc_id, + const CRDTNotes::CRDTAgent& agent +) { + if (!c.all_of()) { + return; + } + + std::vector pkg; + + pkg.push_back(static_cast(NGCEXT_Event::CRDTN_FETCH_DEL)); + + for (const uint8_t v : doc_id) { + pkg.push_back(v); + } + + for (const uint8_t v : agent) { + pkg.push_back(v); + } + + const auto& gp = c.get(); + _t.toxGroupSendCustomPrivatePacket( + gp.group_number, gp.peer_number, + true, + pkg + ); +} + void CRDTNotesToxSync::SendOps( ContactHandle4 c, const CRDTNotes::DocID& doc_id, @@ -228,6 +267,7 @@ void CRDTNotesToxSync::SendOps( // this is very inefficent // a full add op is 124bytes like this + // a full del op is 41bytes for (const auto& op : ops) { if(std::holds_alternative(op)) { const auto& add_op = std::get(op); @@ -332,7 +372,7 @@ bool CRDTNotesToxSync::parse_crdtn_gossip_frontier( while (curser < data_size) { CRDTNotes::Frontier new_f; - _DATA_HAVE(new_f.agent.size() * sizeof(CRDTNotes::CRDTAgent::value_type) + sizeof(new_f.seq), std::cerr << "NGCEXT: packet malformed, not enough data for forntier\n"; return false;) + _DATA_HAVE(new_f.agent.size() * sizeof(CRDTNotes::CRDTAgent::value_type) + sizeof(new_f.seq) + sizeof(new_f.del_num), std::cerr << "NGCEXT: packet malformed, not enough data for frontier\n"; return false;) for (size_t i = 0; i < new_f.agent.size(); i++, curser++) { new_f.agent[i] = data[curser]; @@ -343,7 +383,12 @@ bool CRDTNotesToxSync::parse_crdtn_gossip_frontier( new_f.seq |= uint64_t(data[curser]) << i*8; } - e.selected_frontier.emplace_back(std::move(new_f)); + new_f.del_num = 0; + for (size_t i = 0; i < sizeof(new_f.del_num); i++, curser++) { + new_f.del_num |= uint64_t(data[curser]) << i*8; + } + + e.frontier.emplace_back(std::move(new_f)); } std::cout << "CRDTN gossip_frontier parsed\n"; @@ -371,12 +416,12 @@ bool CRDTNotesToxSync::parse_crdtn_fetch_complete_frontier( return true; } -bool CRDTNotesToxSync::parse_crdtn_fetch_op_range( +bool CRDTNotesToxSync::parse_crdtn_fetch_add_range( ContactHandle4 c, const uint8_t* data, size_t data_size, bool // dont care private ) { - Events::NGCEXT_crdtns_fetch_op_range e; + Events::NGCEXT_crdtns_fetch_add_range e; e.c = c; size_t curser = 0; @@ -403,7 +448,32 @@ bool CRDTNotesToxSync::parse_crdtn_fetch_op_range( e.seq_to |= uint64_t(data[curser]) << i*8; } - std::cout << "CRDTN fetch_op_range parsed\n"; + std::cout << "CRDTN fetch_add_range parsed\n"; + _notes_sync.onCRDTNSyncEvent(std::move(e)); + return true; +} + +bool CRDTNotesToxSync::parse_crdtn_fetch_del( + ContactHandle4 c, + const uint8_t* data, size_t data_size, + bool // dont care private +) { + Events::NGCEXT_crdtns_fetch_del e; + e.c = c; + + size_t curser = 0; + + _DATA_HAVE(e.doc_id.size() * sizeof(decltype(e.doc_id)::value_type), std::cerr << "NGCEXT: packet too small, missing doc_id\n"; return false;) + for (size_t i = 0; i < e.doc_id.size(); i++, curser++) { + e.doc_id[i] = data[curser]; + } + + _DATA_HAVE(e.agent.size() * sizeof(decltype(e.agent)::value_type), std::cerr << "NGCEXT: packet too small, missing agent\n"; return false;) + for (size_t i = 0; i < e.agent.size(); i++, curser++) { + e.agent[i] = data[curser]; + } + + std::cout << "CRDTN fetch_del parsed\n"; _notes_sync.onCRDTNSyncEvent(std::move(e)); return true; } @@ -531,8 +601,10 @@ bool CRDTNotesToxSync::handlePacket( return parse_crdtn_gossip_frontier(c, data+1, data_size-1, _private); case NGCEXT_Event::CRDTN_FETCH_COMPLETE_FRONTIER: return parse_crdtn_fetch_complete_frontier(c, data+1, data_size-1, _private); - case NGCEXT_Event::CRDTN_FETCH_OP_RANGE: - return parse_crdtn_fetch_op_range(c, data+1, data_size-1, _private); + case NGCEXT_Event::CRDTN_FETCH_ADD_RANGE: + return parse_crdtn_fetch_add_range(c, data+1, data_size-1, _private); + case NGCEXT_Event::CRDTN_FETCH_DEL: + return parse_crdtn_fetch_del(c, data+1, data_size-1, _private); case NGCEXT_Event::CRDTN_OPS: return parse_crdtn_ops(c, data+1, data_size-1, _private); default: diff --git a/src/solanaceae/crdtnotes_toxsync/crdtnotes_toxsync.hpp b/src/solanaceae/crdtnotes_toxsync/crdtnotes_toxsync.hpp index 1856e55..6dda1f1 100644 --- a/src/solanaceae/crdtnotes_toxsync/crdtnotes_toxsync.hpp +++ b/src/solanaceae/crdtnotes_toxsync/crdtnotes_toxsync.hpp @@ -39,7 +39,7 @@ class CRDTNotesToxSync : public CRDTNotesContactSyncModelI, public ToxEventI { void SendGossip( ContactHandle4 c, const CRDTNotes::DocID& doc_id, - const std::vector& selected_frontier + const std::vector& frontier ) override; void SendFetchCompleteFrontier( @@ -47,7 +47,7 @@ class CRDTNotesToxSync : public CRDTNotesContactSyncModelI, public ToxEventI { const CRDTNotes::DocID& doc_id ) override; - void SendFetchOps( + void SendFetchAddRange( ContactHandle4 c, const CRDTNotes::DocID& doc_id, const CRDTNotes::CRDTAgent& agent, @@ -55,6 +55,12 @@ class CRDTNotesToxSync : public CRDTNotesContactSyncModelI, public ToxEventI { const uint64_t seq_to ) override; + void SendFetchDel( + ContactHandle4 c, + const CRDTNotes::DocID& doc_id, + const CRDTNotes::CRDTAgent& agent + ) override; + void SendOps( ContactHandle4 c, const CRDTNotes::DocID& doc_id, @@ -77,7 +83,12 @@ class CRDTNotesToxSync : public CRDTNotesContactSyncModelI, public ToxEventI { const uint8_t* data, size_t data_size, bool _private ); - bool parse_crdtn_fetch_op_range( + bool parse_crdtn_fetch_add_range( + ContactHandle4 c, + const uint8_t* data, size_t data_size, + bool _private + ); + bool parse_crdtn_fetch_del( ContactHandle4 c, const uint8_t* data, size_t data_size, bool _private