/* **************************************************************************** * Copyright 2019 Open Systems Development BV * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the "Software"), * * to deal in the Software without restriction, including without limitation * * the rights to use, copy, modify, merge, publish, distribute, sublicense, * * and/or sell copies of the Software, and to permit persons to whom the * * Software is furnished to do so, subject to the following conditions: * * * * The above copyright notice and this permission notice shall be included in * * all copies or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * * DEALINGS IN THE SOFTWARE. * * ***************************************************************************/ #include "timeline.h" #include "log.h" using namespace osdev::components; Timeline::Timeline() : m_timeline(10) , m_proposedChange() { } const OrmBatchChange& Timeline::evaluate(const OrmBatchChange& desiredChange, bool exclusiveUpdate) { m_proposedChange = OrmBatchChange {}; if (m_timeline.full() && desiredChange < m_timeline.front()) { LogWarning("[Timeline::evaluate]", QString("Incoming change (%1) is older then the oldest registered change (%2).").arg(desiredChange.timestamp().toString()).arg(m_timeline.front().timestamp().toString())); return m_proposedChange; // change is older then anything we know, discard. } m_proposedChange = desiredChange; for (const auto& ch : m_timeline) { if (!m_proposedChange.processChange(ch, exclusiveUpdate)) { break; } } if ( m_proposedChange.valid() && !m_timeline.empty() && m_proposedChange < m_timeline.back()) { // reset the timestamp so that the proposed change will be the latest in the timeline when committed. auto ts = m_timeline.back().timestamp(); m_proposedChange.setTimestamp(++ts); } return m_proposedChange; } void Timeline::commit() { if (m_proposedChange.valid()) { m_timeline.push_back(m_proposedChange); m_proposedChange = OrmBatchChange {}; } }