/*************************************************************************** * Copyright (C) 2004 - 2005 by Raphael Langerhorst * * raphael-langerhorst@gmx.at * * * * 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 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 "GElementID.h" #include namespace GCS { /** * The actual static instance in memory. */ GIDContainer GElementID::FreeIDs; GIDRange::GIDRange() : LowerBound(1), UpperBound(0) { } GIDRange::GIDRange(unsigned long lower_bound, unsigned long upper_bound) : LowerBound(lower_bound), UpperBound(upper_bound) { //lower bound should NEVER be 0, the 0 IDs are not valid. if (LowerBound <= 0) { qWarning("Never use 0 as a valid GElementID, raised lower bound to 1!"); LowerBound = 1; } } unsigned long GIDRange::takeID() { if (isEmpty()) return 0; return LowerBound++; } bool GIDRange::isEmpty() const { if (count() <=0) return true; return false; } unsigned long GIDRange::count() const { if (LowerBound > UpperBound) return 0; else return UpperBound - LowerBound + 1; } void GIDRange::setRange(unsigned long low, unsigned long high) { LowerBound = low; UpperBound = high; } unsigned long GIDRange::getLowerBound() const { return LowerBound; } unsigned long GIDRange::getUpperBound() const { return UpperBound; } GElementID GElementID::getFreeID() { unsigned long id = 0; while (!FreeIDs.isEmpty() && id==0) { GIDRange* first = FreeIDs.first(); if (first->isEmpty()) FreeIDs.pop_front(); else id = first->takeID(); } return GElementID(id); } GIDContainer GElementID::getFreeIDRange(unsigned long amount) { GIDContainer container; unsigned long count = 0; while (!FreeIDs.isEmpty() && amount - count > 0) { GIDRange* first = FreeIDs.first(); unsigned long count_first = first->count(); if (amount - count >= count_first) { container.append(new GIDRange(*first)); FreeIDs.pop_front(); count += count_first; } else if (amount - count < count_first) { unsigned long low = first->getLowerBound(); first->setRange(low+amount-count,first->getUpperBound()); container.append(new GIDRange(low,low+amount-count-1)); //lower and upper bounds are included in count! count = amount; //MUST equal count += amount - count; } } return container; } void GElementID::addFreeIDRange(unsigned long lower_bound, unsigned long upper_bound) { qDebug(QString("Element ID Range added to free IDs: %1 to %2").arg(QString::number(lower_bound)).arg(QString::number(upper_bound))); FreeIDs.append(new GIDRange(lower_bound,upper_bound)); } unsigned long GElementID::countFreeIDs() { unsigned long c = 0; GIDContainer::iterator it; for (it = FreeIDs.begin(); it != FreeIDs.end(); ++it) { c+=(*it)->count(); } return c; } GElementID::GElementID() : ID(0) { } GElementID::GElementID(unsigned long id) : ID(id) { } GElementID::GElementID(const GElementID& original) : ID(original.getID()) { } unsigned long GElementID::getID() const { return ID; } QString GElementID::toString() const { return QString::number(ID); } bool GElementID::operator==(const GElementID& id) const { return this->ID == id.ID ? true : false; } bool GElementID::operator!=(const GElementID& id) const { return this->ID != id.ID ? true : false; } bool GElementID::operator>(const GElementID& id) const { return this->ID > id.ID ? true : false; } bool GElementID::operator<(const GElementID& id) const { return this->ID < id.ID ? true : false; } bool GElementID::operator>=(const GElementID& id) const { return this->ID >= id.ID ? true : false; } bool GElementID::operator<=(const GElementID& id) const { return this->ID <= id.ID ? true : false; } }