139 lines
4.1 KiB
C++
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();
|
|
}
|
|
|
|
|
|
|
|
|