/*
* modelrangemanager.cpp
*
* This file is part of NEST.
*
* Copyright (C) 2004 The NEST Initiative
*
* NEST is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* NEST 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 for more details.
*
* You should have received a copy of the GNU General Public License
* along with NEST. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <assert.h>
#include <iostream>
#include "modelrangemanager.h"
#include "exceptions.h"
namespace nest {
Modelrangemanager::Modelrangemanager() :
first_gid_(0), last_gid_(0)
{ }
void Modelrangemanager::add_range(index model, index first_gid, index last_gid)
{
if (!modelranges_.empty())
{
assert(first_gid == last_gid_ + 1);
if (model == modelranges_.back().get_model_id())
modelranges_.back().extend_range(last_gid);
else
modelranges_.push_back(modelrange(model,first_gid,last_gid));
}
else
{
modelranges_.push_back(modelrange(model,first_gid,last_gid));
first_gid_ = first_gid;
}
last_gid_ = last_gid;
}
long_t Modelrangemanager::get_model_id(index gid)
{
int left = -1;
int right = modelranges_.size();
assert(right >= 1);
assert(is_in_range(gid));
// to ensure thread-safety, use local range_idx
size_t range_idx = right / 2; // start in center
while (!modelranges_[range_idx].is_in_range(gid))
{
if (gid > modelranges_[range_idx].get_last_gid())
{
left = range_idx;
range_idx += (right - range_idx)/2;
}
else
{
right = range_idx;
range_idx -= (range_idx - left)/2;
}
assert(left+1 < right);
assert(range_idx < modelranges_.size());
}
return modelranges_[range_idx].get_model_id();
}
bool Modelrangemanager::model_in_use(index i) const
{
bool found = false;
for (std::vector<modelrange>::const_iterator it = modelranges_.begin(); it != modelranges_.end(); it++)
if ( it->get_model_id() == i )
{
found = true;
break;
}
return found;
}
void Modelrangemanager::clear()
{
modelranges_.clear();
}
const modelrange& Modelrangemanager::get_range(index gid) const
{
if (!is_in_range(gid))
throw UnknownNode(gid);
for (std::vector<modelrange>::const_iterator it = modelranges_.begin(); it != modelranges_.end(); it++)
if ( it->is_in_range(gid) )
return (*it);
throw UnknownNode(gid);
}
} // namespace nest