sgpemv2/src/backend/history.cc
tchernobog 383889a203 - Add unified Singleton support
git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@643 3ecf2c5c-341e-0410-92b4-d18e462d057c
2006-06-21 09:09:50 +00:00

139 lines
4.1 KiB
C++

// src/backend/history.cc - Copyright 2005, 2006, University
// of Padova, dept. of Pure and Applied
// Mathematics
//
// This file is part of SGPEMv2.
//
// This 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.
//
// SGPEMv2 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 SGPEMv2; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "history.hh"
using namespace std;
using namespace sgpem;
using namespace memory;
/**
The constructor sets _total_time_elapsed to -1: this permits to insert the INITIAL STATUS
of the simulation which must begin at instant -1 and live for 1 instant.
*/
History::History() //private constructor.
:_total_time_elapsed(-1)
{}
/**
Returns a pointer to a copy of the DynamicSchedulable object relative to this instant.
It can be NULL if time is out of range or if there are no running entities in the associated
SchedulableQueue
*/
smart_ptr<DynamicSchedulable>
History::get_scheduled_at(int time) const
{
if (time > _total_time_elapsed || time < 0) //out of range
return smart_ptr<DynamicSchedulable>(NULL);
//look for a runing entity
smart_ptr<SchedulableQueue> p = get_simulation_status_at(time);
for (uint i = 0; i < p->size(); i++)
if (p->get_item_at(i)->get_state() == DynamicSchedulable::state_running)
return smart_ptr<DynamicSchedulable>(new DynamicSchedulable(*(p->get_item_at(i))));
return smart_ptr<DynamicSchedulable>(NULL);
}
/**
Returns a pointer to a copy of the SimulationStatus object relative to this instant or NULL
if time is out of range.
*/
smart_ptr<SchedulableQueue>
History::get_simulation_status_at(int time) const
{
if (time > _total_time_elapsed || time < 0) //out of range
return smart_ptr<SchedulableQueue>(NULL);
int trascorso = -1;
for(vector<Slice>::const_iterator i=_slices.begin(); i < _slices.end(); i++)
if (time <= trascorso + i->get_duration()) //FOUND!!
return smart_ptr<SchedulableQueue>(new SchedulableQueue(*i->get_simulation_status()));
else //Go on...
trascorso += i->get_duration();
//never reached if all slices are CONTIGUOUS (ans THIS shoul be!!)!!!
return smart_ptr<SchedulableQueue>(NULL);
}
int
History::get_current_time() const
{
return _total_time_elapsed;
}
/**
Appends to the history a SimulationStatus creating a Slice with duration of 1 instant.
Calls the method notify() in quality of ObservedSubject, updating all observers.
*/
void
History::enqueue_slice(const SchedulableQueue& status)
{
if(_slices.size() == 0)
{
_slices.push_back(Slice(-1, 1, status));
_total_time_elapsed++;
notify();
return;
}
//check the last slice
Slice& last = _slices[_slices.size()-1];
if (last.get_simulation_status()->has_same_objects(status)) //increments the duration by ONE unit
{
last.set_duration(last.get_duration()+1);
}
else //insert a new slice CONTIGUOUS to the last one
{
_slices.push_back(Slice(last.get_started_at() + last.get_duration(), 1, status));
}
_total_time_elapsed++; //one instant is passed...
notify();
}
/**
Removes all the informations about the simulation following the specified instant.
Ex. truncate_at(0); removes all scheduled slices
Ex. truncate_at(-1); removes all scheduled slices and the initial status
*/
void
History::truncate_at(int instant)
{
vector<Slice>::iterator i = _slices.begin();
//reach the instant
while (i != _slices.end())
if (i->get_started_at() < instant)
i++;
else
{
//replaces the current vector with the "trimmed" one.
_slices = vector<Slice>(_slices.begin(),i);
_total_time_elapsed = instant;
break;
}
notify();
}