stable feature complete
This commit is contained in:
parent
b5ddd765eb
commit
66d567fea8
5 changed files with 53 additions and 16 deletions
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
22
src/Link.cpp
22
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<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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue