tmp unstable

This commit is contained in:
IlyaShurupov 2024-03-29 22:45:31 +03:00
parent abca7aeb76
commit b5ddd765eb
8 changed files with 101 additions and 47 deletions

View file

@ -17,7 +17,20 @@ public:
std::shared_ptr<Node> findNode(const std::vector<Key>& path, ui32 currentDepth = 0) override;
std::shared_ptr<Node> findNode(const Key& path) override;
[[nodiscard]] ui64 size() const override;
bool isDirectory() const override { return true; }
void clearFlags(std::shared_ptr<Node>& directory) override;
bool isHard() const override;
void removeIncomingDynamicLinks() override;
template <typename tFunctor>
static void traverse(std::shared_ptr<Node>& node, tFunctor functor) {
functor(node);
if (std::shared_ptr<Directory> directory = std::dynamic_pointer_cast<Directory>(node)) {
for (auto& member : directory->mMembers) {
traverse(member.second, functor);
}
}
}
private:
void getMaxDepthUtil(ui32 depth, ui32& maxDepth) const;

View file

@ -18,11 +18,8 @@ public:
// link on link is not allowed, so no inf looping here
std::shared_ptr<Node> findNode(const std::vector<Key>& path, ui32 currentDepth) override;
void dumpUtil(std::stringstream& ss, const Key& key, ui32 currentDepth, std::vector<bool>& indents) override;
bool isLink() const override { return true; }
static bool linkNodes(const std::shared_ptr<Link>& link, const std::shared_ptr<Node>& target, bool hard);
static bool unlinkWithIncomingLinks(std::shared_ptr<Node>& target);
static bool removeOutgoingLinks(const std::shared_ptr<Link>& link);
private:
std::weak_ptr<Node> mLink;

View file

@ -13,6 +13,7 @@ typedef long i32;
#include <memory>
class Link;
class Directory;
typedef std::string Key;
@ -35,9 +36,10 @@ public:
virtual std::shared_ptr<Node> getTarget();
virtual std::shared_ptr<Node> findNode(const std::vector<Key>& path, ui32 currentDepth = 0);
virtual std::shared_ptr<Node> findNode(const Key& path) { return nullptr; }
virtual bool isDirectory() const { return false; }
virtual bool isLink() const { return false; }
virtual bool isHard() const { return false; }
virtual void clearFlags(std::shared_ptr<Node>& directory) {}
virtual bool isHard() const;
virtual void removeIncomingDynamicLinks();
ui32 getMaxDepth() const;
void dump(std::stringstream& ss);
@ -46,8 +48,9 @@ public:
static void indent(std::stringstream & ss, ui32 depth, std::vector<bool>& indents);
public:
Key mKey;
std::weak_ptr<Node> mWorkingNodeFlag;
std::weak_ptr<Node> mParent;
std::vector<std::weak_ptr<Link>> mIncomingHardLinks;
std::vector<std::weak_ptr<Link>> mIncomingDynamicLinks;
};

View file

@ -11,17 +11,12 @@ Directory::~Directory() = default;
bool Directory::attachNode(const Key &newKey, std::shared_ptr<Node> newNode) {
assert(mMembers.find(newKey) == mMembers.end());
mMembers.insert({ newKey, newNode });
newNode->mKey = newKey;
return true;
}
bool Directory::detachNode(const Key& key) {
assert(mMembers.find(key) != mMembers.end());
//if (removeNode->key.incomingLinksHard || removeNode->key.incomingLinksDynamic) {
// gError = "Cannot modify node with incoming hard links";
// return false;
//}
mMembers.erase(key);
return true;
}
@ -92,3 +87,20 @@ std::shared_ptr<Node> Directory::clone() const {
}
return out;
}
void Directory::clearFlags(std::shared_ptr<Node> &directory) {
traverse(directory, [&](std::shared_ptr<Node>& node) {
node->mWorkingNodeFlag = directory;
});
}
bool Directory::isHard() const {
return std::any_of(mMembers.begin(), mMembers.end(), [](const auto& member) { return member.second->isHard(); });
}
void Directory::removeIncomingDynamicLinks() {
Node::removeIncomingDynamicLinks();
for (auto& member : mMembers) {
member.second->removeIncomingDynamicLinks();
}
}

View file

@ -45,7 +45,7 @@ bool FileSystem::changeCurrent(const Path& path) {
return false;
}
if (!parentNode->isDirectory()) {
if (parentNode->getType() != Node::DIRECTORY) {
gError = "Path is not a directory";
return false;
}
@ -136,7 +136,7 @@ bool FileSystem::makeLink(const Path& source, const Path& target, bool isDynamic
return false;
}
if (sourceNode->isLink()) {
if (sourceNode->getType() == Node::LINK) {
gError = "Link on link is not allowed";
return false;
}
@ -179,7 +179,7 @@ bool FileSystem::removeDirectory(const Path& path, bool recursively) {
return false;
}
if (!existingNode->isDirectory()) {
if (existingNode->getType() != Node::DIRECTORY) {
gError = "Path is not a directory";
return false;
}
@ -194,6 +194,15 @@ bool FileSystem::removeDirectory(const Path& path, bool recursively) {
return false;
}
existingNode->clearFlags(parentNode);
if (existingNode->isHard()) {
gError = "Directory is referenced by a hard links";
return false;
}
// deletes dynamic incoming links to this file system sub-ree
existingNode->removeIncomingDynamicLinks();
if (!parentNode->detachNode(path.getFilename())) {
gError = "Can not remove directory because it has hard references";
return false;
@ -221,11 +230,17 @@ bool FileSystem::removeFileOrLink(const Path &path) {
return false;
}
if (existingNode->isDirectory()) {
if (existingNode->getType() == Node::DIRECTORY) {
gError = "Path is not a file or a link";
return false;
}
existingNode->clearFlags(parentNode);
if (existingNode->isHard()) {
gError = "File or link is referenced by a hard links";
return false;
}
if (!parentNode->detachNode(path.getFilename())) {
gError = "Can not remove file or link because it has hard references";
return false;
@ -256,9 +271,9 @@ bool FileSystem::copyNode(const Path& source, const Path& target) {
if (!sourceNode) {
gError = "Invalid source path";
return false;
}
};
if (!parentNodeTarget->isDirectory()) {
if (parentNodeTarget->getType() != Node::DIRECTORY) {
gError = "Target path is not a directory";
return false;
}
@ -308,8 +323,9 @@ bool FileSystem::moveNode(const Path &source, const Path &target) {
return false;
}
sourceNode->clearFlags(parentNodeSource);
if (sourceNode->isHard()) {
gError = "Node contains incoming hard links";
gError = "Node is referenced by a hard links";
return false;
}
@ -327,9 +343,9 @@ void FileSystem::log() const {
root->getNodeStraightPath(currentDirectory, currentPath);
std::reverse(currentPath.begin(), currentPath.end());
ss << "cd - /";
for (auto key : currentPath) {
ss << "X" << "/";
ss << "cd - ";
for (const auto& node : currentPath) {
ss << node->mKey << "/";
}
ss << "\n";

View file

@ -32,26 +32,6 @@ bool Link::linkNodes(const std::shared_ptr<Link>& link, const std::shared_ptr<No
return true;
}
bool Link::unlinkWithIncomingLinks(std::shared_ptr<Node>& target) {
assert(target->mIncomingHardLinks.empty());
auto& links = target->mIncomingDynamicLinks;
auto shouldRemove = [](const std::weak_ptr<Link>& link) {
// Modify the condition as needed
return link.expired(); // Remove expired weak pointers
};
links.erase(std::remove_if(links.begin(), links.end(), shouldRemove), links.end());
}
bool Link::removeOutgoingLinks(const std::shared_ptr<Link>& link) {
// assert(mLink);
// auto& links = mIsHard ? mLink->mIncomingHardLinks : mLink->mIncomingDynamicLinks;
// links.erase(std::remove(links.begin(), links.end(), this), links.end());
// Directory::updateTreeLinkCount(mLink);
// mLink = nullptr;
}
std::shared_ptr<Node> Link::getLink() const {
auto target = mLink.lock();
assert(target);
@ -73,12 +53,12 @@ std::shared_ptr<Node> Link::findNode(const std::vector<Key>& path, ui32 currentD
void Link::dumpUtil(std::stringstream& ss, const Key& key, ui32 currentDepth, std::vector<bool>& indents) {
indent(ss, currentDepth, indents);
ss << key << (isHard() ? " hlink[/" : " dlink[/");
ss << key << (isHard() ? " hlink[" : " dlink[");
std::vector<std::shared_ptr<Node>> path;
getNodeStraightPath(getLink(), path);
std::reverse(path.begin(), path.end());
for (auto tmp : path)
ss << "X" << "/";
for (auto& node : path)
ss << node->mKey << "/";
ss << "]\n";
}

View file

@ -1,5 +1,6 @@
#include "Node.hpp"
#include "Link.hpp"
#include <memory>
#include <sstream>
@ -31,6 +32,37 @@ std::shared_ptr<Node> Node::findNode(const std::vector<Key>& path, ui32 currentD
return nullptr;
}
bool Node::isHard() const {
return std::any_of(mIncomingHardLinks.begin(), mIncomingHardLinks.end(), [this](const std::weak_ptr<Link>& hardLink) {
auto linkNode = hardLink.lock();
assert(linkNode);
auto linkTarget = linkNode->getLink()->mWorkingNodeFlag.lock();
assert(linkTarget);
auto ownLink = mWorkingNodeFlag.lock();
// if hard link in the same working tree it does not count
return ownLink != linkTarget;
});
}
void Node::removeIncomingDynamicLinks() {
for (auto& dynamicLink : mIncomingDynamicLinks) {
auto linkNode = dynamicLink.lock();
assert(linkNode);
auto linkTarget = linkNode->getLink()->mWorkingNodeFlag.lock();
assert(linkTarget);
auto ownLink = mWorkingNodeFlag.lock();
if (ownLink == linkTarget) {
continue;
}
auto parentNode = linkNode->mParent.lock();
assert(parentNode);
parentNode->detachNode(linkNode->mKey);
}
}
std::shared_ptr<Node> Node::getTarget() {
return nullptr;
}

View file

@ -31,6 +31,7 @@ int main() {
interpreter.interpret("md a/b/c");
interpreter.interpret("mhl a /a/b/c/");
interpreter.interpret("md a/b/c/a/k");
interpreter.interpret("copy a /");
interpreter.interpret("mdl a/b/c /a_copy/k");