From 2d2d334f50c31f2c023a91ccfa518db51b2e73ae Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sat, 2 Jul 2016 20:40:44 -0500 Subject: [PATCH] Add ability to delete inodes --- src/ox/fs/filestore.hpp | 90 +++++++++++++++++++++++++++++++--- src/ox/fs/test/filestoreio.cpp | 20 +++++++- 2 files changed, 100 insertions(+), 10 deletions(-) diff --git a/src/ox/fs/filestore.hpp b/src/ox/fs/filestore.hpp index c8424b568..5f21aaa41 100644 --- a/src/ox/fs/filestore.hpp +++ b/src/ox/fs/filestore.hpp @@ -52,12 +52,6 @@ class FileStore { FsSize_t m_rootInode; public: - /** - * Initializes the memory chunk of this FileStore was given. - * This clears the previous contents. - */ - void init(); - /** * Writes the given data to a "file" with the given id. * @param id the id of the file @@ -74,6 +68,12 @@ class FileStore { */ int write(InodeId_t id, void *data, FsSize_t dataLen); + /** + * Removes the inode of the given ID. + * @param id the id of the file + */ + int remove(InodeId_t id); + /** * Reads the "file" at the given id. You are responsible for freeing * the data when done with it. @@ -106,6 +106,18 @@ class FileStore { */ Inode *getInode(Inode *root, InodeId_t id); + /** + * Removes the inode of the given ID. + * @param id the id of the file + */ + int remove(Inode *root, InodeId_t id); + + /** + * Removes the given node from the linked list. + * @param node node to remove + */ + void unlink(Inode *node); + /** * Gets an address for a new Inode. * @param size the size of the Inode @@ -191,7 +203,6 @@ template int FileStore::write(InodeId_t id, void *data, FsSize_t dataLen) { auto retval = 1; const FsSize_t size = sizeof(Inode) + dataLen; - //printf("%d\n", m_rootInode); auto inode = (Inode*) alloc(size); if (inode) { auto root = ptr(m_rootInode); @@ -204,6 +215,69 @@ int FileStore::write(InodeId_t id, void *data, FsSize_t dataLen) { return retval; } +template +int FileStore::remove(InodeId_t id) { + return remove(ptr(m_rootInode), id); +} + +template +int FileStore::remove(Inode *root, InodeId_t id) { + auto err = 1; + + if (root->m_id > id) { + if (root->left) { + auto node = ptr(root->left); + if (node->m_id != id) { + err = remove(node, id); + } else { + root->left = node->left; + if (node->right) { + insert(root, ptr(node->right)); + } + if (node->left) { + insert(root, ptr(node->left)); + } + unlink(node); + err = 0; + } + } + } else if (root->m_id < id) { + if (root->right) { + auto node = ptr(root->right); + if (node->m_id != id) { + err = remove(node, id); + } else { + root->right = node->right; + if (node->right) { + insert(root, ptr(node->right)); + } + if (node->left) { + insert(root, ptr(node->left)); + } + unlink(node); + err = 0; + } + } + } else { + m_rootInode = root->right; + if (root->left) { + insert(ptr(m_rootInode), ptr(root->left)); + } + unlink(root); + err = 0; + } + + return err; +} + +template +void FileStore::unlink(Inode *node) { + auto next = ptr(node->next); + auto prev = ptr(node->prev); + prev->next = ptr(next); + next->prev = ptr(prev); +} + template int FileStore::read(InodeId_t id, void *data, FsSize_t *size) { auto inode = getInode(ptr(m_rootInode), id); @@ -328,7 +402,7 @@ typename FileStore::Inode *FileStore::lastInode() { template uint8_t FileStore::version() { - return 0; + return 1; }; template diff --git a/src/ox/fs/test/filestoreio.cpp b/src/ox/fs/test/filestoreio.cpp index 43ed30793..ff1930f85 100644 --- a/src/ox/fs/test/filestoreio.cpp +++ b/src/ox/fs/test/filestoreio.cpp @@ -29,13 +29,29 @@ int test() { if (fs->write(2, (void*) "World", 6) || fs->read(2, (char*) out, &outSize) || strcmp("World", out)) { - return 1; + return 2; } // make sure first value was not overwritten if (fs->read(1, (char*) out, &outSize) || strcmp("Hello", out)) { - return 1; + return 3; + } + + if (fs->remove(1)) { + return 4; + } + + // make sure inode is not found + if (fs->read(1, (char*) out, &outSize) == 0) { + return 5; + } + + // make sure 2 is still available + if (fs->write(2, (void*) "World", 6) || + fs->read(2, (char*) out, &outSize) || + strcmp("World", out)) { + return 6; } return 0;