2 Commits 4844087021 ... 0906cbd30c

Autore SHA1 Messaggio Data
  Ivan Baidakou 0906cbd30c core: file_info_t: drop block-size & missing blocks cache fields 1 settimana fa
  Ivan Baidakou d4fe71e848 core: file_info_t: drop non-used function 1 settimana fa

+ 2 - 2
src/model/diff/local/file_availability.cpp

@@ -22,14 +22,14 @@ auto file_availability_t::apply_impl(apply_controller_t &controller, void *custo
         auto &folder_info = *folder->get_folder_infos().by_device(*cluster.get_device());
         auto f = folder_info.get_file_infos().by_name(file->get_name()->get_full_name());
         if (f->get_version().identical_to(version)) {
-            f->mark_local(true, folder_info);
-            LOG_TRACE(log, "file_availability_t, mark local file '{}", *file);
             auto count = f->iterate_blocks().get_total();
+            LOG_TRACE(log, "file_availability_t, mark local file '{}', blocks = {}", *file, count);
             for (std::uint32_t i = 0; i < count; ++i) {
                 if (!f->is_locally_available(i)) {
                     f->mark_local_available(i);
                 }
             }
+            f->mark_local(true, folder_info);
             f->notify_update();
         }
     }

+ 50 - 54
src/model/file_info.cpp

@@ -6,7 +6,6 @@
 #include "folder_info.h"
 #include "device.h"
 #include "db/prefix.h"
-#include "fs/utils.h"
 #include "misc/error_code.h"
 #include "misc/file_iterator.h"
 #include "proto/proto-helpers.h"
@@ -187,7 +186,9 @@ auto file_info_t::get_name() const noexcept -> const path_ptr_t & { return name;
 
 std::uint64_t file_info_t::get_block_offset(size_t block_index) const noexcept {
     assert(flags & f_type_file && !content.file.blocks.empty());
-    return content.file.block_size * block_index;
+    auto ptr = reinterpret_cast<std::uintptr_t>(content.file.blocks.front());
+    auto block = reinterpret_cast<const block_info_t *>(ptr & PTR_MASK);
+    return block->get_size() * block_index;
 }
 
 auto file_info_t::fields_update(const db::FileInfo &source, model::path_cache_t &path_cache) noexcept
@@ -215,14 +216,16 @@ auto file_info_t::fields_update(const db::FileInfo &source, model::path_cache_t
         new (&content.file) size_full_t();
         auto declared_size = db::get_size(source);
         bool has_content = declared_size && (flags & f_type_file);
-        content.file.block_size = has_content ? db::get_block_size(source) : 0;
-        auto blocks_count = has_content ? db::get_blocks_size(source) : 0;
-        return reserve_blocks(blocks_count, declared_size);
+        auto block_size = db::get_blocks_size(source);
+        auto blocks_count = has_content ? block_size : 0;
+        if (blocks_count) {
+            reserve_blocks(blocks_count);
+        }
     } else {
         new (&content.non_file) size_less_t();
         content.non_file.symlink_target = db::get_symlink_target(source);
-        return outcome::success();
     }
+    return outcome::success();
 }
 
 auto file_info_t::fields_update(const proto::FileInfo &source, model::path_cache_t &path_cache) noexcept
@@ -249,14 +252,16 @@ auto file_info_t::fields_update(const proto::FileInfo &source, model::path_cache
         new (&content.file) size_full_t();
         auto declared_size = proto::get_size(source);
         bool has_content = declared_size && (flags & f_type_file);
-        content.file.block_size = has_content ? proto::get_block_size(source) : 0;
-        auto blocks_count = has_content ? proto::get_blocks_size(source) : 0;
-        return reserve_blocks(blocks_count, declared_size);
+        auto block_size = proto::get_blocks_size(source);
+        auto blocks_count = has_content ? block_size : 0;
+        if (blocks_count) {
+            reserve_blocks(blocks_count);
+        }
     } else {
         new (&content.non_file) size_less_t();
         content.non_file.symlink_target = proto::get_symlink_target(source);
-        return outcome::success();
     }
+    return outcome::success();
 }
 
 utils::bytes_view_t file_info_t::get_uuid() const noexcept { return {key + uuid_length, uuid_length}; }
@@ -280,7 +285,7 @@ db::FileInfo file_info_t::as_db(bool include_blocks) const noexcept {
     db::set_version(r, version.as_proto());
     if (flags & f_type_file) {
         db::set_size(r, get_size());
-        db::set_block_size(r, content.file.block_size);
+        db::set_block_size(r, get_block_size());
         if (include_blocks) {
             for (auto b_raw : content.file.blocks) {
                 auto ptr = reinterpret_cast<std::uintptr_t>(b_raw);
@@ -312,8 +317,8 @@ proto::FileInfo file_info_t::as_proto(bool include_blocks) const noexcept {
     proto::set_version(r, version.as_proto());
 
     if (flags & f_type_file) {
-        proto::set_block_size(r, content.file.block_size);
         proto::set_size(r, get_size());
+        proto::set_block_size(r, get_block_size());
         if (include_blocks) {
             size_t offset = 0;
             for (auto b_raw : content.file.blocks) {
@@ -332,28 +337,9 @@ proto::FileInfo file_info_t::as_proto(bool include_blocks) const noexcept {
     return r;
 }
 
-outcome::result<void> file_info_t::reserve_blocks(size_t block_count, int64_t declared_size) noexcept {
-    size_t count = 0;
-    if (!block_count && !(flags & f_deleted) && !(flags & f_invalid)) {
-        if ((declared_size < content.file.block_size) && (declared_size >= (int64_t)fs::block_sizes[0])) {
-            return make_error_code(error_code_t::invalid_block_size);
-        }
-        if (declared_size) {
-            if (!content.file.block_size) {
-                return make_error_code(error_code_t::invalid_block_size);
-            }
-            count = declared_size / content.file.block_size;
-            if ((int64_t)(content.file.block_size * count) != declared_size) {
-                ++count;
-            }
-        }
-    } else {
-        count = block_count;
-    }
+void file_info_t::reserve_blocks(size_t block_count) noexcept {
     remove_blocks();
-    content.file.blocks.resize(count);
-    content.file.missing_blocks = !(flags & f_deleted) && !(flags & f_invalid) && (flags & f_type_file) ? count : 0;
-    return outcome::success();
+    content.file.blocks.resize(block_count);
 }
 
 utils::bytes_t file_info_t::serialize(bool include_blocks) const noexcept { return db::encode(as_db(include_blocks)); }
@@ -371,8 +357,22 @@ void file_info_t::mark_local(bool available, const folder_info_t &folder_info) n
         flags = flags | f_local;
     } else {
         flags = flags & ~f_local;
+        flags = flags & ~f_available;
     }
     if (available) {
+        auto available = std::uint32_t{0};
+        if (flags & f_type_file) {
+            for (auto b_raw : content.file.blocks) {
+                auto ptr = reinterpret_cast<std::uintptr_t>(b_raw);
+                if (ptr & LOCAL_MASK) {
+                    ++available;
+                }
+            }
+        }
+        if (!(flags & f_type_file) || static_cast<std::uint32_t>(content.file.blocks.size()) == available) {
+            flags = flags | f_available;
+        }
+
         auto self = folder_info.get_device();
         auto folder = folder_info.get_folder();
         for (auto it : folder->get_folder_infos()) {
@@ -404,8 +404,18 @@ void file_info_t::mark_local_available(size_t block_index) noexcept {
     auto block_mangled = reinterpret_cast<block_info_t *>(ptr);
     blocks[block_index] = block_mangled;
 
-    assert(content.file.missing_blocks);
-    --content.file.missing_blocks;
+    if (!(flags & f_available)) {
+        auto available = std::uint32_t{0};
+        for (auto b_raw : blocks) {
+            auto ptr = reinterpret_cast<std::uintptr_t>(b_raw);
+            if (ptr & LOCAL_MASK) {
+                ++available;
+            }
+        }
+        if (available == static_cast<std::uint32_t>(blocks.size())) {
+            flags = flags | f_available;
+        }
+    }
 }
 
 bool file_info_t::is_locally_available(size_t block_index) const noexcept {
@@ -416,8 +426,9 @@ bool file_info_t::is_locally_available(size_t block_index) const noexcept {
 }
 
 bool file_info_t::is_locally_available() const noexcept {
-    return flags & f_type_file ? content.file.missing_blocks == 0 : true;
-}
+    auto r = !(flags & f_type_file) || ((flags & f_available) || content.file.blocks.empty());
+    return r;
+};
 
 const std::filesystem::path file_info_t::get_path(const folder_info_t &folder_info) const noexcept {
     auto own_name = boost::nowide::widen(name->get_full_name());
@@ -432,16 +443,6 @@ void file_info_t::synchronizing_lock() noexcept { flags |= flags_t::f_synchroniz
 
 bool file_info_t::is_synchronizing() const noexcept { return flags & flags_t::f_synchronizing; }
 
-bool file_info_t::is_unlocking() const noexcept { return flags & flags_t::f_unlocking; }
-
-void file_info_t::set_unlocking(bool value) noexcept {
-    if (value) {
-        flags |= flags_t::f_unlocking;
-    } else {
-        flags = flags & ~flags_t::f_unlocking;
-    }
-}
-
 void file_info_t::assign_block(model::block_info_t *block, size_t index) noexcept {
     auto &blocks = content.file.blocks;
     assert(flags & f_type_file);
@@ -459,7 +460,7 @@ void file_info_t::remove_blocks() noexcept {
             auto block = reinterpret_cast<block_info_t *>(ptr & PTR_MASK);
             remove_block(block);
         }
-        content.file.missing_blocks = content.file.blocks.size();
+        flags = flags & ~f_available;
     }
 }
 
@@ -526,8 +527,6 @@ void file_info_t::update(const file_info_t &other) noexcept {
     if (!(flags & f_type_file)) {
         content.non_file.symlink_target = other.content.non_file.symlink_target;
     } else {
-        content.file.block_size = other.content.file.block_size;
-
         auto local_block_hashes = hashes_t{};
         for (auto b_raw : content.file.blocks) {
             if (b_raw) {
@@ -555,7 +554,6 @@ void file_info_t::update(const file_info_t &other) noexcept {
         remove_blocks();
 
         content.file.blocks.resize(sz);
-        content.file.missing_blocks = sz;
         for (size_t i = 0; i < sz; ++i) {
             auto b_raw = other.content.file.blocks[i];
             if (b_raw) {
@@ -563,9 +561,7 @@ void file_info_t::update(const file_info_t &other) noexcept {
                 auto block = reinterpret_cast<block_info_t *>(ptr & PTR_MASK);
                 assign_block(block, i);
                 auto already_local = ptr & LOCAL_MASK;
-                if (already_local) {
-                    --content.file.missing_blocks;
-                } else if (local_block_hashes.contains(block->get_hash())) {
+                if (local_block_hashes.contains(block->get_hash())) {
                     mark_local_available(i);
                 }
             }

+ 21 - 17
src/model/file_info.h

@@ -38,16 +38,16 @@ struct SYNCSPIRIT_API file_info_t {
 
     // clang-format off
     enum flags_t: std::uint16_t {
-        f_type_file      = 1 << 0,
-        f_type_dir       = 1 << 1,
-        f_type_link      = 1 << 2,
-        f_deleted        = 1 << 3,
-        f_invalid        = 1 << 4,
-        f_no_permissions = 1 << 5,
-        f_synchronizing  = 1 << 6,
-        f_unreachable    = 1 << 7,
-        f_unlocking      = 1 << 8,
-        f_local          = 1 << 9,
+        f_type_file        = 1 << 0,
+        f_type_dir         = 1 << 1,
+        f_type_link        = 1 << 2,
+        f_deleted          = 1 << 3,
+        f_invalid          = 1 << 4,
+        f_no_permissions   = 1 << 5,
+        f_synchronizing    = 1 << 6,
+        f_unreachable      = 1 << 7,
+        f_local            = 1 << 8,
+        f_available        = 1 << 9,
     };
     // clang-format on
 
@@ -146,7 +146,16 @@ struct SYNCSPIRIT_API file_info_t {
 
     std::int64_t get_size() const noexcept;
 
-    std::int32_t get_block_size() const noexcept { return (flags & f_type_file) ? content.file.block_size : 0; }
+    std::int32_t get_block_size() const noexcept {
+        auto has_blocks = (flags & f_type_file && !content.file.blocks.empty());
+        if (has_blocks) {
+            auto &blocks = content.file.blocks;
+            auto ptr = reinterpret_cast<std::uintptr_t>(blocks.front());
+            auto block = reinterpret_cast<const block_info_t *>(ptr & PTR_MASK);
+            return block->get_size();
+        }
+        return 0;
+    }
     std::uint64_t get_block_offset(size_t block_index) const noexcept;
 
     void mark_unreachable(bool value) noexcept;
@@ -170,9 +179,6 @@ struct SYNCSPIRIT_API file_info_t {
     void synchronizing_lock() noexcept;
     void synchronizing_unlock() noexcept;
 
-    bool is_unlocking() const noexcept;
-    void set_unlocking(bool value) noexcept;
-
     proto::FileInfo get() const noexcept;
     bool identical_to(const proto::FileInfo &file) const noexcept;
 
@@ -209,8 +215,6 @@ struct SYNCSPIRIT_API file_info_t {
     struct size_full_t {
         ~size_full_t();
         blocks_t blocks;
-        std::uint32_t missing_blocks;
-        std::int32_t block_size;
     };
 
     struct size_less_t {
@@ -227,7 +231,7 @@ struct SYNCSPIRIT_API file_info_t {
 
     file_info_t(utils::bytes_view_t key, const folder_info_ptr_t &folder_info_) noexcept;
     file_info_t(const bu::uuid &uuid, const folder_info_ptr_t &folder_info_) noexcept;
-    outcome::result<void> reserve_blocks(size_t block_count, std::int64_t declared_size) noexcept;
+    void reserve_blocks(size_t block_count) noexcept;
 
     void update_blocks(const proto::FileInfo &remote_info) noexcept;
     void remove_block(block_info_t *block) noexcept;

+ 0 - 3
src/model/misc/error_code.cpp

@@ -105,9 +105,6 @@ std::string error_code_category_t::message(int c) const {
     case error_code_t::malformed_deviceid:
         r = "device id is malformed";
         break;
-    case error_code_t::invalid_block_size:
-        r = "block size is invalid (i.e. greater than file size)";
-        break;
     case error_code_t::missing_version:
         r = "file version is missing";
         break;

+ 0 - 1
src/model/misc/error_code.h

@@ -40,7 +40,6 @@ enum class error_code_t {
     folder_is_already_shared,
     malformed_deviceid,
     folder_is_not_shared,
-    invalid_block_size,
     missing_version,
     mismatch_file_size,
     invalid_sequence,

+ 1 - 0
tests/026-file_info.cpp

@@ -94,6 +94,7 @@ TEST_CASE("file_info_t::local_file", "[model]") {
     SECTION("no local file") {
         auto file_peer = file_info_t::create(sequencer->next_uuid(), pr_file, folder_peer).value();
         CHECK(!folder_my->get_file_infos().by_name("a.txt"));
+        CHECK(file_peer->is_locally_available());
     }
 
     SECTION("there is identical local file") {

+ 6 - 2
tests/030-diff-load-cluster.cpp

@@ -318,6 +318,10 @@ TEST_CASE("loading cluster (file info + block)", "[model]") {
     proto::set_block_size(pr_fi, 5ul);
     auto &version = proto::get_version(pr_fi);
     proto::add_counters(version, proto::Counter(my_device->device_id().get_uint(), 0));
+    for (size_t i = 0; i < 11; ++i) {
+        proto::add_blocks(pr_fi, bi);
+    }
+
     auto fi = file_info_t::create(sequencer->next_uuid(), pr_fi, folder_info).value();
     CHECK(fi);
     for (size_t i = 0; i < 11; ++i) {
@@ -337,11 +341,11 @@ TEST_CASE("loading cluster (file info + block)", "[model]") {
         std::copy(id.begin(), id.end(), key.data() + 1);
         target = file_info_t::create(key, file_info_db, std::move(folder_info)).value();
         REQUIRE(target);
-        CHECK(target->get_block_size() == 5ul);
-        CHECK(target->iterate_blocks().get_total() == 11ul);
         for (size_t i = 0; i < 11; ++i) {
             target->assign_block(block.get(), i);
         }
+        CHECK(target->get_block_size() == 5ul);
+        CHECK(target->iterate_blocks().get_total() == 11ul);
         CHECK(target->get_size() == 55ul);
     }
 

+ 4 - 0
tests/031-diff-cluster_update.cpp

@@ -395,6 +395,7 @@ TEST_CASE("cluster update, reset folder", "[model]") {
         proto::set_size(f, 5ul);
         proto::set_block_size(f, 5ul);
         proto::set_sequence(f, 1);
+        proto::add_blocks(f, bi1);
         auto &v = proto::get_version(f);
         proto::add_counters(v, proto::Counter(my_device->device_id().get_uint(), 0));
         return f;
@@ -408,6 +409,7 @@ TEST_CASE("cluster update, reset folder", "[model]") {
         proto::set_size(f, 5ul);
         proto::set_block_size(f, 5ul);
         proto::set_sequence(f, 1);
+        proto::add_blocks(f, bi2);
         auto &v = proto::get_version(f);
         proto::add_counters(v, proto::Counter(peer_device->device_id().get_uint(), 0));
         return f;
@@ -422,6 +424,8 @@ TEST_CASE("cluster update, reset folder", "[model]") {
         proto::set_size(f, 10ul);
         proto::set_block_size(f, 5ul);
         proto::set_sequence(f, 2);
+        proto::add_blocks(f, bi2);
+        proto::add_blocks(f, bi3);
         auto &v = proto::get_version(f);
         proto::add_counters(v, proto::Counter(peer_device->device_id().get_uint(), 0));
         return f;

+ 10 - 0
tests/053-scan_task.cpp

@@ -215,6 +215,7 @@ SECTION("regular files") {
         proto::set_size(pr_file, 5);
         proto::set_modified_s(pr_file, modified);
         proto::set_permissions(pr_file, perms);
+        proto::add_blocks(pr_file, bi);
 
         auto file = file_info_t::create(sequencer->next_uuid(), pr_file, folder_my).value();
         file->assign_block(block.get(), 0);
@@ -290,6 +291,7 @@ SECTION("regular files") {
         proto::set_size(pr_file, 5);
         proto::set_modified_s(pr_file, modified);
         proto::set_permissions(pr_file, perms);
+        proto::add_blocks(pr_file, bi);
 
         auto info_file = file_info_t::create(sequencer->next_uuid(), pr_file, folder_my).value();
         info_file->assign_block(block.get(), 0);
@@ -330,6 +332,7 @@ SECTION("regular files") {
         proto::set_block_size(pr_file, 5);
         proto::set_size(pr_file, 5);
         proto::set_modified_s(pr_file, modified);
+        proto::add_blocks(pr_file, bi);
 
         auto file = file_info_t::create(sequencer->next_uuid(), pr_file, folder_my).value();
         file->assign_block(block.get(), 0);
@@ -468,6 +471,7 @@ SECTION("regular files") {
             proto::set_size(pr_file, 5);
             proto::set_modified_s(pr_file, modified);
             proto::set_permissions(pr_file, perms);
+            proto::add_blocks(pr_file, bi);
 
             file = file_info_t::create(sequencer->next_uuid(), pr_file, folder_my).value();
             file->assign_block(block.get(), 0);
@@ -498,6 +502,7 @@ SECTION("regular files") {
             proto::set_size(pr_file, 5);
             proto::set_modified_s(pr_file, modified + 1);
             proto::set_permissions(pr_file, perms);
+            proto::add_blocks(pr_file, bi);
 
             file = file_info_t::create(sequencer->next_uuid(), pr_file, folder_my).value();
             file->assign_block(block.get(), 0);
@@ -522,6 +527,7 @@ SECTION("regular files") {
             proto::set_size(pr_file, 5);
             proto::set_modified_s(pr_file, modified);
             proto::set_permissions(pr_file, static_cast<uint32_t>(-1));
+            proto::add_blocks(pr_file, bi);
 
             auto path = root_path / "a.txt";
             write_file(path, "12345");
@@ -582,6 +588,7 @@ SECTION("regular files") {
         proto::set_block_size(pr_file, 5);
         proto::set_size(pr_file, 5);
         proto::set_modified_s(pr_file, modified);
+        proto::add_blocks(pr_file, bi);
 
         auto path = root_path / "a.txt.syncspirit-tmp";
 
@@ -727,6 +734,8 @@ SECTION("regular files") {
 
             proto::set_size(pr_file, file_peer->get_size() + 10);
             proto::add_counters(v, proto::Counter(peer_device->device_id().get_uint(), 2));
+            proto::add_blocks(pr_file, bi);
+            proto::add_blocks(pr_file, bi);
 
             auto file_peer2 = file_info_t::create(sequencer->next_uuid(), pr_file, folder_peer2).value();
             file_peer2->assign_block(block.get(), 0);
@@ -787,6 +796,7 @@ SECTION("regular files") {
         proto::set_size(pr_file, 5);
         proto::set_modified_s(pr_file, modified);
         proto::set_permissions(pr_file, perms);
+        proto::add_blocks(pr_file, bi);
         auto file_my = file_info_t::create(sequencer->next_uuid(), pr_file, folder_my).value();
         file_my->assign_block(block.get(), 0);
 

+ 0 - 0
tests/071-fs_actor.cpp


Some files were not shown because too many files changed in this diff