From 6d1c37db0acd7ba2aa2e22bc283eff60be3829e4 Mon Sep 17 00:00:00 2001 From: IlyaShurupov Date: Tue, 26 Mar 2024 19:36:05 +0300 Subject: [PATCH] tmp --- CMakeLists.txt | 4 ++ FileSystemEmulator.cpp | 2 - FileSystemEmulator.hpp | 155 +++++++++++++++++++---------------------- Path.hpp | 67 ++++++++++++++++++ Tests.cpp | 18 ++++- 5 files changed, 158 insertions(+), 88 deletions(-) create mode 100644 Path.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 1335f50..0564235 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,9 @@ +cmake_minimum_required(VERSION 3.5) + project(FileSystemEmulator) +set(CMAKE_CXX_STANDARD 20) + add_library(${PROJECT_NAME} STATIC FileSystemEmulator.cpp FileSystemEmulator.hpp) target_include_directories(${PROJECT_NAME} PUBLIC .) diff --git a/FileSystemEmulator.cpp b/FileSystemEmulator.cpp index dde3022..e69de29 100644 --- a/FileSystemEmulator.cpp +++ b/FileSystemEmulator.cpp @@ -1,2 +0,0 @@ - -static void f() {} \ No newline at end of file diff --git a/FileSystemEmulator.hpp b/FileSystemEmulator.hpp index b4ef800..750eeec 100644 --- a/FileSystemEmulator.hpp +++ b/FileSystemEmulator.hpp @@ -25,53 +25,72 @@ // base node class has all the cache data. use it directly in the tree // dynamic links ? -> yet another cache variable in each node? -#include -#include +#include "Path.hpp" + #include #include #include - +#include #include -typedef std::filesystem::path Path; typedef std::string Key; +typedef std::map Tree; -struct Node { - Key key; - - Node* left = nullptr; - Node* right = nullptr; - Node* parent = nullptr; - unsigned int height = 0; - - unsigned int inLinks = 0; - unsigned int outLinks = 0; - - enum Type : unsigned int { NONE, DIRECTORY, FILE, LINK } type = NONE; -}; - -struct File : Node { - File() { - type = FILE; +class Node { +public: + Node() { + type = NONE; } + + virtual void log(std::stringstream& ss, const Key& key, int depth) { + ss << "ss"; + } + + virtual ~Node() = default; + +protected: + enum Type : unsigned int { NONE, DIRECTORY, FILE, LINK }; + Type type; }; -struct Link : Node { - Node* link = nullptr; - bool hard = false; +class File : public Node { +public: + File() { + type = Type::FILE; + } + + void log(std::stringstream& ss, const Key& key, int depth) override { + ss << std::setw(depth * 2) << key << "\n"; + } + + ~File() override = default; +}; + +class Link : public Node { +public: Link() { type = LINK; } + + void log(std::stringstream & ss, const Key& key, int depth) override { + ss << std::setw(depth * 2) << "link [" << key << "] \n"; + } + + ~Link() override = default; + +private: + Node* link = nullptr; + bool hard = false; }; -struct Directory : Node { - Node subNodes; - +class Directory : public Node { +public: Directory() { type = DIRECTORY; } + ~Directory() override = default; void detachNode(Node* node) { // TODO : remove util from avl tree @@ -86,16 +105,16 @@ struct Directory : Node { return false; } - if (node->type != DIRECTORY) { + // if (node->type != DIRECTORY) { // TODO : update error status - given path is not a directory - return false; - } + // return false; + //} if (!((Directory*) node)->insertUtil(newKey, newNode)) return false; - if (newNode->type == LINK) { + // if (newNode->type == LINK) { // TODO : update all caches (due to the new link update) - } + // } return true; } @@ -116,7 +135,7 @@ struct Directory : Node { } const Key& key = {}; // path.getCurrentKey(); - node = findUtil(key, &subNodes); + node = subNodes.find(key)->second; if (!node) { return nullptr; @@ -124,6 +143,7 @@ struct Directory : Node { // TODO : dont allow cyclic links (with length one?)? while (true) { + /* switch (node->type) { case Node::DIRECTORY: return ((Directory*)node)->findNode(path); @@ -135,22 +155,19 @@ struct Directory : Node { default: return nullptr; } + */ } } - Node* findUtil(const Key& key, Node* node) { - Node* iter = node; - while (true) { - if (!iter) return nullptr; - if (iter->key == key) return iter; - if (key > iter->key) { - iter = iter->left; - } else { - iter = iter->right; - } + void log(std::stringstream & ss, const Key& key, int depth) override { + ss << std::setw(depth * 2) << key; + for (auto & node : subNodes) { + node.second->log(ss, node.first, depth + 1); } } +private: + Tree subNodes; }; class FileSystem { @@ -160,6 +177,7 @@ class FileSystem { public: FileSystem() { root = new Directory(); + initializeTransitions(); } ~FileSystem() { @@ -167,60 +185,27 @@ public: } void makeDirectory(const Path& path) { - Directory* parentDirectory = path.is_relative() ? currentDirectory : root; + Directory* parentDirectory = path.isAbsolute() ? root : currentDirectory; auto newDirectory = new Directory(); + /* if (!parentDirectory->attachNode(path.parent_path(), path.filename(), newDirectory)) { delete newDirectory; } + */ } - void changeCurrent(const char* directoryString) { - auto path = Path(directoryString); - auto node = path.is_relative() ? root->findNode(path) : currentDirectory->findNode(path); - if (node->type != Node::DIRECTORY) { + void changeCurrent(const Path& path) { + auto node = path.isAbsolute() ? root->findNode(path) : currentDirectory->findNode(path); + // if (node->type != Node::DIRECTORY) { // TODO : update error status - no such directory - return; - } + // return; + // } currentDirectory = (Directory*) node; } void log() { std::stringstream ss; - logNode(ss, root, 0); + root->log(ss, "/", 0); std::cout << ss.str(); } - -private: - void logUtil(std::stringstream& ss, const Node* node, int depth) { - if (!node) return; - logUtil(ss, node->left, depth); - logNode(ss, node, depth); - logUtil(ss, node->right, depth); - } - - void logNode(std::stringstream& ss, const Node* node, int depth) { - switch (node->type) { - case Node::DIRECTORY: - return logDirectory(ss, (Directory*) node, depth); - case Node::FILE: - return logFile(ss, (File*) node, depth); - case Node::LINK: - return logLink(ss, (Link*) node, depth); - default: - exit(1); - } - } - - void logDirectory(std::stringstream& ss, const Directory* dir, int depth) { - ss << std::setw(depth * 2) << dir->key; - logUtil(ss, &dir->subNodes, depth + 1); - } - - void logFile(std::stringstream& ss, const File* file, int depth) { - ss << std::setw(depth * 2) << file->key << "\n"; - } - - void logLink(std::stringstream& ss, const Link* link, int depth) { - ss << std::setw(depth * 2) << "link [" << link->key << "] \n"; - } }; \ No newline at end of file diff --git a/Path.hpp b/Path.hpp new file mode 100644 index 0000000..eaa797c --- /dev/null +++ b/Path.hpp @@ -0,0 +1,67 @@ +#pragma once + +#include +#include +#include + +std::vector transitions; + +void initializeTransitions() { + transitions.resize(256); + std::fill(transitions.begin(), transitions.end(), 1); + for (char i = 'a'; i <= 'z'; i++) transitions[i] = i; + for (char i = '0'; i <= '9'; i++) transitions[i] = i; + for (char i = 'A'; i <= 'Z'; i++) transitions[i] = i + ('a' - 'A'); + transitions['/'] = '/'; +} + +char getChar(char in) { + return transitions[in]; +} + +class Path { +public: + Path() = default; + + Path(const char* path) { + set(path); + } + + bool isValid() { + return mIsValid; + } + + bool isAbsolute() const { + return mAbsolute; + } + + int getDepth() const { + return mDepth; + } + + void set(const std::string& path) { + if (path.empty()) { + mIsValid = false; + return; + } + + mIsValid = true; + mPath = path; + + mDepth = std::count(path.begin(), path.end(), '/') + 1; + mDepth -= (mPath.back() == '/') + (path.front() == '/'); + + mAbsolute = path.front() == '/'; + + for (auto & character : mPath) { + character = getChar(character); + if (character == 1) mIsValid = false; + } + } + +private: + std::string mPath = ""; + int mDepth = 0; + bool mAbsolute = false; + bool mIsValid = false; +}; \ No newline at end of file diff --git a/Tests.cpp b/Tests.cpp index 59f61ee..b52b31a 100644 --- a/Tests.cpp +++ b/Tests.cpp @@ -1,9 +1,25 @@ + #include "FileSystemEmulator.hpp" +namespace fs = std::filesystem; + int main() { FileSystem fse; - fse.makeDirectory("/newDir"); + Path path; + + path.set("/"); + path.set("/dir"); + path.set("/dir/"); + path.set("dir/"); + + path.set(""); + path.set("asd"); + path.set("asdASD"); + path.set("asdASD123"); + path.set("asdASD123"); + + fse.makeDirectory("/dir"); fse.log(); return 0;