DataSet.cpp 9.83 KB
Newer Older
Matthieu Dorier's avatar
Matthieu Dorier committed
1
2
3
4
5
/*
 * (C) 2018 The University of Chicago
 * 
 * See COPYRIGHT in top-level directory.
 */
6
#include "hepnos/DataSet.hpp"
7
8
#include "hepnos/Run.hpp"
#include "hepnos/RunSet.hpp"
9
10
11
12
#include "RunImpl.hpp"
#include "DataSetImpl.hpp"
#include "DataStoreImpl.hpp"
#include "WriteBatchImpl.hpp"
13
14
15

namespace hepnos {

16
DataSet::DataSet()
17
: m_impl(std::make_shared<DataSetImpl>(nullptr, 0, std::make_shared<std::string>(""), "")) {}
18

19
DataSet::DataSet(const std::shared_ptr<DataSetImpl>& impl)
20
: m_impl(impl) {}
21

22
DataSet::DataSet(std::shared_ptr<DataSetImpl>&& impl)
23
: m_impl(std::move(impl)) {}
24

25
DataStore DataSet::datastore() const {
26
27
28
    if(!valid()) {
        throw Exception("Calling DataSet member function on an invalid DataSet");
    }
29
    return DataStore(m_impl->m_datastore);
30
31
}

32
33
DataSet DataSet::next() const {
    if(!valid()) return DataSet();
34
35
    std::vector<std::shared_ptr<DataSetImpl>> result;
    size_t s = m_impl->m_datastore->nextDataSets(m_impl, result, 1);
36
    if(s == 0) return DataSet();
37
    else return DataSet(std::move(result[0]));
38
39
40
}

bool DataSet::valid() const {
41
    return m_impl && m_impl->m_datastore; 
42
43
}

44
ProductID DataSet::storeRawData(const std::string& key, const char* value, size_t vsize) {
45
    if(!valid()) {
46
        throw Exception("Calling DataSet member function on an invalid DataSet");
47
48
    }
    // forward the call to the datastore's store function
49
    return m_impl->m_datastore->store(0, fullname(), key, value, vsize);
50
51
}

52
ProductID DataSet::storeRawData(WriteBatch& batch, const std::string& key, const char* value, size_t vsize) {
53
54
55
56
    if(!valid()) {
        throw Exception("Calling DataSet member function on an invalid DataSet");
    }
    // forward the call to the datastore's store function
57
    return batch.m_impl->store(0, fullname(), key, value, vsize);
58
59
}

60
bool DataSet::loadRawData(const std::string& key, std::string& buffer) const {
61
62
63
    if(!valid()) {
        throw Exception("Calling DataSet member function on an invalid DataSet");
    }
64
    // forward the call to the datastore's load function
65
    return m_impl->m_datastore->load(0, fullname(), key, buffer);
66
67
}

68
bool DataSet::loadRawData(const std::string& key, char* value, size_t* vsize) const {
69
    if(!valid()) {
70
        throw Exception("Calling DataSet member function on an invalid DataSet");
71
72
    }
    // forward the call to the datastore's load function
73
    return m_impl->m_datastore->load(0, fullname(), key, value, vsize);
74
75
76
}

bool DataSet::operator==(const DataSet& other) const {
77
78
79
80
    bool v1 = valid();
    bool v2 = other.valid();
    if(!v1 && !v2) return true;
    if(v1  && !v2) return false;
81
    if(!v1 &&  v2) return false;
82
83
    return m_impl->m_datastore  == other.m_impl->m_datastore
        && m_impl->m_level      == other.m_impl->m_level
84
85
        && (m_impl->m_container == other.m_impl->m_container
            || *m_impl->m_container == *other.m_impl->m_container )
86
        && m_impl->m_name       == other.m_impl->m_name;
87
88
}

89
90
91
92
bool DataSet::operator!=(const DataSet& other) const {
    return !(*this == other);
}

93
const std::string& DataSet::name() const {
94
95
96
    if(!valid()) {
        throw Exception("Calling DataSet member function on an invalid DataSet");
    }
97
98
99
100
    return m_impl->m_name;
}

const std::string& DataSet::container() const {
101
102
103
    if(!valid()) {
        throw Exception("Calling DataSet member function on an invalid DataSet");
    }
104
    return *m_impl->m_container;
105
106
107
}

std::string DataSet::fullname() const {
108
109
110
111
    if(!valid()) {
        throw Exception("Calling DataSet member function on an invalid DataSet");
    }
    return m_impl->fullname();
112
113
}

114
DataSet DataSet::createDataSet(const std::string& name) {
115
116
117
    if(name.find('/') != std::string::npos
    || name.find('%') != std::string::npos) {
        throw Exception("Invalid character '/' or '%' in dataset name");
118
    }
119
    std::string parent = fullname();
120
    m_impl->m_datastore->createDataSet(m_impl->m_level+1, parent, name);
121
    return DataSet(std::make_shared<DataSetImpl>(
122
123
                m_impl->m_datastore, m_impl->m_level+1,
                std::make_shared<std::string>(parent), name));
124
}
125

126
Run DataSet::createRun(const RunNumber& runNumber) {
127
128
129
    if(InvalidRunNumber == runNumber) {
        throw Exception("Trying to create a Run with InvalidRunNumber");
    }
130
    std::string parent = fullname();
131
    std::string runStr = makeKeyStringFromNumber(runNumber);
132
133
    m_impl->m_datastore->store(m_impl->m_level+1, parent, runStr);
    return Run(
134
            std::make_shared<RunImpl>(
135
136
                m_impl->m_datastore, m_impl->m_level+1,
                std::make_shared<std::string>(parent), runNumber));
137
138
}

Matthieu Dorier's avatar
Matthieu Dorier committed
139
140
141
142
143
Run DataSet::createRun(WriteBatch& batch, const RunNumber& runNumber) {
    if(InvalidRunNumber == runNumber) {
        throw Exception("Trying to create a Run with InvalidRunNumber");
    }
    std::string parent = fullname();
144
    std::string runStr = makeKeyStringFromNumber(runNumber);
145
    batch.m_impl->store(m_impl->m_level+1, parent, runStr);
146
    return Run(
147
            std::make_shared<RunImpl>(
148
149
                m_impl->m_datastore, m_impl->m_level+1,
                std::make_shared<std::string>(parent), runNumber));
Matthieu Dorier's avatar
Matthieu Dorier committed
150
151
}

152
153
DataSet DataSet::operator[](const std::string& datasetName) const {
    auto it = find(datasetName);
154
155
    if(!it->valid())
        throw Exception("Requested DataSet does not exist");
156
157
158
    return std::move(*it);
}

159
Run DataSet::operator[](const RunNumber& runNumber) const {
160
    auto it = runs().find(runNumber);
161
162
    if(!it->valid())
        throw Exception("Requested Run does not exist");
163
164
165
    return std::move(*it);
}

166
DataSet::iterator DataSet::find(const std::string& datasetPath) {
167
168
169
    if(!valid()) {
        throw Exception("Calling DataSet member function on an invalid DataSet");
    }
170
    int ret;
171
172
    if(datasetPath.find('%') != std::string::npos) {
        throw Exception("Invalid character '%' in dataset name");
173
    }
174
175
176
177
178
179

    size_t slash_count = std::count(datasetPath.begin(), datasetPath.end(), '/');
    size_t level = m_impl->m_level + 1 + slash_count;
    std::string containerName;
    std::string datasetName;

180
    std::string parent = fullname();
181
182
183
184
185
186
187
188
189
190

    if(slash_count == 0) {
        datasetName = datasetPath;
        containerName = parent;
    } else {
        size_t c = datasetPath.find_last_of('/');
        containerName = parent + "/" + datasetPath.substr(0,c);
        datasetName   = datasetPath.substr(c+1);
    }

191
    bool b = m_impl->m_datastore->dataSetExists(level, containerName, datasetName);
192
    if(!b) {
193
        return m_impl->m_datastore->m_end;
194
    }
195
196
    return iterator(
                DataSet(
197
                    std::make_shared<DataSetImpl>(
198
199
200
201
                        m_impl->m_datastore,
                        level,
                        std::make_shared<std::string>(containerName),
                        datasetName)));
202
203
204
205
206
207
208
209
}

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

DataSet::iterator DataSet::begin() {
210
211
212
    if(!valid()) {
        throw Exception("Calling DataSet member function on an invalid DataSet");
    }
Matthieu Dorier's avatar
Matthieu Dorier committed
213
214
    // we use the prefix "&" because we need something that comes after "%"
    // (which represents runs) and is not going to be in a dataset name
215
    DataSet ds(
216
            std::make_shared<DataSetImpl>(
217
218
219
220
221
                m_impl->m_datastore, 
                m_impl->m_level+1,
                std::make_shared<std::string>(fullname()),
                "&"));

222
    ds = ds.next();
223
    if(ds.valid()) return iterator(ds);
224
225
226
227
    else return end();
}

DataSet::iterator DataSet::end() {
228
229
230
    if(!valid()) {
        throw Exception("Calling DataSet member function on an invalid DataSet");
    }
231
    return m_impl->m_datastore->m_end;
232
233
}

234
235
236
237
238
DataSet::const_iterator DataSet::begin() const {
    return const_iterator(const_cast<DataSet*>(this)->begin());
}

DataSet::const_iterator DataSet::end() const {
239
240
241
    if(!valid()) {
        throw Exception("Calling DataSet member function on an invalid DataSet");
    }
242
    return m_impl->m_datastore->m_end;
243
244
}

245
246
247
248
249
DataSet::const_iterator DataSet::cbegin() const {
    return const_iterator(const_cast<DataSet*>(this)->begin());
}

DataSet::const_iterator DataSet::cend() const {
250
251
252
    if(!valid()) {
        throw Exception("Calling DataSet member function on an invalid DataSet");
    }
253
    return m_impl->m_datastore->m_end;
254
255
256
}

DataSet::iterator DataSet::lower_bound(const std::string& lb) {
257
258
259
    if(!valid()) {
        throw Exception("Calling DataSet member function on an invalid DataSet");
    }
260
261
262
263
264
265
266
267
268
    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;
    }
269
    DataSet ds(
270
            std::make_shared<DataSetImpl>(
271
272
273
274
275
                m_impl->m_datastore, 
                m_impl->m_level+1,
                std::make_shared<std::string>(fullname()),
                lb2));

276
277
    ds = ds.next();
    if(!ds.valid()) return end();
278
    else return iterator(ds);
279
280
281
282
283
284
285
286
}

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) {
287
288
289
    if(!valid()) {
        throw Exception("Calling DataSet member function on an invalid DataSet");
    }
290
    DataSet ds(
291
            std::make_shared<DataSetImpl>(
292
293
294
295
                m_impl->m_datastore,
                m_impl->m_level+1,
                std::make_shared<std::string>(fullname()), ub));

296
297
    ds = ds.next();
    if(!ds.valid()) return end();
298
    else return iterator(ds);
299
300
301
302
303
304
305
}

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

306
RunSet DataSet::runs() const {
307
308
309
    if(!valid()) {
        throw Exception("Calling DataSet member function on an invalid DataSet");
    }
310
    return RunSet(m_impl);
311
312
}

313
}