DataStore.cpp 8.1 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
#include <vector>
#include <functional>
#include <iostream>
#include <yaml-cpp/yaml.h>
#include <sdskv-client.h>
#include <bake-client.h>
#include <ch-placement.h>
#include "hepnos/Exception.hpp"
#include "hepnos/DataStore.hpp"
#include "hepnos/DataSet.hpp"
11
#include "private/DataStoreImpl.hpp"
12
13
14

namespace hepnos {

15
16
17
18
////////////////////////////////////////////////////////////////////////////////////////////
// DataStore implementation
////////////////////////////////////////////////////////////////////////////////////////////

19
DataStore::DataStore(const std::string& configFile) 
20
: m_impl(std::make_unique<DataStore::Impl>(this)) {
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
    m_impl->init(configFile);
}

DataStore::DataStore(DataStore&& other)
: m_impl(std::move(other.m_impl)) {}

DataStore& DataStore::operator=(DataStore&& other) {
    if(&other == this) return *this;
    if(m_impl) {
        m_impl->cleanup();
    }
    m_impl = std::move(other.m_impl);
}
    
DataStore::~DataStore() {
    if(m_impl) {
        m_impl->cleanup();
    }
}

DataStore::iterator DataStore::find(const std::string& datasetName) {
42
    int ret;
43
44
45
    if(datasetName.find('/') != std::string::npos
    || datasetName.find('%') != std::string::npos) {
        throw Exception("Invalid character ('/' or '%') in dataset name");
46
    }
47
    std::vector<char> data;
48
    bool b = m_impl->load(1, "", datasetName, data);
49
50
    if(!b) {
        return m_impl->m_end;
51
    }
52
    return iterator(DataSet(this, 1, datasetName));
53
54
}

Matthieu Dorier's avatar
Matthieu Dorier committed
55
56
57
58
59
DataSet DataStore::operator[](const std::string& datasetName) const {
    auto it = find(datasetName);
    return std::move(*it);
}

60
DataStore::const_iterator DataStore::find(const std::string& datasetName) const {
61
62
    DataStore::iterator it = const_cast<DataStore*>(this)->find(datasetName);
    return it;
63
64
65
}

DataStore::iterator DataStore::begin() {
66
    DataSet ds(this, 1, "", "");
67
    ds = ds.next();
68
    if(ds.valid()) return iterator(std::move(ds));
69
    else return end();
70
71
}

72
73
74
75
76
DataStore::const_iterator DataStore::begin() const {
    iterator it = const_cast<DataStore*>(this)->begin();
    return const_iterator(std::move(it));
}

77
78
79
80
DataStore::iterator DataStore::end() {
    return m_impl->m_end;
}

81
82
83
84
DataStore::const_iterator DataStore::end() const {
    return m_impl->m_end;
}

85
DataStore::const_iterator DataStore::cbegin() const {
86
    return const_cast<DataStore*>(this)->begin();
87
88
89
}

DataStore::const_iterator DataStore::cend() const {
90
    return const_cast<DataStore*>(this)->end();
91
92
93
}

DataStore::iterator DataStore::lower_bound(const std::string& lb) {
94
95
96
97
98
99
100
101
102
    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;
    }
103
    DataSet ds(this, 1, "", lb2);
104
105
    ds = ds.next();
    if(!ds.valid()) return end();
106
    else return iterator(std::move(ds));
107
108
109
}

DataStore::const_iterator DataStore::lower_bound(const std::string& lb) const {
110
111
    iterator it = const_cast<DataStore*>(this)->lower_bound(lb);
    return it;
112
113
114
}

DataStore::iterator DataStore::upper_bound(const std::string& ub) {
115
    DataSet ds(this, 1, "", ub);
116
117
    ds = ds.next();
    if(!ds.valid()) return end();
118
    else return iterator(std::move(ds));
119
120
121
}

DataStore::const_iterator DataStore::upper_bound(const std::string& ub) const {
122
123
    iterator it = const_cast<DataStore*>(this)->upper_bound(ub);
    return it;
124
125
126
}

DataSet DataStore::createDataSet(const std::string& name) {
127
128
129
    if(name.find('/') != std::string::npos
    || name.find('%') != std::string::npos) {
        throw Exception("Invalid character ('/' or '%') in dataset name");
130
    }
131
    m_impl->store(1, "", name, std::vector<char>());
132
    return DataSet(this, 1, "", name);
133
134
135
136
137
138
}

////////////////////////////////////////////////////////////////////////////////////////////
// DataStore::const_iterator::Impl implementation
////////////////////////////////////////////////////////////////////////////////////////////

139
140
141
142
class DataStore::const_iterator::Impl {
    public:
        DataSet    m_current_dataset;

143
144
        Impl()
        : m_current_dataset()
145
        {}
146

147
148
149
150
151
152
        Impl(const DataSet& dataset)
        : m_current_dataset(dataset)
        {}

        Impl(DataSet&& dataset)
        : m_current_dataset(std::move(dataset))
153
        {}
154
155

        Impl(const Impl& other)
156
        : m_current_dataset(other.m_current_dataset) 
157
158
159
        {}

        bool operator==(const Impl& other) const {
160
            return m_current_dataset == other.m_current_dataset;
161
        }
162
163
};

164
165
166
////////////////////////////////////////////////////////////////////////////////////////////
// DataStore::const_iterator::Impl implementation
////////////////////////////////////////////////////////////////////////////////////////////
167

168
169
DataStore::const_iterator::const_iterator()
: m_impl(std::make_unique<Impl>()) {}
170

171
172
173
174
175
DataStore::const_iterator::const_iterator(const DataSet& dataset)
: m_impl(std::make_unique<Impl>(dataset)) {}

DataStore::const_iterator::const_iterator(DataSet&& dataset)
: m_impl(std::make_unique<Impl>(std::move(dataset))) {}
176

177
DataStore::const_iterator::~const_iterator() {}
178
179

DataStore::const_iterator::const_iterator(const DataStore::const_iterator& other) 
180
: m_impl(std::make_unique<Impl>(*other.m_impl)) {}
181
182

DataStore::const_iterator::const_iterator(DataStore::const_iterator&& other) 
183
: m_impl(std::move(other.m_impl)) {}
184

185
186
187
188
DataStore::const_iterator& DataStore::const_iterator::operator=(const DataStore::const_iterator& other) {
    if(&other == this) return *this;
    m_impl = std::make_unique<Impl>(*other.m_impl);
    return *this;
189
190
}

191
192
193
194
DataStore::const_iterator& DataStore::const_iterator::operator=(DataStore::const_iterator&& other) {
    if(&other == this) return *this;
    m_impl = std::move(other.m_impl);
    return *this;
195
196
197
}

DataStore::const_iterator::self_type DataStore::const_iterator::operator++() {
198
199
200
201
202
    if(!m_impl) {
        throw Exception("Trying to increment an invalid iterator");
    }
    m_impl->m_current_dataset = m_impl->m_current_dataset.next();
    return *this;
203
204
205
}

DataStore::const_iterator::self_type DataStore::const_iterator::operator++(int) {
206
207
208
    const_iterator copy = *this;
    ++(*this);
    return copy;
209
210
211
}

const DataStore::const_iterator::reference DataStore::const_iterator::operator*() {
212
213
214
215
    if(!m_impl) {
        throw Exception("Trying to dereference an invalid iterator");
    }
    return m_impl->m_current_dataset;
216
217
218
}

const DataStore::const_iterator::pointer DataStore::const_iterator::operator->() {
219
220
    if(!m_impl) return nullptr;
    return &(m_impl->m_current_dataset);
221
222
223
}

bool DataStore::const_iterator::operator==(const self_type& rhs) const {
224
225
226
227
    if(!m_impl && !rhs.m_impl)  return true;
    if(m_impl  && !rhs.m_impl)  return false;
    if(!m_impl && rhs.m_impl)   return false;
    return *m_impl == *(rhs.m_impl);
228
229
230
}

bool DataStore::const_iterator::operator!=(const self_type& rhs) const {
231
    return !(*this == rhs);
232
233
}

234
235
236
237
////////////////////////////////////////////////////////////////////////////////////////////
// DataStore::iterator implementation
////////////////////////////////////////////////////////////////////////////////////////////

238
239
240
241
242
DataStore::iterator::iterator(const DataSet& current)
: const_iterator(current) {}

DataStore::iterator::iterator(DataSet&& current)
: const_iterator(std::move(current)) {}
243

244
245
DataStore::iterator::iterator()
: const_iterator() {}
246

247
DataStore::iterator::~iterator() {}
248
249

DataStore::iterator::iterator(const DataStore::iterator& other)
250
: const_iterator(other) {}
251
252

DataStore::iterator::iterator(DataStore::iterator&& other) 
253
: const_iterator(std::move(other)) {}
254
255

DataStore::iterator& DataStore::iterator::operator=(const DataStore::iterator& other) {
256
257
258
    if(this == &other) return *this;
    m_impl = std::make_unique<Impl>(*other.m_impl);
    return *this;
259
260
261
}

DataStore::iterator& DataStore::iterator::operator=(DataStore::iterator&& other) {
262
263
264
    if(this == &other) return *this;
    m_impl = std::move(other.m_impl);
    return *this;
265
266
267
}

DataStore::iterator::reference DataStore::iterator::operator*() {
268
    return const_cast<reference>(const_iterator::operator*());
269
270
271
}

DataStore::iterator::pointer DataStore::iterator::operator->() {
272
    return const_cast<pointer>(const_iterator::operator->());
273
274
275
276
}

}