From 83abdea417ca2c6c96d26ada090dfa6797ca7daf Mon Sep 17 00:00:00 2001 From: IlyaShurupov Date: Thu, 28 Mar 2024 10:50:55 +0300 Subject: [PATCH] node to path --- inc/DirectoryTree.hpp | 56 +++++++++++++++++++++++-------------------- inc/FileSystem.hpp | 14 +++++++++++ inc/Tree.hpp | 8 +++++-- src/DirectoryTree.cpp | 10 ++++++-- src/FileSystem.cpp | 12 +++++++++- test/Tests.cpp | 11 +++++---- 6 files changed, 76 insertions(+), 35 deletions(-) diff --git a/inc/DirectoryTree.hpp b/inc/DirectoryTree.hpp index 624ca23..83aa933 100644 --- a/inc/DirectoryTree.hpp +++ b/inc/DirectoryTree.hpp @@ -9,6 +9,33 @@ extern std::string gError; typedef std::string Key; +struct DirectoryKey { + DirectoryKey() = default; + explicit DirectoryKey(Key val) : val(std::move(val)) {} + + [[nodiscard]] inline bool descentRight(const DirectoryKey& in) const { return in.val > val; } + [[nodiscard]] inline bool descentLeft(const DirectoryKey& in) const { return in.val < val; } + [[nodiscard]] inline bool exactNode(const DirectoryKey& in) const { return in.val == val; } + + [[nodiscard]] inline const DirectoryKey& getFindKey() const { return *this; } + static inline const DirectoryKey& keyInRightSubtree(const DirectoryKey& in) { return in; } + static inline const DirectoryKey& keyInLeftSubtree(const DirectoryKey& in) { return in; } + + template + inline void updateTreeCacheCallBack(NodeType& treeNode) { + treeNode.data->mTreeNode = &treeNode; + // TODO : update incoming links + } + +public: + Key val; + + ui32 incomingLinksHard = 0; + ui32 incomingLinksDynamic = 0; +}; + +typedef AvlTree DirectoryTree; + class Node { public: enum Type : ui32 { NONE, DIRECTORY, FILE, LINK } ; @@ -18,6 +45,8 @@ public: public: Type mType = NONE; + Node* mParent = nullptr; + DirectoryTree::Node* mTreeNode = nullptr; }; class File : public Node { @@ -35,33 +64,7 @@ private: bool mIsHard = false; }; -struct DirectoryKey { - DirectoryKey() = default; - explicit DirectoryKey(Key val) : val(std::move(val)) {} - - [[nodiscard]] inline bool descentRight(const DirectoryKey& in) const { return in.val > val; } - [[nodiscard]] inline bool descentLeft(const DirectoryKey& in) const { return in.val < val; } - [[nodiscard]] inline bool exactNode(const DirectoryKey& in) const { return in.val == val; } - - [[nodiscard]] inline const DirectoryKey& getFindKey() const { return *this; } - static inline const DirectoryKey& keyInRightSubtree(const DirectoryKey& in) { return in; } - static inline const DirectoryKey& keyInLeftSubtree(const DirectoryKey& in) { return in; } - - template - inline void updateTreeCacheCallBack(const NodeType&) { - // TODO : update incoming links - } - -public: - Key val; - - ui32 incomingLinksHard = 0; - ui32 incomingLinksDynamic = 0; -}; - class Directory : public Node { - typedef AvlTree DirectoryTree; - public: Directory(); ~Directory() override; @@ -79,6 +82,7 @@ public: mMembers.traverseInorder(mMembers.getRoot(), functor); } + void getNodePath(Node* node, std::vector& path) const; private: void updateTreeLinkCount(Node* node); void getMaxDepthUtil(ui32 depth, ui32& maxDepth) const; diff --git a/inc/FileSystem.hpp b/inc/FileSystem.hpp index 449349c..5f03702 100644 --- a/inc/FileSystem.hpp +++ b/inc/FileSystem.hpp @@ -5,6 +5,20 @@ #include +// Functionality: +// - add node to path conversion +// - check for current node deletion +// - print current node +// - print links and link counts +// - update link counts +// - add link creation commands + +// Refactor +// - Move DirectoryKey inside Node (no need to store pointers from Node to DirectoryTree::Node) +// - Merge DirectoryTree::Node and Node (no pointer overhead, requires tree nodes to be consistent, check insertNodeInstead) +// - introduce smart pointers +// - reconsider switch statements + class FileSystem { public: FileSystem(); diff --git a/inc/Tree.hpp b/inc/Tree.hpp index 6859b7c..f69ff15 100644 --- a/inc/Tree.hpp +++ b/inc/Tree.hpp @@ -211,12 +211,16 @@ private: } inline Node* newNode(KeyArg key, DataArg data) { - return new Node(key, data); + auto out = new Node(key, data); + out->updateTreeCacheCallBack(); + return out; } inline void injectNodeInstead(Node* target, Node* from) { - target->data = from->data; + std::swap(target->data, from->data); target->key = from->key; + target->updateTreeCacheCallBack(); + from->updateTreeCacheCallBack(); } inline i64 getNodeHeight(const Node* node) const { return node ? node->mHeight : -1; } diff --git a/src/DirectoryTree.cpp b/src/DirectoryTree.cpp index 12cd5d4..438f02c 100644 --- a/src/DirectoryTree.cpp +++ b/src/DirectoryTree.cpp @@ -47,6 +47,7 @@ bool Directory::attachNode(const std::vector& directoryPath, const Key& new directory->mMembers.insert(DirectoryKey(newKey), newNode); + newNode->mParent = directory; updateTreeLinkCount(directory); return true; } @@ -67,6 +68,7 @@ bool Directory::detachNode(const std::vector& directoryPath, const Key& key } directory->mMembers.remove(DirectoryKey(key)); + removeNode->mParent = nullptr; updateTreeLinkCount(directory); return true; @@ -129,9 +131,7 @@ ui32 Directory::getMaxDepth() const { void Directory::dump(std::stringstream& ss) { std::vector indents; indents.resize(getMaxDepth()); - dumpUtil(ss, 0, indents); - ss << "\n"; } @@ -164,4 +164,10 @@ void Directory::dumpUtil(std::stringstream& ss, ui32 currentDepth, std::vector& path) const { + if (!node || !node->mTreeNode) return; + path.push_back(&node->mTreeNode->key.val); + getNodePath(node->mParent, path); } \ No newline at end of file diff --git a/src/FileSystem.cpp b/src/FileSystem.cpp index 300e0b5..df42180 100644 --- a/src/FileSystem.cpp +++ b/src/FileSystem.cpp @@ -76,7 +76,17 @@ bool FileSystem::changeCurrent(const Path& path) { void FileSystem::log() const { std::stringstream ss; - ss << " *\n"; + + std::vector currentPath; + root->getNodePath(currentDirectory, currentPath); + std::reverse(currentPath.begin(), currentPath.end()); + + ss << "cd - /"; + for (auto key : currentPath) { + ss << *key << "/"; + } + + ss << "\n"; root->dump(ss); std::cout << ss.str(); } diff --git a/test/Tests.cpp b/test/Tests.cpp index 0345062..3eff872 100644 --- a/test/Tests.cpp +++ b/test/Tests.cpp @@ -12,10 +12,13 @@ int main() { interpreter.interpret("MD /A123"); interpreter.interpret("cd /A123"); interpreter.interpret("md asd"); - interpreter.interpret("md asd/asd"); - interpreter.interpret("md asd/asd/asd"); - interpreter.interpret("md asd/asd/asd/asd"); - interpreter.interpret("rd asd"); + interpreter.interpret("md asd/b"); + interpreter.interpret("md asd/b/c"); + interpreter.interpret("md asd/b/c/d"); + + interpreter.interpret("cd asd/b/c/d"); + + interpreter.interpret("rd d"); return UnitTest::RunAllTests(); } \ No newline at end of file