From 66d567fea8745476a9932887c7074ef296158b9d Mon Sep 17 00:00:00 2001 From: IlyaShurupov Date: Sat, 30 Mar 2024 09:12:07 +0300 Subject: [PATCH] stable feature complete --- inc/FileSystem.hpp | 15 ++++++--------- inc/Link.hpp | 1 + src/Directory.cpp | 21 +++++++++++++++++++-- src/FileSystem.cpp | 10 +++++++--- src/Link.cpp | 22 ++++++++++++++++++++-- 5 files changed, 53 insertions(+), 16 deletions(-) diff --git a/inc/FileSystem.hpp b/inc/FileSystem.hpp index 4ad88ad..9f6522c 100644 --- a/inc/FileSystem.hpp +++ b/inc/FileSystem.hpp @@ -5,15 +5,12 @@ #include -// restore path unwindingk -// RESTORE LINKS -// COPY operator update link targets on copied nodes - -// use in node 'is_delete' flag and travers all nodes with link checks -// deleting directory - mark all nodes as deleted -// traverse and check for links -// unlink if those links are outgoing - +// Fix copy +// read file with commands +// in subtree links should be in-tree after copy operation +// use C:/ for root +// links have unique names +// tests class FileSystem { public: diff --git a/inc/Link.hpp b/inc/Link.hpp index ed3c8c6..474b519 100644 --- a/inc/Link.hpp +++ b/inc/Link.hpp @@ -20,6 +20,7 @@ public: void dumpUtil(std::stringstream& ss, const Key& key, ui32 currentDepth, std::vector& indents) override; static bool linkNodes(const std::shared_ptr& link, const std::shared_ptr& target, bool hard); + static void unlinkNodes(const std::shared_ptr& link); private: std::weak_ptr mLink; diff --git a/src/Directory.cpp b/src/Directory.cpp index 015862f..c3d053e 100644 --- a/src/Directory.cpp +++ b/src/Directory.cpp @@ -1,12 +1,20 @@ #include "Directory.hpp" +#include "Link.hpp" #include #include Directory::Directory() = default; -Directory::~Directory() = default; +Directory::~Directory() { + for (auto& member : mMembers) { + std::shared_ptr& node = member.second; + if (auto linkNode = std::dynamic_pointer_cast(node)) { + Link::unlinkNodes(linkNode); + } + } +} bool Directory::attachNode(const Key &newKey, std::shared_ptr newNode) { assert(mMembers.find(newKey) == mMembers.end()); @@ -55,7 +63,7 @@ void Directory::dumpUtil(std::stringstream& ss, const Key& key, ui32 currentDept indent(ss, currentDepth, indents); ss << key; - ss << " [" << mIncomingHardLinks.size() << ":" << mIncomingDynamicLinks.size() << "]"; + ss << " [" << mIncomingHardLinks.size() << ":" << mIncomingDynamicLinks.size() << "] " << size(); ss << "\n"; currentDepth++; @@ -85,6 +93,15 @@ std::shared_ptr Directory::clone() const { for (auto& member : out->mMembers) { member.second->mParent = out; } + + for (auto& member : out->mMembers) { + std::shared_ptr& node = member.second; + if (auto linkNode = std::dynamic_pointer_cast(node)) { + auto targetNode = linkNode->getTarget(); + assert(Link::linkNodes(linkNode, targetNode, linkNode->isHard())); + } + } + return out; } diff --git a/src/FileSystem.cpp b/src/FileSystem.cpp index ba079e9..9b4004d 100644 --- a/src/FileSystem.cpp +++ b/src/FileSystem.cpp @@ -237,12 +237,16 @@ bool FileSystem::removeFileOrLink(const Path &path) { existingNode->clearFlags(parentNode); if (existingNode->isHard()) { - gError = "File or link is referenced by a hard links"; + gError = "File is referenced by a hard link"; return false; } + if (auto link = dynamic_pointer_cast(existingNode)) { + Link::unlinkNodes(link); + } + if (!parentNode->detachNode(path.getFilename())) { - gError = "Can not remove file or link because it has hard references"; + gError = "Can not remove file or link because it is referenced by a hard link"; return false; } @@ -325,7 +329,7 @@ bool FileSystem::moveNode(const Path &source, const Path &target) { sourceNode->clearFlags(parentNodeSource); if (sourceNode->isHard()) { - gError = "Node is referenced by a hard links"; + gError = "Node is referenced by a hard link"; return false; } diff --git a/src/Link.cpp b/src/Link.cpp index 857c059..2a2cc64 100644 --- a/src/Link.cpp +++ b/src/Link.cpp @@ -7,7 +7,10 @@ Link::Link() {} -Link::Link(const Link &node) : Node(node) {} +Link::Link(const Link &node) : Node(node) { + mLink = node.mLink; + mIsHard = node.mIsHard; +} std::shared_ptr Link::clone() const { return std::make_shared(*this); @@ -18,7 +21,7 @@ Link::~Link() = default; bool Link::linkNodes(const std::shared_ptr& link, const std::shared_ptr& target, bool hard) { if (target->getType() == LINK) return false; - assert(!link->mLink.lock()); + // assert(!link->mLink.lock()); link->mIsHard = hard; link->mLink = target; @@ -32,6 +35,21 @@ bool Link::linkNodes(const std::shared_ptr& link, const std::shared_ptr& link) { + auto target = link->mLink.lock(); + + // this is happening when + if (!target) return; + + auto& links = link->isHard() ? target->mIncomingHardLinks : target->mIncomingDynamicLinks; + + links.erase(std::remove_if(links.begin(), links.end(), [&](std::weak_ptr& node){ + auto targetLink = node.lock(); + assert(targetLink); + return targetLink == link; + }), links.end()); +} + std::shared_ptr Link::getLink() const { auto target = mLink.lock(); assert(target);