23 Revīzijas 4254e43c6d ... 074dd076bf

Autors SHA1 Ziņojums Datums
  Ivan Baidakou 074dd076bf tests: refactor test-peer 4 dienas atpakaļ
  Ivan Baidakou a3f0d52d02 Merge branch 'optimize-mem-usage' into v0.4.3-dev 4 dienas atpakaļ
  Ivan Baidakou 1bd2fbe869 core: clean up 4 dienas atpakaļ
  Ivan Baidakou dc95b5f525 core: use compact vector 5 dienas atpakaļ
  Ivan Baidakou 58a3b10537 WIP 6 dienas atpakaļ
  Ivan Baidakou 0116ac796e WIP 6 dienas atpakaļ
  Ivan Baidakou f3e794d8fd core: use boost::vector to reduce memory usage 6 dienas atpakaļ
  Ivan Baidakou 0906cbd30c core: file_info_t: drop block-size & missing blocks cache fields 6 dienas atpakaļ
  Ivan Baidakou d4fe71e848 core: file_info_t: drop non-used function 1 nedēļu atpakaļ
  Ivan Baidakou 4844087021 core: file_info_t: store block locality flag in block pointer (black magic) 1 nedēļu atpakaļ
  Ivan Baidakou e6372ec980 core: file_info_t: store raw block pointers instead of smart-pointers 1 nedēļu atpakaļ
  Ivan Baidakou cc6538a523 core: file_info_t: use block iterator interface 1 nedēļu atpakaļ
  Ivan Baidakou 6a6c65f747 core: file_info_t: drop file_size, calcualate it on demand from blocks 1 nedēļu atpakaļ
  Ivan Baidakou da71d95d56 core: optimize mem usage: block_info_t 1 nedēļu atpakaļ
  Ivan Baidakou f42617c752 core: optimize mem usage: file_block_t 1 nedēļu atpakaļ
  Ivan Baidakou 49264dad40 core: optimize mem usage for block_info_t 1 nedēļu atpakaļ
  Ivan Baidakou 17633732d3 core: make file_info_t non-virtual 1 nedēļu atpakaļ
  Ivan Baidakou 546a7415c3 core: use union for content storage for a file_info 1 nedēļu atpakaļ
  Ivan Baidakou 999d6eb359 core: optimize mem usage, drop key prefix from file_info key 1 nedēļu atpakaļ
  Ivan Baidakou 8bddcd26f5 core: format 1 nedēļu atpakaļ
  Ivan Baidakou 617dece5e6 core: optimize mem usage, remove folder_info_t from file_info_t 1 nedēļu atpakaļ
  Ivan Baidakou 7ee59810dd core: clean up 1 nedēļu atpakaļ
  Ivan Baidakou 9d6453074c core: minor optimization 1 nedēļu atpakaļ

+ 1 - 1
README.md

@@ -125,7 +125,7 @@ after the core completion.
 
 ## 0.4.3 (xx-xxx-xxxx)
  - [core] allow to load huge databses and interrupt loading porgress
- - [core] reduce memory consumption by model (~ 35%)
+ - [core] reduce memory consumption by model (~ 44%)
  - [core] fix compatibility with syncthing v2.0 (i.e. tolerate directory with 
           non-zero size and without blocks)
  - [core] allow to specify root certificate authority to use in all tls/ssl connections,

+ 7 - 6
src/fs/chunk_iterator.cpp

@@ -5,15 +5,16 @@
 
 using namespace syncspirit::fs;
 
-chunk_iterator_t::chunk_iterator_t(scan_task_ptr_t task_, model::file_info_ptr_t file_, file_ptr_t backend_) noexcept
-    : task{std::move(task_)}, peer_file{std::move(file_)}, backend{std::move(backend_)}, last_queued_block{0},
-      valid_blocks_count{0}, abandoned{false} {
-    unhashed_blocks = peer_file->get_blocks().size();
+chunk_iterator_t::chunk_iterator_t(scan_task_ptr_t task_, model::file_info_ptr_t file_,
+                                   const model::folder_info_t &peer_folder_, file_ptr_t backend_) noexcept
+    : task{std::move(task_)}, peer_folder{peer_folder_}, peer_file{std::move(file_)}, backend{std::move(backend_)},
+      last_queued_block{0}, valid_blocks_count{0}, abandoned{false} {
+    unhashed_blocks = peer_file->iterate_blocks().get_total();
     valid_blocks_map.resize(unhashed_blocks);
 }
 
 bool chunk_iterator_t::has_more_chunks() const noexcept {
-    return !abandoned && (last_queued_block < (int64_t)peer_file->get_blocks().size());
+    return !abandoned && (last_queued_block < (int64_t)peer_file->iterate_blocks().get_total());
 }
 
 auto chunk_iterator_t::read() noexcept -> outcome::result<details::chunk_t> {
@@ -38,7 +39,7 @@ auto chunk_iterator_t::read() noexcept -> outcome::result<details::chunk_t> {
 void chunk_iterator_t::ack_hashing() noexcept { --unhashed_blocks; }
 
 void chunk_iterator_t::ack_block(utils::bytes_view_t digest, size_t block_index) noexcept {
-    auto &orig_block = peer_file->get_blocks().at(block_index);
+    auto orig_block = peer_file->iterate_blocks(block_index).next();
     if (orig_block->get_hash() != digest) {
         return;
     }

+ 4 - 1
src/fs/chunk_iterator.h

@@ -21,7 +21,8 @@ namespace bfs = std::filesystem;
 struct SYNCSPIRIT_API chunk_iterator_t {
     using valid_blocks_map_t = std::vector<bool>;
 
-    chunk_iterator_t(scan_task_ptr_t task, model::file_info_ptr_t file, file_ptr_t backend) noexcept;
+    chunk_iterator_t(scan_task_ptr_t task, model::file_info_ptr_t file, const model::folder_info_t &peer_folder,
+                     file_ptr_t backend) noexcept;
 
     bool has_more_chunks() const noexcept;
     inline bool is_complete() const noexcept { return unhashed_blocks == 0; }
@@ -33,6 +34,7 @@ struct SYNCSPIRIT_API chunk_iterator_t {
     outcome::result<details::chunk_t> read() noexcept;
 
     inline model::file_info_ptr_t get_file() { return peer_file; }
+    inline const model::folder_info_t &get_folder() { return peer_folder; }
 
     inline bfs::path get_path() noexcept { return backend->get_path(); }
     inline outcome::result<void> remove() noexcept { return backend->remove(); }
@@ -41,6 +43,7 @@ struct SYNCSPIRIT_API chunk_iterator_t {
 
   private:
     scan_task_ptr_t task;
+    const model::folder_info_t &peer_folder;
     model::file_info_ptr_t peer_file;
     file_ptr_t backend;
     int64_t last_queued_block;

+ 13 - 10
src/fs/file.cpp

@@ -26,10 +26,12 @@ using namespace syncspirit::fs;
 #define SS_STAT_BUFF struct stat
 #endif
 
-auto file_t::open_write(model::file_info_ptr_t model) noexcept -> outcome::result<file_t> {
+auto file_t::open_write(model::file_info_ptr_t model, const model::folder_info_t &folder_info) noexcept
+    -> outcome::result<file_t> {
     using mode_t = utils::fstream_t;
     auto tmp = model->get_size() > 0;
-    auto path = tmp ? make_temporal(model->get_path()) : model->get_path();
+    auto model_path = model->get_path(folder_info);
+    auto path = tmp ? make_temporal(std::move(model_path)) : std::move(model_path);
     path.make_preferred();
 
     bool need_resize = true;
@@ -58,7 +60,7 @@ auto file_t::open_write(model::file_info_ptr_t model) noexcept -> outcome::resul
         return sys::error_code{errno, sys::system_category()};
     }
 
-    return file_t(std::move(file), std::move(model), std::move(path), tmp);
+    return file_t(std::move(file), std::move(model), std::move(path), std::move(model_path), tmp);
 }
 
 auto file_t::open_read(const bfs::path &path) noexcept -> outcome::result<file_t> {
@@ -71,10 +73,11 @@ auto file_t::open_read(const bfs::path &path) noexcept -> outcome::result<file_t
 
 file_t::file_t() noexcept {};
 
-file_t::file_t(utils::fstream_t backend_, model::file_info_ptr_t model_, bfs::path path_, bool temporal_) noexcept
+file_t::file_t(utils::fstream_t backend_, model::file_info_ptr_t model_, bfs::path path_, bfs::path model_path_,
+               bool temporal_) noexcept
     : backend{new utils::fstream_t(std::move(backend_))}, model{std::move(model_)}, path{std::move(path_)},
       temporal{temporal_} {
-    auto model_path = model->get_path();
+    model_path = std::move(model_path_);
     model_path.make_preferred();
     path.make_preferred();
     path_str = boost::nowide::narrow(model_path.generic_wstring());
@@ -117,19 +120,19 @@ auto file_t::close(bool remove_temporal, const bfs::path &local_name) noexcept -
     backend.reset();
 
     sys::error_code ec;
-    auto orig_path = local_name.empty() ? model->get_path() : local_name;
+    auto orig_path = local_name.empty() ? &model_path : &local_name;
     if (remove_temporal) {
         assert(temporal);
-        bfs::rename(path, orig_path, ec);
+        bfs::rename(path, *orig_path, ec);
         if (ec) {
             return ec;
         }
-    } else if (orig_path != path) {
-        orig_path = path;
+    } else if (*orig_path != path) {
+        orig_path = &path;
     }
 
     auto modified = from_unix(model->get_modified_s());
-    bfs::last_write_time(orig_path, modified, ec);
+    bfs::last_write_time(*orig_path, modified, ec);
     if (ec) {
         return ec;
     }

+ 5 - 2
src/fs/file.h

@@ -42,17 +42,20 @@ struct SYNCSPIRIT_API file_t : model::arc_base_t<file_t> {
     outcome::result<void> copy(size_t my_offset, const file_t &from, size_t source_offset, size_t size) noexcept;
     outcome::result<utils::bytes_t> read(size_t offset, size_t size) const noexcept;
 
-    static outcome::result<file_t> open_write(model::file_info_ptr_t model) noexcept;
+    static outcome::result<file_t> open_write(model::file_info_ptr_t model,
+                                              const model::folder_info_t &folder_info) noexcept;
     static outcome::result<file_t> open_read(const bfs::path &path) noexcept;
 
   private:
     using backend_ptr_t = std::unique_ptr<utils::fstream_t>;
-    file_t(utils::fstream_t backend, model::file_info_ptr_t model, bfs::path path, bool temporal) noexcept;
+    file_t(utils::fstream_t backend, model::file_info_ptr_t model, bfs::path path, bfs::path model_path,
+           bool temporal) noexcept;
     file_t(utils::fstream_t backend, bfs::path path) noexcept;
 
     backend_ptr_t backend;
     model::file_info_ptr_t model;
     bfs::path path;
+    bfs::path model_path;
     std::string path_str;
     bool temporal{false};
 };

+ 42 - 40
src/fs/file_actor.cpp

@@ -12,6 +12,7 @@
 #include "model/diff/modify/finish_file.h"
 #include "model/diff/modify/mark_reachable.h"
 #include "presentation/presence.h"
+#include "presentation/cluster_file_presence.h"
 #include "utils.h"
 #include "utils/io.h"
 #include "utils/format.hpp"
@@ -124,9 +125,9 @@ void file_actor_t::on_block_request(message::block_request_t &message) noexcept
     auto &dest = p.reply_to;
     auto &req = message.payload.remote_request;
     auto folder = cluster->get_folders().by_id(get_folder(req));
-    auto folder_info = folder->get_folder_infos().by_device(*cluster->get_device());
-    auto file_info = folder_info->get_file_infos().by_name(get_name(req));
-    auto &path = file_info->get_path();
+    auto &folder_info = *folder->get_folder_infos().by_device(*cluster->get_device());
+    auto file_info = folder_info.get_file_infos().by_name(get_name(req));
+    auto &path = file_info->get_path(folder_info);
     auto file_opt = open_file_ro(path, true);
     auto ec = sys::error_code{};
     auto data = utils::bytes_t{};
@@ -161,7 +162,8 @@ void file_actor_t::on_controller_predown(net::message::controller_predown_t &mes
     }
 }
 
-auto file_actor_t::reflect(model::file_info_ptr_t &file_ptr, const bfs::path &path) noexcept -> outcome::result<void> {
+auto file_actor_t::reflect(model::file_info_ptr_t &file_ptr, const model::folder_info_t &folder_info,
+                           const bfs::path &path) noexcept -> outcome::result<void> {
     auto &file = *file_ptr;
     sys::error_code ec;
 
@@ -205,7 +207,7 @@ auto file_actor_t::reflect(model::file_info_ptr_t &file_ptr, const bfs::path &pa
         bool temporal = sz > 0;
         if (temporal) {
             LOG_TRACE(log, "touching file {} ({} bytes)", path.string(), sz);
-            auto file_opt = open_file_rw(path, &file);
+            auto file_opt = open_file_rw(path, &file, folder_info);
             if (!file_opt) {
                 auto &err = file_opt.assume_error();
                 LOG_ERROR(log, "cannot open file: {}: {}", path.string(), err.message());
@@ -226,7 +228,7 @@ auto file_actor_t::reflect(model::file_info_ptr_t &file_ptr, const bfs::path &pa
             }
         }
         set_perms = utils::platform_t::permissions_supported(path) && !file.has_no_permissions() &&
-                    !file.get_folder_info()->get_folder()->are_permissions_ignored();
+                    !folder_info.get_folder()->are_permissions_ignored();
     } else if (file.is_dir()) {
         LOG_DEBUG(log, "creating directory {}", path.string());
         bfs::create_directory(path, ec);
@@ -234,7 +236,7 @@ auto file_actor_t::reflect(model::file_info_ptr_t &file_ptr, const bfs::path &pa
             return ec;
         }
         set_perms = utils::platform_t::permissions_supported(path) && !file.has_no_permissions() &&
-                    !file.get_folder_info()->get_folder()->are_permissions_ignored();
+                    !folder_info.get_folder()->are_permissions_ignored();
     } else if (file.is_link()) {
         if (utils::platform_t::symlinks_supported()) {
             auto target = bfs::path(file.get_link_target());
@@ -272,15 +274,15 @@ auto file_actor_t::reflect(model::file_info_ptr_t &file_ptr, const bfs::path &pa
 auto file_actor_t::operator()(const model::diff::advance::remote_copy_t &diff, void *custom) noexcept
     -> outcome::result<void> {
     auto folder = cluster->get_folders().by_id(diff.folder_id);
-    auto file_info = folder->get_folder_infos().by_device_id(diff.peer_id);
+    auto &folder_info = *folder->get_folder_infos().by_device_id(diff.peer_id);
     auto name = get_name(diff.proto_source);
-    auto file = file_info->get_file_infos().by_name(name);
-    auto r = reflect(file, file->get_path());
+    auto file = folder_info.get_file_infos().by_name(name);
+    auto r = reflect(file, folder_info, file->get_path(folder_info));
     if (!r) {
         auto msg = r.error().message();
         LOG_ERROR(log, "cannot reflect (create) file '{}': {}", *file, msg);
         auto diff = model::diff::cluster_diff_ptr_t();
-        diff = new model::diff::modify::mark_reachable_t(*file, false);
+        diff = new model::diff::modify::mark_reachable_t(*file, folder_info, false);
         send<model::payload::model_update_t>(coordinator, std::move(diff), this);
     }
     return diff.visit_next(*this, custom);
@@ -289,12 +291,12 @@ auto file_actor_t::operator()(const model::diff::advance::remote_copy_t &diff, v
 auto file_actor_t::operator()(const model::diff::advance::remote_win_t &diff, void *custom) noexcept
     -> outcome::result<void> {
     auto folder = cluster->get_folders().by_id(diff.folder_id);
-    auto folder_info = folder->get_folder_infos();
-    auto file_info = folder_info.by_device_id(diff.peer_id);
+    auto folder_infos = folder->get_folder_infos();
+    auto &folder_info = *folder_infos.by_device_id(diff.peer_id);
     auto source_name = get_name(diff.proto_source);
     auto local_name = get_name(diff.proto_local);
-    auto file = file_info->get_file_infos().by_name(source_name);
-    auto &source_path = file->get_path();
+    auto file = folder_info.get_file_infos().by_name(source_name);
+    auto &source_path = file->get_path(folder_info);
     auto target_path = folder->get_path() / local_name;
     LOG_DEBUG(log, "renaming {} -> {}", source_path, target_path);
     auto ec = sys::error_code{};
@@ -303,7 +305,7 @@ auto file_actor_t::operator()(const model::diff::advance::remote_win_t &diff, vo
     if (ec) {
         LOG_ERROR(log, "cannot rename file '{}': {}", file, ec.message());
         auto diff = model::diff::cluster_diff_ptr_t();
-        diff = new model::diff::modify::mark_reachable_t(*file, false);
+        diff = new model::diff::modify::mark_reachable_t(*file, folder_info, false);
         send<model::payload::model_update_t>(coordinator, std::move(diff), this);
     }
     return diff.visit_next(*this, custom);
@@ -313,11 +315,11 @@ auto file_actor_t::operator()(const model::diff::modify::finish_file_t &diff, vo
     -> outcome::result<void> {
     auto folder = cluster->get_folders().by_id(diff.folder_id);
     if (folder) {
-        auto file_info = folder->get_folder_infos().by_device_id(diff.peer_id);
-        if (file_info) {
-            auto file = file_info->get_file_infos().by_name(diff.file_name);
+        auto folder_info = folder->get_folder_infos().by_device_id(diff.peer_id);
+        if (folder_info) {
+            auto file = folder_info->get_file_infos().by_name(diff.file_name);
             if (file) {
-                auto &local_path = file->get_path();
+                auto &local_path = file->get_path(*folder_info);
                 auto action = diff.action;
 
                 if (action == model::advance_action_t::resolve_remote_win) {
@@ -338,8 +340,8 @@ auto file_actor_t::operator()(const model::diff::modify::finish_file_t &diff, vo
                 if (!backend) {
                     LOG_DEBUG(log, "attempt to flush non-opened file {}, re-open it as temporal",
                               local_path.generic_string());
-                    auto path_tmp = make_temporal(file->get_path());
-                    auto result = open_file_rw(path_tmp, file);
+                    auto path_tmp = make_temporal(local_path);
+                    auto result = open_file_rw(path_tmp, file, *folder_info);
                     if (!result) {
                         auto &ec = result.assume_error();
                         LOG_ERROR(log, "cannot open file: {}: {}", path_tmp.string(), ec.message());
@@ -358,7 +360,7 @@ auto file_actor_t::operator()(const model::diff::modify::finish_file_t &diff, vo
 
                 LOG_INFO(log, "file {} ({} bytes) is now locally available", *file, file->get_size());
 
-                auto ack = model::diff::advance::advance_t::create(action, *file, *sequencer);
+                auto ack = model::diff::advance::advance_t::create(action, *file, *folder_info, *sequencer);
                 send<model::payload::model_update_t>(coordinator, std::move(ack), this);
             }
         }
@@ -370,11 +372,11 @@ auto file_actor_t::operator()(const model::diff::modify::append_block_t &diff, v
     -> outcome::result<void> {
     auto guard = write_guard_t(*this, diff);
     auto folder = cluster->get_folders().by_id(diff.folder_id);
-    auto file_info = folder->get_folder_infos().by_device_id(diff.device_id);
-    auto file = file_info->get_file_infos().by_name(diff.file_name);
-    auto &path = file->get_path();
+    auto &folder_info = *folder->get_folder_infos().by_device_id(diff.device_id);
+    auto file = folder_info.get_file_infos().by_name(diff.file_name);
+    auto &path = file->get_path(folder_info);
     auto path_str = path.string();
-    auto file_opt = open_file_rw(path, file);
+    auto file_opt = open_file_rw(path, file, folder_info);
     if (!file_opt) {
         auto &err = file_opt.assume_error();
         LOG_ERROR(log, "cannot open file: {}: {}", path_str, err.message());
@@ -388,9 +390,9 @@ auto file_actor_t::operator()(const model::diff::modify::append_block_t &diff, v
     return r ? diff.visit_next(*this, custom) : r;
 }
 
-auto file_actor_t::get_source_for_cloning(model::file_info_ptr_t &source, const file_ptr_t &target_backend) noexcept
-    -> outcome::result<file_ptr_t> {
-    auto source_path = source->get_path();
+auto file_actor_t::get_source_for_cloning(model::file_info_ptr_t &source, const model::folder_info_t &source_fi,
+                                          const file_ptr_t &target_backend) noexcept -> outcome::result<file_ptr_t> {
+    auto source_path = source->get_path(source_fi);
     if (source_path == target_backend->get_path()) {
         return target_backend;
     }
@@ -401,7 +403,7 @@ auto file_actor_t::get_source_for_cloning(model::file_info_ptr_t &source, const
         return cached;
     } else if (auto cached = rw_cache->get(source_tmp); cached) {
         return cached;
-    } else if (auto cached = ro_cache.get(source_tmp); cached) {
+    } else if (auto cached = ro_cache.get(source_path); cached) {
         return cached;
     } else if (auto cached = ro_cache.get(source_tmp); cached) {
         return cached;
@@ -416,22 +418,22 @@ auto file_actor_t::operator()(const model::diff::modify::clone_block_t &diff, vo
     -> outcome::result<void> {
     auto guard = write_guard_t(*this, diff);
     auto folder = cluster->get_folders().by_id(diff.folder_id);
-    auto target_folder_info = folder->get_folder_infos().by_device_id(diff.device_id);
-    auto target = target_folder_info->get_file_infos().by_name(diff.file_name);
+    auto &target_folder_info = *folder->get_folder_infos().by_device_id(diff.device_id);
+    auto target = target_folder_info.get_file_infos().by_name(diff.file_name);
 
     auto source_folder = cluster->get_folders().by_id(diff.source_folder_id);
     auto source_folder_info = source_folder->get_folder_infos().by_device_id(diff.source_device_id);
     auto source = source_folder_info->get_file_infos().by_name(diff.source_file_name);
 
-    auto &target_path = target->get_path();
-    auto file_opt = open_file_rw(target_path, target);
+    auto &target_path = target->get_path(target_folder_info);
+    auto file_opt = open_file_rw(target_path, target, target_folder_info);
     if (!file_opt) {
         auto &err = file_opt.assume_error();
         LOG_ERROR(log, "cannot open file: {}: {}", target_path.string(), err.message());
         return err;
     }
     auto target_backend = std::move(file_opt.assume_value());
-    auto source_backend_opt = get_source_for_cloning(source, target_backend);
+    auto source_backend_opt = get_source_for_cloning(source, *source_folder_info, target_backend);
     if (!source_backend_opt) {
         auto ec = source_backend_opt.assume_error();
         LOG_ERROR(log, "cannot open source file for cloning: {}: {}", diff.source_file_name, ec.message());
@@ -439,15 +441,15 @@ auto file_actor_t::operator()(const model::diff::modify::clone_block_t &diff, vo
     }
 
     auto &source_backend = source_backend_opt.assume_value();
-    auto &block = source->get_blocks().at(diff.source_block_index);
+    auto block = source->iterate_blocks(diff.source_block_index).next();
     auto target_offset = target->get_block_offset(diff.block_index);
     auto source_offset = source->get_block_offset(diff.source_block_index);
     auto r = guard(target_backend->copy(target_offset, *source_backend, source_offset, block->get_size()));
     return r ? diff.visit_next(*this, custom) : r;
 }
 
-auto file_actor_t::open_file_rw(const std::filesystem::path &path, model::file_info_ptr_t info) noexcept
-    -> outcome::result<file_ptr_t> {
+auto file_actor_t::open_file_rw(const std::filesystem::path &path, model::file_info_ptr_t info,
+                                const model::folder_info_t &folder_info) noexcept -> outcome::result<file_ptr_t> {
     auto augmentation = info.get()->get_augmentation();
     auto presence = static_cast<presentation::presence_t *>(augmentation.get());
     if (!presence->is_unique()) {
@@ -476,7 +478,7 @@ auto file_actor_t::open_file_rw(const std::filesystem::path &path, model::file_i
         }
     }
 
-    auto option = file_t::open_write(info);
+    auto option = file_t::open_write(info, folder_info);
     if (!option) {
         return option.assume_error();
     }

+ 5 - 2
src/fs/file_actor.h

@@ -75,9 +75,11 @@ struct SYNCSPIRIT_API file_actor_t : public r::actor_base_t, private model::diff
     void on_controller_predown(net::message::controller_predown_t &message) noexcept;
 
     outcome::result<file_ptr_t> get_source_for_cloning(model::file_info_ptr_t &source,
+                                                       const model::folder_info_t &source_fi,
                                                        const file_ptr_t &target_backend) noexcept;
 
-    outcome::result<file_ptr_t> open_file_rw(const bfs::path &path, model::file_info_ptr_t info) noexcept;
+    outcome::result<file_ptr_t> open_file_rw(const bfs::path &path, model::file_info_ptr_t info,
+                                             const model::folder_info_t &folder_info) noexcept;
     outcome::result<file_ptr_t> open_file_ro(const bfs::path &path, bool use_cache = false) noexcept;
 
     outcome::result<void> operator()(const model::diff::advance::remote_copy_t &, void *) noexcept override;
@@ -86,7 +88,8 @@ struct SYNCSPIRIT_API file_actor_t : public r::actor_base_t, private model::diff
     outcome::result<void> operator()(const model::diff::modify::append_block_t &, void *) noexcept override;
     outcome::result<void> operator()(const model::diff::modify::clone_block_t &, void *) noexcept override;
 
-    outcome::result<void> reflect(model::file_info_ptr_t &file, const bfs::path &path) noexcept;
+    outcome::result<void> reflect(model::file_info_ptr_t &file, const model::folder_info_t &fi,
+                                  const bfs::path &path) noexcept;
 
     model::cluster_ptr_t cluster;
     model::sequencer_ptr_t sequencer;

+ 6 - 5
src/fs/fs_supervisor.cpp

@@ -177,11 +177,11 @@ auto fs_supervisor_t::apply(const model::diff::advance::advance_t &diff, void *c
         auto folder_entity = static_cast<presentation::folder_entity_t *>(augmentation);
         if (folder_entity) {
             auto &folder_infos = folder->get_folder_infos();
-            auto local_fi = folder_infos.by_device(*cluster->get_device());
+            auto &local_fi = *folder_infos.by_device(*cluster->get_device());
             auto file_name = proto::get_name(diff.proto_local);
-            auto local_file = local_fi->get_file_infos().by_name(file_name);
+            auto local_file = local_fi.get_file_infos().by_name(file_name);
             if (local_file) {
-                folder_entity->on_insert(*local_file);
+                folder_entity->on_insert(*local_file, local_fi);
             }
         }
     }
@@ -198,14 +198,15 @@ auto fs_supervisor_t::apply(const model::diff::peer::update_folder_t &diff, void
 
         auto &devices_map = cluster->get_devices();
         auto peer = devices_map.by_sha256(diff.peer_id);
-        auto &files_map = folder->get_folder_infos().by_device(*peer)->get_file_infos();
+        auto &folder_info = *folder->get_folder_infos().by_device(*peer);
+        auto &files_map = folder_info.get_file_infos();
 
         for (auto &file : diff.files) {
             auto file_name = proto::get_name(file);
             auto file_info = files_map.by_name(file_name);
             auto augmentation = file_info->get_augmentation().get();
             if (!augmentation) {
-                folder_entity->on_insert(*file_info);
+                folder_entity->on_insert(*file_info, folder_info);
             }
         }
     }

+ 8 - 7
src/fs/scan_actor.cpp

@@ -99,6 +99,7 @@ void scan_actor_t::on_scan(message::scan_progress_t &message) noexcept {
     LOG_TRACE(log, "on_scan, folder = {}", folder_id);
 
     auto folder = cluster->get_folders().by_id(folder_id);
+    auto folder_local = folder->get_folder_infos().by_device(*folder->get_cluster()->get_device());
     bool stop_processing = false;
     bool completed = false;
     if (folder->is_suspended()) {
@@ -118,20 +119,18 @@ void scan_actor_t::on_scan(message::scan_progress_t &message) noexcept {
                 } else if constexpr (std::is_same_v<T, scan_errors_t>) {
                     task->push(new local::io_failure_t(std::move(r)), 0, true);
                 } else if constexpr (std::is_same_v<T, unchanged_meta_t>) {
-                    task->push(new local::file_availability_t(r.file), 0, true);
+                    task->push(new local::file_availability_t(r.file, *folder_local), 0, true);
                 } else if constexpr (std::is_same_v<T, removed_t>) {
                     auto &file = *r.file;
-                    auto folder = file.get_folder_info()->get_folder();
                     LOG_DEBUG(log, "locally removed '{}'", file);
-                    auto folder_id = std::string(folder->get_id());
                     auto fi = file.as_proto(false);
                     proto::set_deleted(fi, true);
-                    task->push(new advance::local_update_t(*cluster, *sequencer, std::move(fi), std::move(folder_id)),
+                    task->push(new advance::local_update_t(*cluster, *sequencer, std::move(fi), std::string(folder_id)),
                                0, true);
                 } else if constexpr (std::is_same_v<T, changed_meta_t>) {
                     auto &file = *r.file;
                     auto &metadata = r.metadata;
-                    auto errs = initiate_hash(task, file.get_path(), metadata);
+                    auto errs = initiate_hash(task, file.get_path(*folder_local), metadata);
                     if (errs.empty()) {
                         stop_processing = true;
                     } else {
@@ -146,8 +145,9 @@ void scan_actor_t::on_scan(message::scan_progress_t &message) noexcept {
                     }
                 } else if constexpr (std::is_same_v<T, incomplete_t>) {
                     auto &f = r.file;
+                    auto fi = folder->get_folder_infos().by_uuid(f->get_folder_uuid());
                     stop_processing = true;
-                    send<payload::rehash_needed_t>(address, task, std::move(f), std::move(r.opened_file));
+                    send<payload::rehash_needed_t>(address, task, std::move(f), *fi, std::move(r.opened_file));
                 } else if constexpr (std::is_same_v<T, incomplete_removed_t>) {
                     auto &file = *r.file;
                 } else if constexpr (std::is_same_v<T, orphaned_removed_t>) {
@@ -262,6 +262,7 @@ void scan_actor_t::on_hash(hasher::message::digest_response_t &res) noexcept {
         return do_shutdown(ee);
     }
 
+    auto &fi = info.get_folder();
     bool queued_next = false;
     auto &digest = res.payload.res.digest;
     auto block_index = rp.block_index;
@@ -286,7 +287,7 @@ void scan_actor_t::on_hash(hasher::message::digest_response_t &res) noexcept {
                 }
             }
             if (valid_blocks_count) {
-                task.push(new model::diff::local::blocks_availability_t(*file, info.valid_blocks()));
+                task.push(new model::diff::local::blocks_availability_t(*file, fi, info.valid_blocks()));
             } else {
                 LOG_DEBUG(log, "file '{}' has no unknown local blocks, ingnoring", *file);
             }

+ 0 - 0
src/fs/scan_task.cpp


Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels