Verified Commit 4645fd16 authored by Tommaso Tocci's avatar Tommaso Tocci
Browse files

DB ops: get directory entries

exposes a new  DB function that allows to retrieve all the
first-level entries of a specific directory.
parent b1c7f2bf
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ class MetadataDB {
        bool exists(const std::string& key);
        void update(const std::string& old_key, const std::string& new_key, const std::string& val);
        void update_size(const std::string& key, size_t size, bool append);
        std::vector<std::pair<std::string, bool>> get_dirents(const std::string& dir) const;
        void iterate_all();
};

+1 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@ target_sources(metadata_db
    ${INCLUDE_DIR}/daemon/backend/metadata/db.hpp
    ${INCLUDE_DIR}/daemon/backend/exceptions.hpp
    PRIVATE
    ${INCLUDE_DIR}/global/path_util.hpp
    ${INCLUDE_DIR}/daemon/backend/metadata/merge.hpp
    ${CMAKE_CURRENT_LIST_DIR}/merge.cpp
    ${CMAKE_CURRENT_LIST_DIR}/db.cpp
+58 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@
#include <daemon/backend/metadata/merge.hpp>
#include <daemon/backend/exceptions.hpp>

#include <global/path_util.hpp>
#include <extern/spdlog/spdlog.h>

MetadataDB::MetadataDB(const std::string& path): path(path) {
@@ -44,6 +45,9 @@ std::string MetadataDB::get(const std::string& key) const {
}

void MetadataDB::put(const std::string& key, const std::string& val) {
    assert(is_absolute_path(key));
    assert(key == "/" || !has_trailing_slash(key));

    auto cop = CreateOperand(val);
    auto s = db->Merge(write_opts, key, cop.serialize());
    if(!s.ok()){
@@ -97,6 +101,60 @@ void MetadataDB::update_size(const std::string& key, size_t size, bool append){
    }
}

/**
 * Return all the first-level entries of the directory @dir
 *
 * @return vector of pair <std::string name, bool is_dir>,
 *         where name is the name of the entries and is_dir
 *         is true in the case the entry is a directory.
 */
std::vector<std::pair<std::string, bool>> MetadataDB::get_dirents(const std::string& dir) const {
    auto root_path = dir;
    assert(is_absolute_path(root_path));
    //add trailing slash if missing
    if(!has_trailing_slash(root_path) && root_path.size() != 1) {
        //add trailing slash only if missing and is not the root_folder "/"
        root_path.push_back('/');
    }

    rocksdb::ReadOptions ropts;
    auto it = db->NewIterator(ropts);

    std::vector<std::pair<std::string, bool>> entries;

    for(it->Seek(root_path);
            it->Valid() &&
            it->key().starts_with(root_path) &&
            it->key().size() != root_path.size();
        it->Next()){

        /***** Get File name *****/
        auto name = it->key().ToString();
        if(name.find_first_of('/', root_path.size()) != std::string::npos){
            //skip stuff deeper then one level depth
            continue;
        }
        // remove prefix
        name = name.substr(root_path.size());

        //relative path of directory entries must not be empty
        assert(name.size() > 0);

        /***** Get File type *****/
        /*TODO: move this routine along with general metadata {de,se}rialization
         * functions
         */
        auto metadata = it->value().ToString();
        assert(metadata.size() > 0);
        auto mode = static_cast<mode_t>(stoul(metadata.substr(0, metadata.find(','))));
        auto is_dir = S_ISDIR(mode);

        entries.push_back(std::make_pair(std::move(name), std::move(is_dir)));
    }
    assert(it->status().ok());
    return entries;
}

void MetadataDB::iterate_all() {
    std::string key;
    std::string val;