// 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 History::get_scheduled_at(int time) const { if (time > _total_time_elapsed || time < 0) //out of range return smart_ptr(NULL); //look for a runing entity smart_ptr 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(new DynamicSchedulable(*(p->get_item_at(i)))); return smart_ptr(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 History::get_simulation_status_at(int time) const { if (time > _total_time_elapsed || time < 0) //out of range return smart_ptr(NULL); int trascorso = -1; for(vector::const_iterator i=_slices.begin(); i < _slices.end(); i++) if (time <= trascorso + i->get_duration()) //FOUND!! return smart_ptr(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(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::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(_slices.begin(),i); _total_time_elapsed = instant; break; } notify(); }