stable feature complete

This commit is contained in:
IlyaShurupov 2024-03-30 09:12:07 +03:00
parent b5ddd765eb
commit 66d567fea8
5 changed files with 53 additions and 16 deletions

View file

@ -5,15 +5,12 @@
#include <sstream>
// 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:

View file

@ -20,6 +20,7 @@ public:
void dumpUtil(std::stringstream& ss, const Key& key, ui32 currentDepth, std::vector<bool>& indents) override;
static bool linkNodes(const std::shared_ptr<Link>& link, const std::shared_ptr<Node>& target, bool hard);
static void unlinkNodes(const std::shared_ptr<Link>& link);
private:
std::weak_ptr<Node> mLink;

View file

@ -1,12 +1,20 @@
#include "Directory.hpp"
#include "Link.hpp"
#include <sstream>
#include <algorithm>
Directory::Directory() = default;
Directory::~Directory() = default;
Directory::~Directory() {
for (auto& member : mMembers) {
std::shared_ptr<Node>& node = member.second;
if (auto linkNode = std::dynamic_pointer_cast<Link>(node)) {
Link::unlinkNodes(linkNode);
}
}
}
bool Directory::attachNode(const Key &newKey, std::shared_ptr<Node> 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<Node> Directory::clone() const {
for (auto& member : out->mMembers) {
member.second->mParent = out;
}
for (auto& member : out->mMembers) {
std::shared_ptr<Node>& node = member.second;
if (auto linkNode = std::dynamic_pointer_cast<Link>(node)) {
auto targetNode = linkNode->getTarget();
assert(Link::linkNodes(linkNode, targetNode, linkNode->isHard()));
}
}
return out;
}

View file

@ -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<Link>(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;
}

View file

@ -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<Node> Link::clone() const {
return std::make_shared<Link>(*this);
@ -18,7 +21,7 @@ Link::~Link() = default;
bool Link::linkNodes(const std::shared_ptr<Link>& link, const std::shared_ptr<Node>& 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>& link, const std::shared_ptr<No
return true;
}
void Link::unlinkNodes(const std::shared_ptr<Link>& 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<Link>& node){
auto targetLink = node.lock();
assert(targetLink);
return targetLink == link;
}), links.end());
}
std::shared_ptr<Node> Link::getLink() const {
auto target = mLink.lock();
assert(target);