/* * Nomad Instrument Control Software * * Copyright 2011 Institut Laue-Langevin * * Licensed under the EUPL, Version 1.1 only (the "License"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * * http://www.osor.eu/eupl * * Unless required by applicable law or agreed to in writing, software * distributed under the Licence is distributed on an "AS IS" basis, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the Licence for the specific language governing permissions and * limitations under the Licence. */ #include "EventBlockArray.h" #include #include "Event.h" using namespace std; namespace lstdpp128 { EventBlock * EventBlockArray::updateBlocks() { //cout << "update with #blocks = " << _array.size() << " max = " << _maxBlocks << endl; // removing first block? if (_maxBlocks != -1 && _array.size() >= _maxBlocks) { // removing first block //cout << "deleting block " << _array.front()->id << endl; EventBlock * block = _array.front(); _array.pop_front(); _reduced = true; //cout << "array reduced, first block is " << *_array.front() << endl; return block; } return 0; } void EventBlockArray::addEventBlock() { // adding a block only if last is not empty if (_array.empty() || !_array.back()->events.empty()) { updateBlocks(); _array.push_back(new EventBlock()); } } bool EventBlockArray::isInsertable(time_type time) const { if (_reduced) { // if (time < _array.front()->minTime()) { // cout << "cannot insert event with time " << time << ", min time is " << _array.front()->minTime() << endl; // } return (time >= _array.front()->minTime()); } return true; } EventBlockArrayIterator EventBlockArray::begin() const { return EventBlockArrayIterator(_array, _array.begin(), (*_array.begin())->events.begin()); } EventBlockArrayIterator EventBlockArray::end() const { return EventBlockArrayIterator(_array, _array.end(), _array.back()->events.end()); } time_type EventBlockArray::maxPreviousBlockTime(EventBlockArray::array_type::reverse_iterator const & b) const { EventBlockArray::array_type::const_reverse_iterator bc = b; // cout << "maxPreviousBlockTime " << (*b)->id << " " << (*bc)->id << endl; ++bc; if (bc != array().rend()) { // cout << "maxPreviousBlockTime returning " << (*bc)->id << endl; return (*bc)->maxTime(); } return -1; } EventBlockArrayIterator EventBlockArray::insertEvent(Event const & event) { //cout << "inserting event " << event << endl; // inserting the event in the events blocks for (EventBlockArray::array_type::reverse_iterator b = array().rbegin(); b != array().rend(); ++b) { EventBlock * block = *b; // testing if the event belongs to the current block if ((block->events.empty() && event.time() >= maxPreviousBlockTime(b)) || (!block->events.empty() && event.time() >= block->minTime())) { // iterator multiset::const_iterator e; if (block->events.size() == _maxBlockSize - 1) { //cout << "max block size for block " << block->id << endl; // splitting the block time_type midTime = (block->minTime() + block->maxTime()) / 2; EventBlock * newBlock = block->split(midTime); // inserting new block in EventBlocks EventBlockArray::array_type::const_iterator fb = array().insert(b.base(), newBlock); //cout << "inserted new block " << newBlock->id << " " << (*fb)->id << endl; // selecting block if (event.time() <= midTime) { e = block->events.insert(event); --fb; //cout << "inserted in first block " << block->id << ", block fb " << (*fb)->id << endl; } else { e = newBlock->events.insert(event); //cout << "inserted in second block " << newBlock->id << ", block fb " << (*fb)->id << endl; } //cout << "iterator in block " << (*fb)->id << endl; // returning the new iterator return EventBlockArrayIterator(array(), fb, e); } else { // simply insert e = block->events.insert(event); // converting b to a forward iterator ++b; EventBlockArray::array_type::const_iterator fb = b.base(); //cout << "iterator in block " << (*fb)->id << endl; /* EventBlockArrayIterator eba(array(), fb, e); if (eba.end()) { cout << " at end 1" << endl; } else { ++eba; if (eba.end()) { cout << " at end 2" << endl; } }*/ // returning the new iterator return EventBlockArrayIterator(array(), fb, e); } } // go to next block } // finally, we insert in the first block if not found the block before // inserting and getting the iterator multiset::const_iterator e = array().front()->events.insert(event); // returning the new iterator return EventBlockArrayIterator(array(), array().begin(), e); } void testIterator(EventBlockArray const & EventBlocks) { EventBlockArrayIterator e = EventBlocks.begin(); while (e != EventBlocks.end()) { cout << "event " << *e << endl; ++e; --e; ++e; } while (e != EventBlocks.begin()) { --e; cout << "event " << *e << endl; } } void testSplitBlocks(EventBlockArray const & EventBlocks) { EventBlocks.array().front()->split(); } void printBlocks(EventBlockArray const & EventBlocks, bool printEvents) { for (EventBlockArray::array_type::const_iterator b = EventBlocks.array().begin(); b != EventBlocks.array().end(); ++b) { cout << "block " << *(*b) << endl; if (printEvents) { for (multiset::const_iterator e = (*b)->events.begin(); e != (*b)->events.end(); ++e) { cout << " event " << *e << endl; } } } } void checkEvents(EventBlockArray const & EventBlocks) { int32_t nbEvents = 0; time_type lastEventTime = 0; for (EventBlockArray::array_type::const_iterator b = EventBlocks.array().begin(); b != EventBlocks.array().end(); ++b) { for (multiset::const_iterator e = (*b)->events.begin(); e != (*b)->events.end(); ++e) { nbEvents++; if (e->time() < lastEventTime) { cout << "error in events ordering" << endl; } lastEventTime = e->time(); } } cout << "found " << nbEvents << " events" << endl; } }