node to path

This commit is contained in:
IlyaShurupov 2024-03-28 10:50:55 +03:00
parent 1e926dc3e4
commit 83abdea417
6 changed files with 76 additions and 35 deletions

View file

@ -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 <typename NodeType>
inline void updateTreeCacheCallBack(NodeType& treeNode) {
treeNode.data->mTreeNode = &treeNode;
// TODO : update incoming links
}
public:
Key val;
ui32 incomingLinksHard = 0;
ui32 incomingLinksDynamic = 0;
};
typedef AvlTree<DirectoryKey, class Node*> 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 <typename NodeType>
inline void updateTreeCacheCallBack(const NodeType&) {
// TODO : update incoming links
}
public:
Key val;
ui32 incomingLinksHard = 0;
ui32 incomingLinksDynamic = 0;
};
class Directory : public Node {
typedef AvlTree<DirectoryKey, class Node*> DirectoryTree;
public:
Directory();
~Directory() override;
@ -79,6 +82,7 @@ public:
mMembers.traverseInorder(mMembers.getRoot(), functor);
}
void getNodePath(Node* node, std::vector<const Key*>& path) const;
private:
void updateTreeLinkCount(Node* node);
void getMaxDepthUtil(ui32 depth, ui32& maxDepth) const;

View file

@ -5,6 +5,20 @@
#include <sstream>
// 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();

View file

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

View file

@ -47,6 +47,7 @@ bool Directory::attachNode(const std::vector<Key>& 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<Key>& 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<bool> indents;
indents.resize(getMaxDepth());
dumpUtil(ss, 0, indents);
ss << "\n";
}
@ -164,4 +164,10 @@ void Directory::dumpUtil(std::stringstream& ss, ui32 currentDepth, std::vector<b
return;
}
});
}
void Directory::getNodePath(Node* node, std::vector<const Key*>& path) const {
if (!node || !node->mTreeNode) return;
path.push_back(&node->mTreeNode->key.val);
getNodePath(node->mParent, path);
}

View file

@ -76,7 +76,17 @@ bool FileSystem::changeCurrent(const Path& path) {
void FileSystem::log() const {
std::stringstream ss;
ss << " *\n";
std::vector<const Key*> 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();
}

View file

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