/* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2.0, as published by the Free Software Foundation. This program is also distributed with certain software (including but not limited to OpenSSL) that is licensed under separate terms, as designated in a particular file or component or in included license documentation. The authors of MySQL hereby grant you an additional permission to link the program and your derivative works with the separately licensed software that they have included with MySQL. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0, for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef NDBT_HISTORY_HPP #define NDBT_HISTORY_HPP #include #include /** * Class for giving e.g. a set of steps their own * id out of a range of 0..totalWorkers * * Handy for e.g. subdividing a range of records * amongst a variable number of workers * * Usage : * WorkerIdentifier() * Repeat * init(totalWorkers) * Repeat * getNextWorkerId() * getTotalWorkers() * ... */ class WorkerIdentifier : public NdbLockable { Uint32 m_totalWorkers; Uint32 m_nextWorker; public: WorkerIdentifier(); void init(const Uint32 totalWorkers); Uint32 getTotalWorkers() const; Uint32 getNextWorkerId(); }; /** * EpochRange * * A representation of a range of epochs * This is useful when comparing versions between * multiple histories * * Epoch range has an open start and closed end * * [start, end) * * start = 11/20 * end = 12/3 * * includes * 11/20,11/21,...11/0xffffffff,12/0,12/1 * * does not include * <= 11/19 >= 12/3 * * Two ranges intersect if they have any epochs * in common */ struct EpochRange { static const Uint64 MAX_EPOCH = 0xffffffffffffffffULL; /* Start is included */ Uint64 m_start; /* End is not included */ Uint64 m_end; EpochRange intersect(const EpochRange& other) const { EpochRange i; i.m_start = MAX(m_start, other.m_start); i.m_end = MIN(m_end, other.m_end); return i; } bool isEmpty() const { return (m_start >= m_end); } bool spansGciBoundary() const { /* Does this range span at least one GCI ? */ assert(m_end > m_start); return ((m_end >> 32) > (m_start >> 32)); } static Uint32 hi(const Uint64 epoch) { return Uint32(epoch>>32); } static Uint32 lo(const Uint64 epoch) { return Uint32(epoch & 0xffffffff); } void dump() const; }; /** * EpochRangeSet * * Set of EpochRanges of interest. * * This is useful for describing consistent points in * history when some condition was true * * Not guaranteed that all contained ranges are unique or * disjoint with each other */ struct EpochRangeSet { Vector m_ranges; EpochRangeSet() {} EpochRangeSet(const EpochRangeSet& other) { for (Uint32 i=0; i < other.m_ranges.size(); i++) { m_ranges.push_back(other.m_ranges[i]); } } /** * Add an epochRange to an EpochRangeSet */ void addEpochRange(const EpochRange& er) { m_ranges.push_back(er); } /** * Does this EpochRangeSet describe any range * of epochs? */ bool isEmpty() const { for (Uint32 i=0; i m_storedVersions; Uint64 m_nextNumber; }; #endif