mirror of
https://github.com/basiliscos/syncspirit.git
synced 2026-05-02 17:42:26 +00:00
core: refactor remote_folder_info -> remove_view
This commit is contained in:
+2
-2
@@ -151,7 +151,6 @@ add_library(syncspirit_core
|
||||
src/model/diff/local/synchronization_finish.cpp
|
||||
src/model/diff/local/synchronization_start.cpp
|
||||
src/model/diff/modify/add_blocks.cpp
|
||||
src/model/diff/modify/add_remote_folder_infos.cpp
|
||||
src/model/diff/modify/add_ignored_device.cpp
|
||||
src/model/diff/modify/add_pending_device.cpp
|
||||
src/model/diff/modify/add_pending_folders.cpp
|
||||
@@ -177,6 +176,7 @@ add_library(syncspirit_core
|
||||
src/model/diff/peer/cluster_update.cpp
|
||||
src/model/diff/peer/rx_tx.cpp
|
||||
src/model/diff/peer/update_folder.cpp
|
||||
src/model/diff/peer/update_remote_views.cpp
|
||||
src/model/misc/augmentation.cpp
|
||||
src/model/misc/block_iterator.cpp
|
||||
src/model/misc/error_code.cpp
|
||||
@@ -202,7 +202,7 @@ add_library(syncspirit_core
|
||||
src/model/ignored_folder.cpp
|
||||
src/model/pending_device.cpp
|
||||
src/model/pending_folder.cpp
|
||||
src/model/remote_folder_info.cpp
|
||||
src/model/remote_view.cpp
|
||||
src/model/some_device.cpp
|
||||
src/model/version.cpp
|
||||
src/net/acceptor_actor.cpp
|
||||
|
||||
+3
-3
@@ -7,7 +7,7 @@
|
||||
#include "misc/map.hpp"
|
||||
#include "device_id.h"
|
||||
#include "device_state.h"
|
||||
#include "remote_folder_info.h"
|
||||
#include "remote_view.h"
|
||||
#include "utils/uri.h"
|
||||
#include "utils/bytes.h"
|
||||
#include "syncspirit-export.h"
|
||||
@@ -58,7 +58,7 @@ struct SYNCSPIRIT_API device_t : augmentable_t {
|
||||
inline bool has_auto_accept() const noexcept { return auto_accept; }
|
||||
inline bool is_paused() const noexcept { return paused; }
|
||||
inline bool get_skip_introduction_removals() const noexcept { return skip_introduction_removals; }
|
||||
inline auto &get_remote_folder_infos() noexcept { return remote_folder_infos; }
|
||||
inline auto &get_remote_view_map() noexcept { return remote_view_map; }
|
||||
inline const pt::ptime &get_last_seen() const noexcept { return last_seen; }
|
||||
|
||||
inline const uris_t &get_uris() const noexcept { return uris; }
|
||||
@@ -98,7 +98,7 @@ struct SYNCSPIRIT_API device_t : augmentable_t {
|
||||
|
||||
file_iterator_ptr_t iterator;
|
||||
|
||||
remote_folder_infos_map_t remote_folder_infos;
|
||||
remote_view_map_t remote_view_map;
|
||||
pt::ptime last_seen;
|
||||
std::size_t rx_bytes;
|
||||
std::size_t tx_bytes;
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
#include "modify/add_ignored_device.h"
|
||||
#include "modify/add_pending_device.h"
|
||||
#include "modify/add_pending_folders.h"
|
||||
#include "modify/add_remote_folder_infos.h"
|
||||
#include "modify/block_ack.h"
|
||||
#include "modify/mark_reachable.h"
|
||||
#include "modify/remove_blocks.h"
|
||||
@@ -52,6 +51,7 @@
|
||||
#include "peer/cluster_update.h"
|
||||
#include "peer/rx_tx.h"
|
||||
#include "peer/update_folder.h"
|
||||
#include "peer/update_remote_views.h"
|
||||
|
||||
using namespace syncspirit::model::diff;
|
||||
|
||||
@@ -179,6 +179,11 @@ auto cluster_visitor_t::operator()(const peer::update_folder_t &diff, void *cust
|
||||
return diff.visit_next(*this, custom);
|
||||
}
|
||||
|
||||
auto cluster_visitor_t::operator()(const peer::update_remote_views_t &diff, void *custom) noexcept
|
||||
-> outcome::result<void> {
|
||||
return diff.visit_next(*this, custom);
|
||||
}
|
||||
|
||||
auto cluster_visitor_t::operator()(const local::blocks_availability_t &diff, void *custom) noexcept
|
||||
-> outcome::result<void> {
|
||||
return diff.visit_next(*this, custom);
|
||||
@@ -197,11 +202,6 @@ auto cluster_visitor_t::operator()(const modify::add_blocks_t &diff, void *custo
|
||||
return diff.visit_next(*this, custom);
|
||||
}
|
||||
|
||||
auto cluster_visitor_t::operator()(const modify::add_remote_folder_infos_t &diff, void *custom) noexcept
|
||||
-> outcome::result<void> {
|
||||
return diff.visit_next(*this, custom);
|
||||
}
|
||||
|
||||
auto cluster_visitor_t::operator()(const modify::add_ignored_device_t &diff, void *custom) noexcept
|
||||
-> outcome::result<void> {
|
||||
return diff.visit_next(*this, custom);
|
||||
|
||||
@@ -44,12 +44,12 @@ struct SYNCSPIRIT_API cluster_visitor_t {
|
||||
virtual outcome::result<void> operator()(const peer::cluster_update_t &, void *custom) noexcept;
|
||||
virtual outcome::result<void> operator()(const peer::rx_tx_t &, void *custom) noexcept;
|
||||
virtual outcome::result<void> operator()(const peer::update_folder_t &, void *custom) noexcept;
|
||||
virtual outcome::result<void> operator()(const peer::update_remote_views_t &, void *custom) noexcept;
|
||||
|
||||
virtual outcome::result<void> operator()(const modify::add_blocks_t &, void *custom) noexcept;
|
||||
virtual outcome::result<void> operator()(const modify::add_ignored_device_t &, void *custom) noexcept;
|
||||
virtual outcome::result<void> operator()(const modify::add_pending_device_t &, void *custom) noexcept;
|
||||
virtual outcome::result<void> operator()(const modify::add_pending_folders_t &, void *custom) noexcept;
|
||||
virtual outcome::result<void> operator()(const modify::add_remote_folder_infos_t &, void *custom) noexcept;
|
||||
virtual outcome::result<void> operator()(const modify::block_ack_t &, void *custom) noexcept;
|
||||
virtual outcome::result<void> operator()(const modify::mark_reachable_t &, void *custom) noexcept;
|
||||
virtual outcome::result<void> operator()(const modify::remove_blocks_t &, void *custom) noexcept;
|
||||
|
||||
@@ -51,6 +51,7 @@ namespace peer {
|
||||
struct cluster_update_t;
|
||||
struct rx_tx_t;
|
||||
struct update_folder_t;
|
||||
struct update_remote_views_t;
|
||||
} // namespace peer
|
||||
|
||||
namespace modify {
|
||||
@@ -58,7 +59,6 @@ struct add_blocks_t;
|
||||
struct add_ignored_device_t;
|
||||
struct add_pending_device_t;
|
||||
struct add_pending_folders_t;
|
||||
struct add_remote_folder_infos_t;
|
||||
struct block_ack_t;
|
||||
struct block_transaction_t;
|
||||
struct generic_remove_t;
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// SPDX-FileCopyrightText: 2024-2025 Ivan Baidakou
|
||||
|
||||
#include "add_remote_folder_infos.h"
|
||||
#include "model/cluster.h"
|
||||
#include "model/diff/apply_controller.h"
|
||||
#include "model/diff/cluster_visitor.h"
|
||||
#include "model/misc/error_code.h"
|
||||
|
||||
using namespace syncspirit::model::diff::modify;
|
||||
|
||||
add_remote_folder_infos_t::add_remote_folder_infos_t(const model::device_t &peer, container_t items) noexcept
|
||||
: container{std::move(items)} {
|
||||
auto &peer_device = peer.device_id();
|
||||
device_id = peer_device.get_sha256();
|
||||
for (auto &item : container) {
|
||||
LOG_DEBUG(log, "add_remote_folder_infos_t, device = {}, folder = {}, index = {:#x}, max seq. = {}",
|
||||
peer_device.get_short(), item.folder_id, item.index_id, item.max_sequence);
|
||||
}
|
||||
}
|
||||
|
||||
auto add_remote_folder_infos_t::apply_impl(apply_controller_t &controller, void *custom) const noexcept
|
||||
-> outcome::result<void> {
|
||||
auto &cluster = controller.get_cluster();
|
||||
auto &devices = cluster.get_devices();
|
||||
auto &folders = cluster.get_folders();
|
||||
auto peer = devices.by_sha256(device_id);
|
||||
if (!peer) {
|
||||
return make_error_code(error_code_t::no_such_device);
|
||||
}
|
||||
auto &remote_folders = peer->get_remote_folder_infos();
|
||||
for (auto &item : container) {
|
||||
auto folder = folders.by_id(item.folder_id);
|
||||
if (!folder) {
|
||||
return make_error_code(error_code_t::no_such_folder);
|
||||
}
|
||||
auto opt = model::remote_folder_info_t::create(item.index_id, item.max_sequence, *peer, *folder);
|
||||
if (!opt) {
|
||||
return opt.assume_error();
|
||||
}
|
||||
remote_folders.put(opt.assume_value());
|
||||
}
|
||||
return applicator_t::apply_sibling(controller, custom);
|
||||
}
|
||||
|
||||
auto add_remote_folder_infos_t::visit(cluster_visitor_t &visitor, void *custom) const noexcept
|
||||
-> outcome::result<void> {
|
||||
LOG_TRACE(log, "visiting add_remote_folder_infos_t");
|
||||
return visitor(*this, custom);
|
||||
}
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "model/cluster.h"
|
||||
#include "model/misc/error_code.h"
|
||||
#include "model/diff/cluster_visitor.h"
|
||||
#include "add_remote_folder_infos.h"
|
||||
#include "remove_pending_folders.h"
|
||||
#include "upsert_folder_info.h"
|
||||
#include "utils/format.hpp"
|
||||
@@ -42,17 +41,12 @@ share_folder_t::share_folder_t(const bu::uuid &uuid, const model::device_t &peer
|
||||
LOG_DEBUG(log, "share_folder_t, with peer = {}, folder_id = {}", peer.device_id(), folder_id);
|
||||
auto current = assign_child(new upsert_folder_info_t(uuid, peer.device_id(), introducer, folder_id, index_id));
|
||||
if (pf) {
|
||||
using container_t = typename add_remote_folder_infos_t::container_t;
|
||||
using item_t = typename container_t::value_type;
|
||||
auto keys = remove_pending_folders_t::keys_t{};
|
||||
auto key = pf->get_key();
|
||||
auto bytes = utils::bytes_t(key.begin(), key.end());
|
||||
keys.emplace_back(std::move(bytes));
|
||||
auto diff = cluster_diff_ptr_t{};
|
||||
current = current->assign_sibling(new remove_pending_folders_t(std::move(keys)));
|
||||
|
||||
auto remote_folders = container_t{{item_t{folder_id, index_id, 0}}};
|
||||
current = current->assign_sibling(new add_remote_folder_infos_t(peer, std::move(remote_folders)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "../cluster_diff.h"
|
||||
#include "model/device.h"
|
||||
#include "model/folder_info.h"
|
||||
#include "model/misc/sequencer.h"
|
||||
#include "proto/proto-fwd.hpp"
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
#include "cluster_update.h"
|
||||
#include "model/diff/apply_controller.h"
|
||||
#include "model/diff/modify/add_remote_folder_infos.h"
|
||||
#include "model/diff/modify/add_pending_folders.h"
|
||||
#include "model/diff/modify/remove_blocks.h"
|
||||
#include "model/diff/modify/remove_folder_infos.h"
|
||||
@@ -13,6 +12,7 @@
|
||||
#include "model/diff/modify/update_peer.h"
|
||||
#include "model/diff/modify/upsert_folder.h"
|
||||
#include "model/diff/modify/upsert_folder_info.h"
|
||||
#include "model/diff/peer/update_remote_views.h"
|
||||
#include "model/diff/cluster_visitor.h"
|
||||
#include "model/cluster.h"
|
||||
#include "model/misc/orphaned_blocks.h"
|
||||
@@ -50,6 +50,7 @@ cluster_update_t::cluster_update_t(const bfs::path &default_path, const cluster_
|
||||
using allocator_t = std::pmr::polymorphic_allocator<char>;
|
||||
using fmt_buff_t = fmt::basic_memory_buffer<char, fmt::inline_buffer_size, allocator_t>;
|
||||
using fi_set_t = std::pmr::unordered_set<model::folder_info_ptr_t>;
|
||||
using view_t = peer::update_remote_views_t::item_t;
|
||||
struct introduced_device_t {
|
||||
db::Device device;
|
||||
model::device_id_t device_id;
|
||||
@@ -74,7 +75,7 @@ cluster_update_t::cluster_update_t(const bfs::path &default_path, const cluster_
|
||||
|
||||
auto &known_pending_folders = cluster.get_pending_folders();
|
||||
auto new_pending_folders = diff::modify::add_pending_folders_t::container_t{};
|
||||
auto remote_folders = diff::modify::add_remote_folder_infos_t::container_t{};
|
||||
auto remote_views = diff::peer::update_remote_views_t::container_t{};
|
||||
uuid_folder_infos_map_t reset_folders;
|
||||
uuid_folder_infos_map_t removed_folders;
|
||||
auto reshared_folders = fi_set_t(allocator);
|
||||
@@ -285,9 +286,15 @@ cluster_update_t::cluster_update_t(const bfs::path &default_path, const cluster_
|
||||
folder_info = folder->get_folder_infos().by_device_id(device_sha);
|
||||
}
|
||||
|
||||
if (device_sha != sha256 && device.get() != cluster.get_device()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto view = view_t{std::string(folder_id), utils::bytes_t(device_sha), index_id, max_sequence};
|
||||
remote_views.emplace_back(std::move(view));
|
||||
|
||||
if (device.get() == cluster.get_device()) {
|
||||
if (is_shared_with_source(folder_id)) {
|
||||
remote_folders.emplace_back(std::string(folder_id), index_id, max_sequence);
|
||||
LOG_DEBUG(log, "cluster_update_t, remote folder = {}, device = {}, max seq. = {}", folder_label,
|
||||
device_id.get_short(), max_sequence);
|
||||
} else {
|
||||
@@ -297,10 +304,6 @@ cluster_update_t::cluster_update_t(const bfs::path &default_path, const cluster_
|
||||
continue;
|
||||
}
|
||||
|
||||
if (device_sha != sha256) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!folder_info) {
|
||||
bool share = false;
|
||||
if (device_sha == source.device_id().get_sha256()) {
|
||||
@@ -489,8 +492,8 @@ cluster_update_t::cluster_update_t(const bfs::path &default_path, const cluster_
|
||||
auto ptr = new modify::add_pending_folders_t(std::move(new_pending_folders));
|
||||
update_current(ptr);
|
||||
}
|
||||
if (!remote_folders.empty()) {
|
||||
auto ptr = new modify::add_remote_folder_infos_t(source, std::move(remote_folders));
|
||||
if (!remote_views.empty()) {
|
||||
auto ptr = new peer::update_remote_views_t(source, std::move(remote_views));
|
||||
update_current(ptr);
|
||||
}
|
||||
for (auto &id : introduced_devices) {
|
||||
@@ -509,7 +512,7 @@ auto cluster_update_t::apply_impl(apply_controller_t &controller, void *custom)
|
||||
LOG_TRACE(log, "applying cluster_update_t (self)");
|
||||
auto &cluster = controller.get_cluster();
|
||||
auto peer = cluster.get_devices().by_sha256(peer_id);
|
||||
peer->get_remote_folder_infos().clear();
|
||||
peer->get_remote_view_map().clear();
|
||||
|
||||
LOG_TRACE(log, "applying cluster_update_t (children)");
|
||||
auto r = applicator_t::apply_child(controller, custom);
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// SPDX-FileCopyrightText: 2025 Ivan Baidakou
|
||||
|
||||
#include "update_remote_views.h"
|
||||
#include "model/cluster.h"
|
||||
#include "model/diff/apply_controller.h"
|
||||
#include "model/diff/cluster_visitor.h"
|
||||
|
||||
using namespace syncspirit;
|
||||
using namespace syncspirit::model::diff::peer;
|
||||
|
||||
update_remote_views_t::update_remote_views_t(const model::device_t &peer_, container_t container_) noexcept
|
||||
: container{std::move(container_)}, peer_id{peer_.device_id().get_sha256()} {
|
||||
LOG_DEBUG(log, "update_remote_views_t '{}', {} views", peer_.device_id().get_short(), container.size());
|
||||
}
|
||||
|
||||
auto update_remote_views_t::apply_impl(apply_controller_t &controller, void *custom) const noexcept
|
||||
-> outcome::result<void> {
|
||||
LOG_TRACE(log, "applying update_remote_views_t");
|
||||
|
||||
auto &cluster = controller.get_cluster();
|
||||
auto peer = cluster.get_devices().by_sha256(peer_id);
|
||||
auto &views = peer->get_remote_view_map();
|
||||
auto &folders = cluster.get_folders();
|
||||
auto &devices = cluster.get_devices();
|
||||
for (auto &item : container) {
|
||||
auto folder = folders.by_id(item.folder_id);
|
||||
auto device = devices.by_sha256(item.device_id);
|
||||
if (folder && device) {
|
||||
views.push(*device, *folder, item.index_id, item.max_sequence);
|
||||
LOG_TRACE(log, "'{}' update remote view of folder '{}' to max seq. {}", device->device_id().get_short(),
|
||||
folder->get_id(), item.max_sequence);
|
||||
}
|
||||
}
|
||||
return applicator_t::apply_sibling(controller, custom);
|
||||
}
|
||||
|
||||
auto update_remote_views_t::visit(cluster_visitor_t &visitor, void *custom) const noexcept -> outcome::result<void> {
|
||||
LOG_TRACE(log, "visiting update_remote_views_t");
|
||||
return visitor(*this, custom);
|
||||
}
|
||||
+9
-7
@@ -1,28 +1,30 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// SPDX-FileCopyrightText: 2024-2025 Ivan Baidakou
|
||||
// SPDX-FileCopyrightText: 2025 Ivan Baidakou
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../cluster_diff.h"
|
||||
#include "model/device.h"
|
||||
#include <vector>
|
||||
#include "model/device.h"
|
||||
|
||||
namespace syncspirit::model::diff::modify {
|
||||
namespace syncspirit::model::diff::peer {
|
||||
|
||||
struct SYNCSPIRIT_API add_remote_folder_infos_t final : cluster_diff_t {
|
||||
struct SYNCSPIRIT_API update_remote_views_t final : cluster_diff_t {
|
||||
struct item_t {
|
||||
std::string folder_id;
|
||||
utils::bytes_t device_id;
|
||||
std::uint64_t index_id;
|
||||
std::int64_t max_sequence;
|
||||
};
|
||||
using container_t = std::vector<item_t>;
|
||||
|
||||
add_remote_folder_infos_t(const model::device_t &peer, container_t items) noexcept;
|
||||
update_remote_views_t(const model::device_t &peer, container_t container) noexcept;
|
||||
outcome::result<void> apply_impl(apply_controller_t &, void *) const noexcept override;
|
||||
outcome::result<void> visit(cluster_visitor_t &, void *) const noexcept override;
|
||||
|
||||
utils::bytes_t device_id;
|
||||
private:
|
||||
container_t container;
|
||||
utils::bytes_t peer_id;
|
||||
};
|
||||
|
||||
} // namespace syncspirit::model::diff::modify
|
||||
} // namespace syncspirit::model::diff::peer
|
||||
@@ -2,7 +2,6 @@
|
||||
// SPDX-FileCopyrightText: 2023-2025 Ivan Baidakou
|
||||
|
||||
#include "updates_streamer.h"
|
||||
#include "model/remote_folder_info.h"
|
||||
#include <algorithm>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
@@ -15,7 +14,7 @@ updates_streamer_t::updates_streamer_t(cluster_t &cluster_, device_t &device) no
|
||||
|
||||
void updates_streamer_t::refresh_remote() noexcept {
|
||||
auto &folders = cluster.get_folders();
|
||||
auto &remote_folders = peer->get_remote_folder_infos();
|
||||
auto &remote_views = peer->get_remote_view_map();
|
||||
auto streaming_folder = (model::folder_info_t *)(nullptr);
|
||||
auto prev_seen = std::move(seen_info);
|
||||
seen_info = {};
|
||||
@@ -28,10 +27,10 @@ void updates_streamer_t::refresh_remote() noexcept {
|
||||
if (streaming && streaming->folder_info == local_folder) {
|
||||
streaming_folder = local_folder.get();
|
||||
}
|
||||
auto remote_folder = remote_folders.by_folder(folder);
|
||||
if (remote_folder) {
|
||||
auto index_match = remote_folder->get_index() == local_folder->get_index();
|
||||
auto remote_max = index_match ? remote_folder->get_max_sequence() : 0;
|
||||
auto remote_view = remote_views.get(*cluster.get_device(), folder);
|
||||
if (remote_view) {
|
||||
auto index_match = remote_view->index_id == local_folder->get_index();
|
||||
auto remote_max = index_match ? remote_view->max_sequence : 0;
|
||||
auto previously_seen = prev_seen[local_folder];
|
||||
auto seen = std::max(remote_max, previously_seen);
|
||||
seen_info[local_folder] = seen;
|
||||
@@ -42,9 +41,12 @@ void updates_streamer_t::refresh_remote() noexcept {
|
||||
if (streaming && !streaming_folder) {
|
||||
streaming.reset();
|
||||
} else if (streaming_folder) {
|
||||
auto remote_folder = remote_folders.by_folder(*streaming_folder->get_folder());
|
||||
if (!remote_folder) {
|
||||
streaming.reset();
|
||||
auto &folder = *streaming_folder->get_folder();
|
||||
auto remote_view = remote_views.get(*cluster.get_device(), folder);
|
||||
if (remote_view) {
|
||||
if (remote_view->index_id != streaming_folder->get_index()) {
|
||||
streaming.reset();
|
||||
}
|
||||
} else {
|
||||
// TODO, refresh files?
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// SPDX-FileCopyrightText: 2023-2024 Ivan Baidakou
|
||||
// SPDX-FileCopyrightText: 2023-2025 Ivan Baidakou
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include "model/file_info.h"
|
||||
#include "model/device.h"
|
||||
#include "model/folder_info.h"
|
||||
#include "model/remote_folder_info.h"
|
||||
#include "syncspirit-export.h"
|
||||
#include <optional>
|
||||
#include <unordered_map>
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
#include "remote_folder_info.h"
|
||||
#include "folder.h"
|
||||
#include "cluster.h"
|
||||
|
||||
namespace syncspirit::model {
|
||||
|
||||
auto remote_folder_info_t::create(std::uint64_t index_id, std::int64_t max_sequence, device_t &device_,
|
||||
folder_t &folder_) noexcept -> outcome::result<remote_folder_info_t_ptr_t> {
|
||||
auto ptr = remote_folder_info_t_ptr_t{new remote_folder_info_t(index_id, max_sequence, device_, folder_)};
|
||||
return outcome::success(ptr);
|
||||
}
|
||||
|
||||
remote_folder_info_t::~remote_folder_info_t() {}
|
||||
|
||||
remote_folder_info_t::remote_folder_info_t(std::uint64_t index_id_, std::int64_t max_sequence_, device_t &device_,
|
||||
folder_t &folder_) noexcept
|
||||
: index_id{index_id_}, max_sequence{max_sequence_}, device{&device_}, folder{&folder_} {}
|
||||
|
||||
std::string_view remote_folder_info_t::get_key() const noexcept { return folder->get_id(); }
|
||||
|
||||
remote_folder_info_t_ptr_t remote_folder_infos_map_t::by_folder(const folder_t &folder) const noexcept {
|
||||
auto id = folder.get_id();
|
||||
auto ptr = (unsigned char *)id.data();
|
||||
auto view = utils::bytes_view_t(ptr, id.size());
|
||||
return get<0>(view);
|
||||
}
|
||||
|
||||
auto remote_folder_info_t::get_local() const noexcept -> folder_info_ptr_t {
|
||||
auto device = folder->get_cluster()->get_device();
|
||||
return folder->get_folder_infos().by_device(*device);
|
||||
}
|
||||
|
||||
template <> SYNCSPIRIT_API utils::bytes_view_t get_index<0>(const remote_folder_info_t_ptr_t &item) noexcept {
|
||||
auto key = item->get_key();
|
||||
auto ptr = (unsigned char *)key.data();
|
||||
return {ptr, key.size()};
|
||||
}
|
||||
|
||||
} // namespace syncspirit::model
|
||||
@@ -1,55 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// SPDX-FileCopyrightText: 2023-2025 Ivan Baidakou
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "syncspirit-export.h"
|
||||
#include "misc/augmentation.h"
|
||||
#include "misc/map.hpp"
|
||||
#include <boost/outcome.hpp>
|
||||
|
||||
namespace syncspirit::model {
|
||||
|
||||
namespace outcome = boost::outcome_v2;
|
||||
|
||||
struct folder_t;
|
||||
using folder_ptr_t = intrusive_ptr_t<folder_t>;
|
||||
|
||||
struct device_t;
|
||||
using device_ptr_t = intrusive_ptr_t<device_t>;
|
||||
|
||||
struct remote_folder_info_t;
|
||||
using remote_folder_info_t_ptr_t = intrusive_ptr_t<remote_folder_info_t>;
|
||||
|
||||
struct folder_info_t;
|
||||
using folder_info_ptr_t = intrusive_ptr_t<folder_info_t>;
|
||||
|
||||
struct SYNCSPIRIT_API remote_folder_info_t final : augmentable_t {
|
||||
|
||||
static outcome::result<remote_folder_info_t_ptr_t> create(std::uint64_t index_id, std::int64_t max_sequence,
|
||||
device_t &device_, folder_t &folder_) noexcept;
|
||||
|
||||
~remote_folder_info_t();
|
||||
std::string_view get_key() const noexcept;
|
||||
|
||||
inline std::uint64_t get_index() const noexcept { return index_id; }
|
||||
inline std::int64_t get_max_sequence() const noexcept { return max_sequence; }
|
||||
|
||||
folder_info_ptr_t get_local() const noexcept;
|
||||
|
||||
private:
|
||||
remote_folder_info_t(std::uint64_t index_id, std::int64_t max_sequence, device_t &device_,
|
||||
folder_t &folder_) noexcept;
|
||||
|
||||
std::uint64_t index_id;
|
||||
std::int64_t max_sequence;
|
||||
device_t *device;
|
||||
folder_ptr_t folder;
|
||||
};
|
||||
|
||||
struct SYNCSPIRIT_API remote_folder_infos_map_t : public generic_map_t<remote_folder_info_t_ptr_t, 1> {
|
||||
remote_folder_info_t_ptr_t by_folder(const folder_t &folder) const noexcept;
|
||||
};
|
||||
|
||||
} // namespace syncspirit::model
|
||||
@@ -0,0 +1,37 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// SPDX-FileCopyrightText: 2025 Ivan Baidakou
|
||||
|
||||
#include "remote_view.h"
|
||||
#include "device.h"
|
||||
#include "folder.h"
|
||||
|
||||
using namespace syncspirit;
|
||||
using namespace syncspirit::model;
|
||||
using namespace syncspirit::model::details;
|
||||
|
||||
template <typename T> inline static std::size_t get_hash(const T &key) noexcept {
|
||||
auto h1 = std::hash<decltype(key.folder_id)>{}(key.folder_id);
|
||||
auto h2 = std::hash<decltype(key.device_id)>{}(key.device_id);
|
||||
return h1 + 0x9e3779b9 + (h2 << 6) + (h2 >> 2);
|
||||
}
|
||||
|
||||
std::size_t remote_view_key_hash_t::operator()(const remote_view_key_t &key) const noexcept { return get_hash(key); }
|
||||
|
||||
std::size_t remote_view_key_hash_t::operator()(const transient_view_key_t &key) const noexcept { return get_hash(key); }
|
||||
|
||||
void remote_view_map_t::push(const device_t &device, const folder_t &folder, std::uint64_t index_id,
|
||||
std::int64_t max_sequence) noexcept {
|
||||
auto folder_id = std::string(folder.get_id());
|
||||
auto device_id = utils::bytes_t(device.device_id().get_sha256());
|
||||
auto key = details::remote_view_key_t(std::move(folder_id), std::move(device_id));
|
||||
emplace(std::move(key), remote_view_t{index_id, max_sequence});
|
||||
}
|
||||
|
||||
const remote_view_t *remote_view_map_t::get(const device_t &device, const folder_t &folder) const noexcept {
|
||||
auto key = details::transient_view_key_t{folder.get_id(), device.device_id().get_sha256()};
|
||||
auto it = find(key);
|
||||
if (it != end()) {
|
||||
return &it->second;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// SPDX-FileCopyrightText: 2025 Ivan Baidakou
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include "utils/bytes.h"
|
||||
#include "syncspirit-export.h"
|
||||
|
||||
namespace syncspirit::model {
|
||||
|
||||
struct device_t;
|
||||
struct folder_t;
|
||||
|
||||
struct remote_view_t {
|
||||
std::uint64_t index_id;
|
||||
std::int64_t max_sequence;
|
||||
};
|
||||
|
||||
namespace details {
|
||||
|
||||
struct remote_view_key_t {
|
||||
std::string folder_id;
|
||||
utils::bytes_t device_id;
|
||||
};
|
||||
|
||||
struct transient_view_key_t {
|
||||
std::string_view folder_id;
|
||||
utils::bytes_view_t device_id;
|
||||
};
|
||||
|
||||
struct SYNCSPIRIT_API remote_view_key_eq_t {
|
||||
using is_transparent = void;
|
||||
template <typename U, typename V> bool operator()(const U &lhs, const V &rhs) const {
|
||||
return lhs.folder_id == rhs.folder_id && lhs.device_id == rhs.device_id;
|
||||
}
|
||||
};
|
||||
|
||||
struct SYNCSPIRIT_API remote_view_key_hash_t {
|
||||
using is_transparent = void;
|
||||
std::size_t operator()(const remote_view_key_t &key) const noexcept;
|
||||
std::size_t operator()(const transient_view_key_t &key) const noexcept;
|
||||
};
|
||||
|
||||
using remote_view_map_base_t =
|
||||
std::unordered_map<remote_view_key_t, remote_view_t, remote_view_key_hash_t, remote_view_key_eq_t>;
|
||||
|
||||
} // namespace details
|
||||
|
||||
struct SYNCSPIRIT_API remote_view_map_t : details::remote_view_map_base_t {
|
||||
void push(const device_t &, const folder_t &, std::uint64_t index_id, std::int64_t max_sequence) noexcept;
|
||||
const remote_view_t *get(const device_t &, const folder_t &) const noexcept;
|
||||
};
|
||||
|
||||
} // namespace syncspirit::model
|
||||
@@ -323,17 +323,17 @@ void controller_actor_t::send_cluster_config(stack_context_t &ctx) noexcept {
|
||||
|
||||
void controller_actor_t::send_new_indices() noexcept {
|
||||
if (updates_streamer && peer_address) {
|
||||
auto &remote_folders = peer->get_remote_folder_infos();
|
||||
auto &remote_views = peer->get_remote_view_map();
|
||||
for (auto it : cluster->get_folders()) {
|
||||
auto &folder = *it.item;
|
||||
auto peer_folder = folder.is_shared_with(*peer);
|
||||
if (peer_folder) {
|
||||
auto local_folder = folder.get_folder_infos().by_device(*cluster->get_device());
|
||||
auto remote_folder = remote_folders.by_folder(folder);
|
||||
if (remote_folder) {
|
||||
if (remote_folder->get_index() != local_folder->get_index()) {
|
||||
auto remote_view = remote_views.get(*cluster->get_device(), folder);
|
||||
if (remote_view) {
|
||||
if (remote_view->index_id != local_folder->get_index()) {
|
||||
LOG_DEBUG(log, "peer still has wrong index for '{}' ({:#x} vs {:#x}), refreshing",
|
||||
folder.get_id(), remote_folder->get_index(), local_folder->get_index());
|
||||
folder.get_id(), remote_view->index_id, local_folder->get_index());
|
||||
updates_streamer->on_remote_refresh();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "presentation/presence.h"
|
||||
#include "model/folder_info.h"
|
||||
#include "fs/task/scan_dir.h"
|
||||
#include <filesystem>
|
||||
#include <boost/system/error_code.hpp>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "entity.h"
|
||||
#include "orphans.h"
|
||||
#include "model/file_info.h"
|
||||
#include "model/folder.h"
|
||||
|
||||
namespace syncspirit::presentation {
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "presence.h"
|
||||
#include "model/folder_info.h"
|
||||
#include "syncspirit-export.h"
|
||||
|
||||
namespace syncspirit::presentation {
|
||||
|
||||
@@ -730,14 +730,14 @@ TEST_CASE("cluster update with remote folders (1)", "[model]") {
|
||||
auto &pr_peer = proto::add_devices(pr_folder);
|
||||
proto::set_id(pr_peer, peer_id_1.get_sha256());
|
||||
proto::set_name(pr_peer, peer_device->get_name());
|
||||
proto::set_max_sequence(pr_peer, 123456u);
|
||||
proto::set_index_id(pr_peer, 7u);
|
||||
proto::set_index_id(pr_peer, 123456u);
|
||||
proto::set_max_sequence(pr_peer, 7u);
|
||||
|
||||
auto &pr_peer_my = proto::add_devices(pr_folder);
|
||||
proto::set_id(pr_peer_my, my_id.get_sha256());
|
||||
proto::set_name(pr_peer_my, my_device->get_name());
|
||||
proto::set_max_sequence(pr_peer_my, 3);
|
||||
proto::set_index_id(pr_peer_my, 5ul);
|
||||
proto::set_max_sequence(pr_peer_my, 3);
|
||||
|
||||
auto diff_opt = diff::peer::cluster_update_t::create({}, *cluster, *sequencer, *peer_device, *cc);
|
||||
REQUIRE(diff_opt);
|
||||
@@ -745,10 +745,17 @@ TEST_CASE("cluster update with remote folders (1)", "[model]") {
|
||||
auto opt = diff_opt.value()->apply(*controller, {});
|
||||
REQUIRE(opt);
|
||||
|
||||
auto remote_folder = peer_device->get_remote_folder_infos().by_folder(*folder);
|
||||
REQUIRE(remote_folder);
|
||||
CHECK(remote_folder->get_index() == 5ul);
|
||||
CHECK(remote_folder->get_max_sequence() == 3);
|
||||
auto remote_views = peer_device->get_remote_view_map();
|
||||
REQUIRE(remote_views.size() == 2);
|
||||
auto view_peer = remote_views.get(*peer_device, *folder);
|
||||
REQUIRE(view_peer);
|
||||
CHECK(view_peer->index_id == 123456u);
|
||||
CHECK(view_peer->max_sequence == 7);
|
||||
|
||||
auto view_local = remote_views.get(*my_device, *folder);
|
||||
REQUIRE(view_local);
|
||||
CHECK(view_local->index_id == 5u);
|
||||
CHECK(view_local->max_sequence == 3);
|
||||
|
||||
SECTION("unshare by peer") {
|
||||
auto cc = std::make_unique<proto::ClusterConfig>();
|
||||
@@ -758,7 +765,7 @@ TEST_CASE("cluster update with remote folders (1)", "[model]") {
|
||||
auto &diff = diff_opt.value();
|
||||
REQUIRE(diff->apply(*controller, {}));
|
||||
|
||||
CHECK(peer_device->get_remote_folder_infos().size() == 0);
|
||||
CHECK(peer_device->get_remote_view_map().size() == 0);
|
||||
auto fi = folder->get_folder_infos().by_device(*peer_device);
|
||||
// we are still sharing the folder with peer
|
||||
CHECK(fi);
|
||||
|
||||
@@ -33,8 +33,8 @@ TEST_CASE("updates_streamer", "[model]") {
|
||||
auto folder = folders.by_id("1234-5678");
|
||||
|
||||
auto add_remote = [&](std::uint64_t index, std::int64_t sequence) {
|
||||
auto remote_folder = remote_folder_info_t::create(index, sequence, *peer_device, *folder).value();
|
||||
peer_device->get_remote_folder_infos().put(remote_folder);
|
||||
auto &views = peer_device->get_remote_view_map();
|
||||
views.push(*my_device, *folder, index, sequence);
|
||||
};
|
||||
|
||||
SECTION("trivial") {
|
||||
|
||||
Reference in New Issue
Block a user