DataSet.cpp 5.81 KB
Newer Older
1
#include "hepnos/DataSet.hpp"
2
#include "private/DataStoreImpl.hpp"
3 4 5

namespace hepnos {

6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
class DataSet::Impl {

    public:

        DataStore*   m_datastore;
        uint8_t      m_level;
        std::string  m_container;
        std::string  m_name;

        Impl(DataStore* ds, uint8_t level, const std::string& container, const std::string& name)
        : m_datastore(ds)
        , m_level(level)
        , m_container(container)
        , m_name(name) {}
};

22
DataSet::DataSet()
23
: m_impl(std::make_unique<DataSet::Impl>(nullptr, 0, "", "")) {}
24

25 26
DataSet::DataSet(DataStore* ds, uint8_t level, const std::string& fullname)
: m_impl(std::make_unique<DataSet::Impl>(ds, level, "", "")) {
27 28
    size_t p = fullname.find_last_of('/');
    if(p == std::string::npos) {
29
        m_impl->m_name = fullname;
30
    } else {
31 32
        m_impl->m_name = fullname.substr(p+1);
        m_impl->m_container = fullname.substr(0, p);
33 34 35
    }
}

36 37
DataSet::DataSet(DataStore* ds, uint8_t level, const std::string& container, const std::string& name) 
: m_impl(std::make_unique<DataSet::Impl>(ds, level, container, name)) {}
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52

DataSet::DataSet(const DataSet& other)
: m_impl(std::make_unique<DataSet::Impl>(*other.m_impl)) {}

DataSet::DataSet(DataSet&&) = default;

DataSet& DataSet::operator=(const DataSet& other) {
    if(this == &other) return *this;
    m_impl = std::make_unique<DataSet::Impl>(*other.m_impl);
    return *this;
}

DataSet& DataSet::operator=(DataSet&&) = default;

DataSet::~DataSet() {}
53

54 55 56 57
DataSet DataSet::next() const {
    if(!valid()) return DataSet();
   
    std::vector<std::string> keys; 
58
    size_t s = m_impl->m_datastore->m_impl->nextKeys(
59
            m_impl->m_level, m_impl->m_container, m_impl->m_name, keys, 1);
60
    if(s == 0) return DataSet();
61
    return DataSet(m_impl->m_datastore, m_impl->m_level, m_impl->m_container, keys[0]);
62 63 64
}

bool DataSet::valid() const {
65
    return m_impl && m_impl->m_datastore; 
66 67 68

}

69
bool DataSet::storeRawData(const std::string& key, const std::vector<char>& buffer) {
70 71 72 73
    if(!valid()) {
        throw Exception("Calling store() on invalid DataSet");
    }
    // forward the call to the datastore's store function
74
    return m_impl->m_datastore->m_impl->store(0, fullname(), key, buffer);
75 76
}

77
bool DataSet::loadRawData(const std::string& key, std::vector<char>& buffer) const {
78 79 80 81
    if(!valid()) {
        throw Exception("Calling load() on invalid DataSet");
    }
    // forward the call to the datastore's load function
82
    return m_impl->m_datastore->m_impl->load(0, fullname(), key, buffer);
83 84 85
}

bool DataSet::operator==(const DataSet& other) const {
86 87 88 89
    return m_impl->m_datastore == other.m_impl->m_datastore
        && m_impl->m_level     == other.m_impl->m_level
        && m_impl->m_container == other.m_impl->m_container
        && m_impl->m_name      == other.m_impl->m_name;
90 91
}

92 93 94 95
bool DataSet::operator!=(const DataSet& other) const {
    return !(*this == other);
}

96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
const std::string& DataSet::name() const {
    return m_impl->m_name;
}

const std::string& DataSet::container() const {
    return m_impl->m_container;
}

std::string DataSet::fullname() const {
    std::stringstream ss;
    if(container().size() != 0)
        ss << container() << "/";
    ss << name();
    return ss.str();
}

112 113 114 115
DataSet DataSet::createDataSet(const std::string& name) {
    if(name.find('/') != std::string::npos) {
        throw Exception("Invalid character '/' in dataset name");
    }
116
    std::string parent = fullname();
117
    m_impl->m_datastore->m_impl->store(m_impl->m_level+1, parent, name, std::vector<char>());
118
    return DataSet(m_impl->m_datastore, m_impl->m_level+1, parent, name);
119
}
120

121 122 123 124 125 126 127 128 129 130 131
DataSet DataSet::operator[](const std::string& datasetName) const {
    auto it = find(datasetName);
    return std::move(*it);
}

DataSet::iterator DataSet::find(const std::string& datasetName) {
    int ret;
    if(datasetName.find('/') != std::string::npos) {
        throw Exception("Invalid character '/' in dataset name");
    }
    std::vector<char> data;
132
    std::string parent = fullname();
133
    bool b = m_impl->m_datastore->m_impl->load(m_impl->m_level+1, parent, datasetName, data);
134 135 136
    if(!b) {
        return m_impl->m_datastore->end();
    }
137
    return iterator(DataSet(m_impl->m_datastore, m_impl->m_level+1, parent, datasetName));
138 139 140 141 142 143 144 145
}

DataSet::const_iterator DataSet::find(const std::string& datasetName) const {
    iterator it = const_cast<DataSet*>(this)->find(datasetName);
    return it;
}

DataSet::iterator DataSet::begin() {
146
    DataSet ds(m_impl->m_datastore, m_impl->m_level+1, fullname(),"");
147
    ds = ds.next();
148
    if(ds.valid()) return iterator(ds);
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
    else return end();
}

DataSet::iterator DataSet::end() {
    return m_impl->m_datastore->end();
}

DataSet::const_iterator DataSet::cbegin() const {
    return const_iterator(const_cast<DataSet*>(this)->begin());
}

DataSet::const_iterator DataSet::cend() const {
    return m_impl->m_datastore->cend();
}

DataSet::iterator DataSet::lower_bound(const std::string& lb) {
    std::string lb2 = lb;
    size_t s = lb2.size();
    lb2[s-1] -= 1; // sdskv_list_keys's start_key is exclusive
    iterator it = find(lb2);
    if(it != end()) {
        // we found something before the specified lower bound
        ++it;
        return it;
    }
174
    DataSet ds(m_impl->m_datastore, m_impl->m_level+1, fullname(), lb2);
175 176
    ds = ds.next();
    if(!ds.valid()) return end();
177
    else return iterator(ds);
178 179 180 181 182 183 184 185
}

DataSet::const_iterator DataSet::lower_bound(const std::string& lb) const {
    iterator it = const_cast<DataSet*>(this)->lower_bound(lb);
    return it;
}

DataSet::iterator DataSet::upper_bound(const std::string& ub) {
186
    DataSet ds(m_impl->m_datastore, m_impl->m_level+1, fullname(), ub);
187 188
    ds = ds.next();
    if(!ds.valid()) return end();
189
    else return iterator(ds);
190 191 192 193 194 195 196
}

DataSet::const_iterator DataSet::upper_bound(const std::string& ub) const {
    iterator it = const_cast<DataSet*>(this)->upper_bound(ub);
    return it;
}

197
}