stable
This commit is contained in:
parent
492ab9d13d
commit
fae5a39053
3 changed files with 85 additions and 88 deletions
|
|
@ -9,6 +9,32 @@
|
|||
extern std::string gError;
|
||||
typedef std::string Key;
|
||||
|
||||
class Node {
|
||||
public:
|
||||
enum Type : ui32 { NONE, DIRECTORY, FILE, LINK } ;
|
||||
|
||||
public:
|
||||
virtual ~Node();
|
||||
|
||||
public:
|
||||
Type mType = NONE;
|
||||
};
|
||||
|
||||
class File : public Node {
|
||||
public:
|
||||
File();
|
||||
};
|
||||
|
||||
class Link : public Node {
|
||||
public:
|
||||
Link();
|
||||
[[nodiscard]] Node* getLink() const;
|
||||
|
||||
private:
|
||||
Node* mLink = nullptr;
|
||||
bool mIsHard = false;
|
||||
};
|
||||
|
||||
struct DirectoryKey {
|
||||
DirectoryKey() = default;
|
||||
explicit DirectoryKey(Key val) : val(std::move(val)) {}
|
||||
|
|
@ -33,40 +59,15 @@ public:
|
|||
ui32 incomingLinksDynamic = 0;
|
||||
};
|
||||
|
||||
class Node {
|
||||
public:
|
||||
enum Type : ui32 { NONE, DIRECTORY, FILE, LINK } ;
|
||||
|
||||
public:
|
||||
virtual void dump(const Node* node, const Key& key) const = 0;
|
||||
virtual ~Node();
|
||||
|
||||
public:
|
||||
Type mType = NONE;
|
||||
};
|
||||
|
||||
class File : public Node {
|
||||
public:
|
||||
File();
|
||||
};
|
||||
|
||||
class Link : public Node {
|
||||
public:
|
||||
Link();
|
||||
[[nodiscard]] Node* getLink() const;
|
||||
|
||||
private:
|
||||
Node* mLink = nullptr;
|
||||
bool mIsHard = false;
|
||||
};
|
||||
|
||||
class Directory : public Node {
|
||||
typedef AvlTree<DirectoryKey, Node*> DirectoryTree;
|
||||
typedef AvlTree<DirectoryKey, class Node*> DirectoryTree;
|
||||
|
||||
public:
|
||||
Directory();
|
||||
~Directory() override;
|
||||
|
||||
void dump(std::stringstream& ss);
|
||||
|
||||
bool attachNode(const std::vector<Key>& directoryPath, const Key& newKey, Node* newNode);
|
||||
Node* findNode(const std::vector<Key>& path, ui32 currentDepth = 0);
|
||||
void detachNode(Node* node);
|
||||
|
|
@ -81,6 +82,7 @@ public:
|
|||
private:
|
||||
void updateTreeLinkCount(Node* node);
|
||||
void getMaxDepthUtil(ui32 depth, ui32& maxDepth) const;
|
||||
void dumpUtil(std::stringstream& ss, ui32 currentDepth, std::vector<bool>& indents);
|
||||
|
||||
public:
|
||||
DirectoryTree mMembers;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
|
||||
#include "DirectoryTree.hpp"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
std::string gError;
|
||||
|
||||
Node::~Node() = default;
|
||||
|
|
@ -37,9 +39,9 @@ bool Directory::attachNode(const std::vector<Key>& directoryPath, const Key& new
|
|||
|
||||
auto directory = ((Directory*) node);
|
||||
|
||||
Node* existingNode = directory->mMembers.find(DirectoryKey(newKey))->data;
|
||||
if (existingNode) {
|
||||
if (existingNode->mType == newNode->mType) return false; // exit silently
|
||||
DirectoryTree::Node* iterNode = directory->mMembers.find(DirectoryKey(newKey));
|
||||
if (iterNode) {
|
||||
if (iterNode->data->mType == newNode->mType) return false; // exit silently
|
||||
gError = "Cant add node";
|
||||
return false;
|
||||
}
|
||||
|
|
@ -56,12 +58,14 @@ Node* Directory::findNode(const std::vector<Key>& path, ui32 currentDepth) {
|
|||
}
|
||||
|
||||
const Key& key = path[currentDepth];
|
||||
Node* node = mMembers.find(DirectoryKey(key))->data;
|
||||
DirectoryTree::Node* iterNode = mMembers.find(DirectoryKey(key));
|
||||
|
||||
if (!node) {
|
||||
if (!iterNode) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Node* node = iterNode->data;
|
||||
|
||||
// link on link is not allowed
|
||||
while (true) {
|
||||
switch (node->mType) {
|
||||
|
|
@ -95,7 +99,7 @@ void Directory::getMaxDepthUtil(ui32 depth, ui32& maxDepth) const {
|
|||
maxDepth = std::max(depth, maxDepth);
|
||||
mMembers.traverseInorder(mMembers.getRoot(), [&](const DirectoryTree::Node* node){
|
||||
if (node->data->mType == DIRECTORY) {
|
||||
((Directory*)node)->getMaxDepthUtil(++depth, maxDepth);
|
||||
((Directory*)node->data)->getMaxDepthUtil(++depth, maxDepth);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -104,4 +108,44 @@ ui32 Directory::getMaxDepth() const {
|
|||
ui32 maxDepth = 1;
|
||||
getMaxDepthUtil(1, maxDepth);
|
||||
return maxDepth;
|
||||
}
|
||||
|
||||
void Directory::dump(std::stringstream& ss) {
|
||||
std::vector<bool> indents;
|
||||
indents.resize(getMaxDepth());
|
||||
|
||||
dumpUtil(ss, 0, indents);
|
||||
|
||||
ss << "\n";
|
||||
}
|
||||
|
||||
static void indent(std::stringstream & ss, ui32 depth, std::vector<bool>& indents) {
|
||||
if (!depth) return;
|
||||
for (auto i = 0; i < depth - 1; i++) {
|
||||
ss << (indents[i] ? " |" : " ");
|
||||
}
|
||||
ss << " |_";
|
||||
}
|
||||
|
||||
void Directory::dumpUtil(std::stringstream& ss, ui32 currentDepth, std::vector<bool>& indents) {
|
||||
indents[currentDepth] = true;
|
||||
currentDepth++;
|
||||
|
||||
auto lastNode = mMembers.maxNode(mMembers.getRoot());
|
||||
traverseInorder([&](const DirectoryTree::Node* node){
|
||||
if (lastNode == node) indents[currentDepth - 1] = false;
|
||||
|
||||
indent(ss, currentDepth, indents);
|
||||
ss << node->key.val << "\n";
|
||||
|
||||
switch (node->data->mType) {
|
||||
case Node::DIRECTORY:
|
||||
((Directory*) node->data)->dumpUtil(ss, currentDepth, indents);
|
||||
return;
|
||||
|
||||
default:
|
||||
// do nothing for now
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -23,7 +23,7 @@ bool FileSystem::makeDirectory(const Path& path) {
|
|||
|
||||
auto existingNode = parentDirectory->findNode(path.getChain());
|
||||
if (existingNode) {
|
||||
if (existingNode->type == Node::DIRECTORY) return true;
|
||||
if (existingNode->mType == Node::DIRECTORY) return true;
|
||||
gError = "Cant create directory, such node exists";
|
||||
return false;
|
||||
}
|
||||
|
|
@ -45,7 +45,7 @@ bool FileSystem::changeCurrent(const Path& path) {
|
|||
}
|
||||
|
||||
auto node = path.isAbsolute() ? root->findNode(path.getChain(), 0) : currentDirectory->findNode(path.getChain(), 0);
|
||||
if (!node || node->type != Node::DIRECTORY) {
|
||||
if (!node || node->mType != Node::DIRECTORY) {
|
||||
gError = "No such directory";
|
||||
return false;
|
||||
}
|
||||
|
|
@ -56,58 +56,9 @@ bool FileSystem::changeCurrent(const Path& path) {
|
|||
|
||||
void FileSystem::log() const {
|
||||
std::stringstream ss;
|
||||
std::vector<bool> indents;
|
||||
indents.resize(root->getMaxDepth());
|
||||
logNode(ss, root, 0, indents);
|
||||
std::cout << ss.str() << "\n";
|
||||
}
|
||||
|
||||
|
||||
void FileSystem::logNode(std::stringstream& ss, const Node* node, const Key& key, int depth, std::vector<bool>& indents) const {
|
||||
indent(ss, depth, indents);
|
||||
ss << key << "\n";
|
||||
|
||||
switch (node->type) {
|
||||
case Node::DIRECTORY:
|
||||
return logDirectory(ss, (Directory*) node, depth, indents);
|
||||
case Node::FILE:
|
||||
return logFile(ss, (File*) node, depth, indents);
|
||||
case Node::LINK:
|
||||
return logLink(ss, (Link*) node, depth, indents);
|
||||
}
|
||||
}
|
||||
|
||||
void FileSystem::indent(std::stringstream & ss, int depth, std::vector<bool>& indents) const {
|
||||
if (!depth) return;
|
||||
for (auto i = 0; i < depth - 1; i++) {
|
||||
ss << (indents[i] ? " |" : " ");
|
||||
}
|
||||
ss << " |_";
|
||||
}
|
||||
|
||||
void FileSystem::logDirectory(std::stringstream & ss, const Directory* node, int depth, std::vector<bool>& indents) const {
|
||||
ss << (node == currentDirectory ? "* " : " ");
|
||||
indent(ss, depth, indents);
|
||||
// ss << node->key << "\n";
|
||||
indents[depth] = true;
|
||||
depth++;
|
||||
/*
|
||||
auto lastNode = node->maxNode();
|
||||
node->traverseInorder([&](const Node* iterNode){
|
||||
if (lastNode == iterNode) indents[depth - 1] = false;
|
||||
logNode(ss, iterNode, depth, indents);
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
void FileSystem::logFile(std::stringstream& ss, const File* node, int depth, std::vector<bool>& indents) const {
|
||||
indent(ss, depth, indents);
|
||||
// ss << node->key << "\n";
|
||||
}
|
||||
|
||||
void FileSystem::logLink(std::stringstream & ss, const Link* node, int depth, std::vector<bool>& indents) const {
|
||||
indent(ss, depth, indents);
|
||||
// ss << "link [" << node->key << "] \n";
|
||||
ss << " *\n";
|
||||
root->dump(ss);
|
||||
std::cout << ss.str();
|
||||
}
|
||||
|
||||
const std::string& FileSystem::getLastError() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue