Run.cpp 13.1 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/Run.hpp"
7
#include "hepnos/AsyncEngine.hpp"
Matthieu Dorier's avatar
Matthieu Dorier committed
8 9
#include "ItemImpl.hpp"
#include "ItemImpl.hpp"
10 11
#include "DataStoreImpl.hpp"
#include "WriteBatchImpl.hpp"
12
#include "AsyncEngineImpl.hpp"
13 14 15

namespace hepnos {

Matthieu Dorier's avatar
Matthieu Dorier committed
16
static Run::iterator Run_end;
17

18
Run::Run()
Matthieu Dorier's avatar
Matthieu Dorier committed
19
: m_impl(std::make_shared<ItemImpl>(nullptr, UUID(), InvalidRunNumber)) {} 
20

Matthieu Dorier's avatar
Matthieu Dorier committed
21
Run::Run(std::shared_ptr<ItemImpl>&& impl)
22
: m_impl(std::move(impl)) { }
23

Matthieu Dorier's avatar
Matthieu Dorier committed
24
Run::Run(const std::shared_ptr<ItemImpl>& impl)
25
: m_impl(impl) { }
26

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

34 35 36
Run Run::next() const {
    if(!valid()) return Run();
   
Matthieu Dorier's avatar
Matthieu Dorier committed
37 38
    std::vector<std::shared_ptr<ItemImpl>> next_runs;
    size_t s = m_impl->m_datastore->nextItems(m_impl, next_runs, 1);
39
    if(s == 0) return Run();
Matthieu Dorier's avatar
Matthieu Dorier committed
40
    return Run(std::move(next_runs[0]));
41 42 43 44 45 46 47
}

bool Run::valid() const {
    return m_impl && m_impl->m_datastore; 

}

48
ProductID Run::storeRawData(const std::string& key, const char* value, size_t vsize) {
49
    if(!valid()) {
50
        throw Exception("Calling Run member function on an invalid Run object");
51 52
    }
    // forward the call to the datastore's store function
Matthieu Dorier's avatar
Matthieu Dorier committed
53 54
    const ItemDescriptor& id = m_impl->m_descriptor;
    return m_impl->m_datastore->storeRawProduct(id, key, value, vsize);
55 56
}

57
ProductID Run::storeRawData(WriteBatch& batch, const std::string& key, const char* value, size_t vsize) {
58 59 60
    if(!valid()) {
        throw Exception("Calling Run member function on an invalid Run object");
    }
61
    // forward the call to the batch's store function
Matthieu Dorier's avatar
Matthieu Dorier committed
62
    const ItemDescriptor& id = m_impl->m_descriptor;
63 64 65 66
    if(batch.m_impl)
        return batch.m_impl->storeRawProduct(id, key, value, vsize);
    else
        return m_impl->m_datastore->storeRawProduct(id, key, value, vsize);
67 68
}

69 70 71 72 73 74
ProductID Run::storeRawData(AsyncEngine& async, const std::string& key, const char* value, size_t vsize) {
    if(!valid()) {
        throw Exception("Calling Run member function on an invalid Run object");
    }
    // forward the call to the async engine's store function
    const ItemDescriptor& id = m_impl->m_descriptor;
75 76 77 78
    if(async.m_impl)
        return async.m_impl->storeRawProduct(id, key, value, vsize);
    else
        return m_impl->m_datastore->storeRawProduct(id, key, value, vsize);
79 80
}

81
bool Run::loadRawData(const std::string& key, std::string& buffer) const {
82 83 84
    if(!valid()) {
        throw Exception("Calling Run member function on an invalid Run object");
    }
85
    // forward the call to the datastore's load function
Matthieu Dorier's avatar
Matthieu Dorier committed
86 87
    const ItemDescriptor& id = m_impl->m_descriptor;
    return m_impl->m_datastore->loadRawProduct(id, key, buffer);
88 89
}

90
bool Run::loadRawData(const std::string& key, char* value, size_t* vsize) const {
91
    if(!valid()) {
92
        throw Exception("Calling DataSet member function on an invalid DataSet");
93 94
    }
    // forward the call to the datastore's load function
Matthieu Dorier's avatar
Matthieu Dorier committed
95 96
    const ItemDescriptor& id = m_impl->m_descriptor;
    return m_impl->m_datastore->loadRawProduct(id, key, value, vsize);
97 98 99
}

bool Run::operator==(const Run& other) const {
100 101 102 103 104
    bool v1 = valid();
    bool v2 = other.valid();
    if(!v1 && !v2) return true;
    if(v1 && !v2)  return false;
    if(!v1 && v2)  return false;
105
    return (m_impl == other.m_impl) || (*m_impl == *other.m_impl);
106 107 108 109 110 111 112
}

bool Run::operator!=(const Run& other) const {
    return !(*this == other);
}

const RunNumber& Run::number() const {
113 114 115
    if(!valid()) {
        throw Exception("Calling Run member function on an invalid Run object");
    }
Matthieu Dorier's avatar
Matthieu Dorier committed
116
    return m_impl->m_descriptor.run;
117 118
}

Matthieu Dorier's avatar
Matthieu Dorier committed
119
SubRun Run::createSubRun(const SubRunNumber& subRunNumber) {
120 121 122
    if(!valid()) {
        throw Exception("Calling Run member function on an invalid Run object");
    }
Matthieu Dorier's avatar
Matthieu Dorier committed
123 124 125
    ItemDescriptor& id = m_impl->m_descriptor;
    m_impl->m_datastore->createItem(id.dataset, id.run, subRunNumber);
    auto new_subrun_impl = std::make_shared<ItemImpl>(m_impl->m_datastore, id.dataset, id.run, subRunNumber);
126
    return SubRun(std::move(new_subrun_impl));
127 128
}

Matthieu Dorier's avatar
Matthieu Dorier committed
129 130 131 132
SubRun Run::createSubRun(WriteBatch& batch, const SubRunNumber& subRunNumber) {
    if(!valid()) {
        throw Exception("Calling Run member function on an invalid Run object");
    }
Matthieu Dorier's avatar
Matthieu Dorier committed
133
    ItemDescriptor& id = m_impl->m_descriptor;
134 135 136 137
    if(batch.m_impl)
        batch.m_impl->createItem(id.dataset, id.run, subRunNumber);
    else
        m_impl->m_datastore->createItem(id.dataset, id.run, subRunNumber);
Matthieu Dorier's avatar
Matthieu Dorier committed
138
    auto new_subrun_impl = std::make_shared<ItemImpl>(m_impl->m_datastore, id.dataset, id.run, subRunNumber);
139 140 141 142 143 144 145 146
    return SubRun(std::move(new_subrun_impl));
}

SubRun Run::createSubRun(AsyncEngine& async, const SubRunNumber& subRunNumber) {
    if(!valid()) {
        throw Exception("Calling Run member function on an invalid Run object");
    }
    ItemDescriptor& id = m_impl->m_descriptor;
147 148 149 150
    if(async.m_impl)
        async.m_impl->createItem(id.dataset, id.run, subRunNumber);
    else
        m_impl->m_datastore->createItem(id.dataset, id.run, subRunNumber);
151
    auto new_subrun_impl = std::make_shared<ItemImpl>(m_impl->m_datastore, id.dataset, id.run, subRunNumber);
152
    return SubRun(std::move(new_subrun_impl));
Matthieu Dorier's avatar
Matthieu Dorier committed
153 154
}

155
SubRun Run::operator[](const SubRunNumber& subRunNumber) const {
Matthieu Dorier's avatar
Matthieu Dorier committed
156
    auto it = find(subRunNumber);
157 158
    if(!it->valid())
        throw Exception("Requested SubRun does not exist");
159 160 161
    return std::move(*it);
}

Matthieu Dorier's avatar
Matthieu Dorier committed
162
Run::iterator Run::find(const SubRunNumber& subRunNumber) {
163 164 165
    if(!valid()) {
        throw Exception("Calling Run member function on an invalid Run object");
    }
Matthieu Dorier's avatar
Matthieu Dorier committed
166 167 168 169
    auto& id = m_impl->m_descriptor;
    bool b = m_impl->m_datastore->itemExists(id.dataset, 
                                             id.run,
                                             subRunNumber);
170
    if(!b) {
Matthieu Dorier's avatar
Matthieu Dorier committed
171
        return Run_end;
172
    }
Matthieu Dorier's avatar
Matthieu Dorier committed
173
    auto new_subrun_impl = std::make_shared<ItemImpl>(m_impl->m_datastore, id.dataset, id.run, subRunNumber);
174
    return iterator(SubRun(std::move(new_subrun_impl)));
175 176
}

Matthieu Dorier's avatar
Matthieu Dorier committed
177 178
Run::const_iterator Run::find(const SubRunNumber& subRunNumber) const {
    iterator it = const_cast<Run*>(this)->find(subRunNumber);
179 180 181
    return it;
}

Matthieu Dorier's avatar
Matthieu Dorier committed
182 183
Run::iterator Run::begin() {
    auto it = find(0);
184
    if(it != end()) return it;
Matthieu Dorier's avatar
Matthieu Dorier committed
185

Matthieu Dorier's avatar
Matthieu Dorier committed
186 187
    auto& id = m_impl->m_descriptor;
    auto new_subrun_impl = std::make_shared<ItemImpl>(m_impl->m_datastore, id.dataset, id.run, 0);
188 189

    SubRun subrun(std::move(new_subrun_impl));
Matthieu Dorier's avatar
Matthieu Dorier committed
190 191 192
    subrun = subrun.next();

    if(subrun.valid()) return iterator(subrun);
193 194 195
    else return end();
}

Matthieu Dorier's avatar
Matthieu Dorier committed
196
Run::iterator Run::end() {
197 198 199
    if(!valid()) {
        throw Exception("Calling Run member function on an invalid Run object");
    }
Matthieu Dorier's avatar
Matthieu Dorier committed
200
    return Run_end;
Matthieu Dorier's avatar
Matthieu Dorier committed
201 202 203 204 205 206 207
}

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

Run::const_iterator Run::end() const {
208 209 210
    if(!valid()) {
        throw Exception("Calling Run member function on an invalid Run object");
    }
Matthieu Dorier's avatar
Matthieu Dorier committed
211
    return Run_end;
212 213
}

Matthieu Dorier's avatar
Matthieu Dorier committed
214 215
Run::const_iterator Run::cbegin() const {
    return const_iterator(const_cast<Run*>(this)->begin());
216 217
}

Matthieu Dorier's avatar
Matthieu Dorier committed
218
Run::const_iterator Run::cend() const {
219 220 221
    if(!valid()) {
        throw Exception("Calling Run member function on an invalid Run object");
    }
Matthieu Dorier's avatar
Matthieu Dorier committed
222
    return Run_end;
223 224
}

Matthieu Dorier's avatar
Matthieu Dorier committed
225 226 227 228 229 230
Run::iterator Run::lower_bound(const SubRunNumber& lb) {
    if(lb == 0) {
        auto it = find(0);
        if(it != end()) {
            return it;
        } else {
Matthieu Dorier's avatar
Matthieu Dorier committed
231 232
            auto& id = m_impl->m_descriptor;
            auto new_subrun_impl = std::make_shared<ItemImpl>(m_impl->m_datastore, id.dataset, id.run, 0);
233
            SubRun subrun(std::move(new_subrun_impl));
Matthieu Dorier's avatar
Matthieu Dorier committed
234 235 236 237 238 239 240 241 242 243
            subrun = subrun.next();
            if(!subrun.valid()) return end();
            else return iterator(subrun);
        }
    } else {
        auto it = find(lb-1);
        if(it != end()) {
            ++it;
            return it;
        }
Matthieu Dorier's avatar
Matthieu Dorier committed
244 245
        auto& id = m_impl->m_descriptor;
        auto new_subrun_impl = std::make_shared<ItemImpl>(m_impl->m_datastore, id.dataset, id.run, lb-1);
246
        SubRun subrun(std::move(new_subrun_impl));
Matthieu Dorier's avatar
Matthieu Dorier committed
247 248 249
        subrun = subrun.next();
        if(!subrun.valid()) return end();
        else return iterator(subrun);
250 251 252
    }
}

Matthieu Dorier's avatar
Matthieu Dorier committed
253 254
Run::const_iterator Run::lower_bound(const SubRunNumber& lb) const {
    iterator it = const_cast<Run*>(this)->lower_bound(lb);
255 256 257
    return it;
}

Matthieu Dorier's avatar
Matthieu Dorier committed
258
Run::iterator Run::upper_bound(const SubRunNumber& ub) {
259 260 261
    if(!valid()) {
        throw Exception("Calling Run member function on an invalid Run object");
    }
Matthieu Dorier's avatar
Matthieu Dorier committed
262 263
    auto& id = m_impl->m_descriptor;
    auto new_subrun_impl = std::make_shared<ItemImpl>(m_impl->m_datastore, id.dataset, id.run, ub);
264
    SubRun subrun(std::move(new_subrun_impl));
Matthieu Dorier's avatar
Matthieu Dorier committed
265 266 267
    subrun = subrun.next();
    if(!subrun.valid()) return end();
    else return iterator(subrun);
268 269
}

Matthieu Dorier's avatar
Matthieu Dorier committed
270 271
Run::const_iterator Run::upper_bound(const SubRunNumber& ub) const {
    iterator it = const_cast<Run*>(this)->upper_bound(ub);
272 273
    return it;
}
Matthieu Dorier's avatar
Matthieu Dorier committed
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318

////////////////////////////////////////////////////////////////////////////////////////////
// Run::const_iterator::Impl implementation
////////////////////////////////////////////////////////////////////////////////////////////

class Run::const_iterator::Impl {
    public:
        SubRun m_current_subrun;

        Impl()
        : m_current_subrun()
        {}

        Impl(const SubRun& subrun)
        : m_current_subrun(subrun)
        {}

        Impl(SubRun&& subrun)
            : m_current_subrun(std::move(subrun))
        {}

        Impl(const Impl& other)
            : m_current_subrun(other.m_current_subrun)
        {}

        bool operator==(const Impl& other) const {
            return m_current_subrun == other.m_current_subrun;
        }
};

////////////////////////////////////////////////////////////////////////////////////////////
// Run::const_iterator implementation
////////////////////////////////////////////////////////////////////////////////////////////

Run::const_iterator::const_iterator()
: m_impl(std::make_unique<Impl>()) {}

Run::const_iterator::const_iterator(const SubRun& subrun)
: m_impl(std::make_unique<Impl>(subrun)) {}

Run::const_iterator::const_iterator(SubRun&& subrun)
: m_impl(std::make_unique<Impl>(std::move(subrun))) {}

Run::const_iterator::~const_iterator() {}

319 320 321 322
Run::const_iterator::const_iterator(const Run::const_iterator& other) {
    if(other.m_impl) 
        m_impl = std::make_unique<Impl>(*other.m_impl);
}
Matthieu Dorier's avatar
Matthieu Dorier committed
323 324 325 326 327 328

Run::const_iterator::const_iterator(Run::const_iterator&& other)
: m_impl(std::move(other.m_impl)) {}

Run::const_iterator& Run::const_iterator::operator=(const Run::const_iterator& other) {
    if(&other == this) return *this;
329 330 331 332
    if(other.m_impl)
        m_impl = std::make_unique<Impl>(*other.m_impl);
    else
        m_impl.reset();
Matthieu Dorier's avatar
Matthieu Dorier committed
333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375
    return *this;
}

Run::const_iterator& Run::const_iterator::operator=(Run::const_iterator&& other) {
    if(&other == this) return *this;
    m_impl = std::move(other.m_impl);
    return *this;
}

Run::const_iterator::self_type Run::const_iterator::operator++() {
    if(!m_impl) {
        throw Exception("Trying to increment an invalid iterator");
    }
    m_impl->m_current_subrun = m_impl->m_current_subrun.next();
    return *this;
}

Run::const_iterator::self_type Run::const_iterator::operator++(int) {
    const_iterator copy = *this;
    ++(*this);
    return copy;
}

const Run::const_iterator::reference Run::const_iterator::operator*() {
    if(!m_impl) {
        throw Exception("Trying to dereference an invalid iterator");
    }
    return m_impl->m_current_subrun;
}

const Run::const_iterator::pointer Run::const_iterator::operator->() {
    if(!m_impl) return nullptr;
    return &(m_impl->m_current_subrun);
}

bool Run::const_iterator::operator==(const self_type& rhs) const {
    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);
}

bool Run::const_iterator::operator!=(const self_type& rhs) const {
376
    return !(*this == rhs);
Matthieu Dorier's avatar
Matthieu Dorier committed
377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401
}

////////////////////////////////////////////////////////////////////////////////////////////
// Run::iterator implementation
////////////////////////////////////////////////////////////////////////////////////////////

Run::iterator::iterator(const SubRun& current)
: const_iterator(current) {}

Run::iterator::iterator(SubRun&& current)
: const_iterator(std::move(current)) {}

Run::iterator::iterator()
: const_iterator() {}

Run::iterator::~iterator() {}

Run::iterator::iterator(const Run::iterator& other)
: const_iterator(other) {}

Run::iterator::iterator(Run::iterator&& other)
: const_iterator(std::move(other)) {}

Run::iterator& Run::iterator::operator=(const Run::iterator& other) {
    if(this == &other) return *this;
402 403 404 405
    if(other.m_impl) 
        m_impl = std::make_unique<Impl>(*other.m_impl);
    else
        m_impl.reset();
Matthieu Dorier's avatar
Matthieu Dorier committed
406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422
    return *this;
}

Run::iterator& Run::iterator::operator=(Run::iterator&& other) {
    if(this == &other) return *this;
    m_impl = std::move(other.m_impl);
    return *this;
}

Run::iterator::reference Run::iterator::operator*() {
    return const_cast<reference>(const_iterator::operator*());
}

Run::iterator::pointer Run::iterator::operator->() {
    return const_cast<pointer>(const_iterator::operator->());
}

423
}