DataSet.cpp 6.74 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
9
10
#include "hepnos/Run.hpp"
#include "hepnos/RunSet.hpp"
#include "private/RunImpl.hpp"
#include "private/DataSetImpl.hpp"
11
#include "private/DataStoreImpl.hpp"
12
13
14

namespace hepnos {

15
DataSet::DataSet()
16
: m_impl(std::make_unique<DataSet::Impl>(this, nullptr, 0, "", "")) {}
17

18
DataSet::DataSet(DataStore* ds, uint8_t level, const std::string& fullname)
19
: m_impl(std::make_unique<DataSet::Impl>(this, ds, level, "", "")) {
20
21
    size_t p = fullname.find_last_of('/');
    if(p == std::string::npos) {
22
        m_impl->m_name = fullname;
23
    } else {
24
25
        m_impl->m_name = fullname.substr(p+1);
        m_impl->m_container = fullname.substr(0, p);
26
27
28
    }
}

29
DataSet::DataSet(DataStore* ds, uint8_t level, const std::string& container, const std::string& name) 
30
: m_impl(std::make_unique<DataSet::Impl>(this, ds, level, container, name)) {}
31
32

DataSet::DataSet(const DataSet& other)
33
34
35
36
37
: m_impl(std::make_unique<DataSet::Impl>(
            this, other.m_impl->m_datastore,
            other.m_impl->m_level,
            other.m_impl->m_container,
            other.m_impl->m_name)) {}
38
39
40
41
42

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

DataSet& DataSet::operator=(const DataSet& other) {
    if(this == &other) return *this;
43
44
45
46
47
    m_impl = std::make_unique<DataSet::Impl>(this, 
            other.m_impl->m_datastore,
            other.m_impl->m_level,
            other.m_impl->m_container,
            other.m_impl->m_name);
48
49
50
51
52
53
    return *this;
}

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

DataSet::~DataSet() {}
54

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

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

}

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

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

bool DataSet::operator==(const DataSet& other) const {
87
88
89
90
    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;
91
92
}

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

97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
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();
}

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

122
123
124
125
126
127
128
Run DataSet::createRun(const RunNumber& runNumber) {
    std::string parent = fullname();
    std::string runStr = Run::Impl::makeKeyStringFromRunNumber(runNumber);
    m_impl->m_datastore->m_impl->store(m_impl->m_level+1, parent, runStr, std::vector<char>());
    return Run(m_impl->m_datastore, m_impl->m_level+1, parent, runNumber);
}

129
130
131
132
133
DataSet DataSet::operator[](const std::string& datasetName) const {
    auto it = find(datasetName);
    return std::move(*it);
}

134
135
136
137
138
Run DataSet::operator()(const RunNumber& runNumber) const {
    auto it = runs().find(runNumber);
    return std::move(*it);
}

139
140
141
142
143
144
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;
145
    std::string parent = fullname();
146
    bool b = m_impl->m_datastore->m_impl->load(m_impl->m_level+1, parent, datasetName, data);
147
148
149
    if(!b) {
        return m_impl->m_datastore->end();
    }
150
    return iterator(DataSet(m_impl->m_datastore, m_impl->m_level+1, parent, datasetName));
151
152
153
154
155
156
157
158
}

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

DataSet::iterator DataSet::begin() {
159
    DataSet ds(m_impl->m_datastore, m_impl->m_level+1, fullname(),"");
160
    ds = ds.next();
161
    if(ds.valid()) return iterator(ds);
162
163
164
165
166
167
168
    else return end();
}

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

169
170
171
172
173
174
175
176
DataSet::const_iterator DataSet::begin() const {
    return const_iterator(const_cast<DataSet*>(this)->begin());
}

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

177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
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;
    }
195
    DataSet ds(m_impl->m_datastore, m_impl->m_level+1, fullname(), lb2);
196
197
    ds = ds.next();
    if(!ds.valid()) return end();
198
    else return iterator(ds);
199
200
201
202
203
204
205
206
}

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) {
207
    DataSet ds(m_impl->m_datastore, m_impl->m_level+1, fullname(), ub);
208
209
    ds = ds.next();
    if(!ds.valid()) return end();
210
    else return iterator(ds);
211
212
213
214
215
216
217
}

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

218
219
220
221
222
223
224
225
RunSet& DataSet::runs() {
    return m_impl->m_runset;
}

const RunSet& DataSet::runs() const {
    return const_cast<DataSet*>(this)->runs();
}

226
}