Container.cpp 31 KB
Newer Older
Mathieu Faverge's avatar
Mathieu Faverge committed
1
/*
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
 ** This file is part of the ViTE project.
 **
 ** This software is governed by the CeCILL-A license under French law
 ** and abiding by the rules of distribution of free software. You can
 ** use, modify and/or redistribute the software under the terms of the
 ** CeCILL-A license as circulated by CEA, CNRS and INRIA at the following
 ** URL: "http://www.cecill.info".
 **
 ** As a counterpart to the access to the source code and rights to copy,
 ** modify and redistribute granted by the license, users are provided
 ** only with a limited warranty and the software's author, the holder of
 ** the economic rights, and the successive licensors have only limited
 ** liability.
 **
 ** In this respect, the user's attention is drawn to the risks associated
 ** with loading, using, modifying and/or developing or reproducing the
 ** software by the user in light of its specific status of free software,
 ** that may mean that it is complicated to manipulate, and that also
 ** therefore means that it is reserved for developers and experienced
 ** professionals having in-depth computer knowledge. Users are therefore
 ** encouraged to load and test the software's suitability as regards
 ** their requirements in conditions enabling the security of their
 ** systems and/or data to be ensured and, more generally, to use and
 ** operate it in the same conditions as regards security.
 **
 ** The fact that you are presently reading this means that you have had
 ** knowledge of the CeCILL-A license and that you accept its terms.
 **
 **
 ** ViTE developers are (for version 0.* to 1.0):
 **
 **        - COULOMB Kevin
 **        - FAVERGE Mathieu
 **        - JAZEIX Johnny
 **        - LAGRASSE Olivier
 **        - MARCOUEILLE Jule
 **        - NOISETTE Pascal
 **        - REDONDY Arthur
 **        - VUCHENER Clément
 **
 */
43
#include <iostream>
44
#include <cstring>
45
#include <string>
46
#include "stdio.h"
47 48
#include <map>
#include <list>
49
#include <vector>
50
#include <stack>
51 52 53
#include <algorithm>
/* -- */
#include "common/common.hpp"
54
#include "common/Info.hpp"
55 56 57 58 59 60 61 62
/* -- */
#include "trace/values/Values.hpp"
#include "trace/EntityTypes.hpp"
#include "trace/Entitys.hpp"
#include "trace/tree/Interval.hpp"
#include "trace/tree/Node.hpp"
#include "trace/tree/BinaryTree.hpp"
/* -- */
63

64 65
#include "statistics/Statistic.hpp"
/* -- */
66
#include "trace/Container.hpp"
67
/* -- */
Augustin Degomme's avatar
Augustin Degomme committed
68 69
#ifdef USE_ITC
#include "trace/IntervalOfContainer.hpp"
70 71 72 73
#ifdef BOOST_SERIALIZE
#include "trace/SerializerDispatcher.hpp"
#endif
//#include "trace/SerializerWriter.hpp"
Augustin Degomme's avatar
Augustin Degomme committed
74 75 76 77
//number of Events before reallocation of the array
#define N 1000

#endif
78
using namespace std;
79

80 81 82 83
Container::Container(Name name,
                     Date creation_time,
                     ContainerType *type,
                     Container *parent,
84
                     map<string, Value *> &opt)
85
    : _name(std::move(name)), _creation_time(std::move(creation_time)),
86
      _destruction_time(0.0), _type(type),
87 88
      _parent(parent), _n_states(0), _state_tree(nullptr),
      _n_events(0), _event_tree(nullptr), _n_variables(0),
89
      _extra_fields(std::move(opt))
90 91
{
    if (parent) {
Olivier Lagrasse's avatar
Olivier Lagrasse committed
92
        _depth = parent->_depth+1;
93
    }
94 95 96
    else {
        _depth = 0;
    }
Augustin Degomme's avatar
Augustin Degomme committed
97 98

#ifdef USE_ITC
99
    IntervalOfContainer * itc= new IntervalOfContainer();
Augustin Degomme's avatar
Augustin Degomme committed
100
    _intervalsOfContainer.push_back(itc);
101
    _events=NULL;
Augustin Degomme's avatar
Augustin Degomme committed
102
#endif
103 104
}

105 106
template <class T>
void MyDelete(T *ptr){
107
    delete ptr;
108
}
109

110
Container::~Container()
111
{
112 113 114
    std::for_each(_children.begin(),
                  _children.end(),
                  MyDelete<Container>);
115 116
    _children.clear();
    _children.resize(0);
117
#ifdef USE_ITC
118 119 120
    std::for_each(_intervalsOfContainer.begin(),
                  _intervalsOfContainer.end(),
                  MyDelete<IntervalOfContainer>);
121
    _intervalsOfContainer.clear();
Augustin Degomme's avatar
Augustin Degomme committed
122 123
#endif

124
    // Delete states
125
    // delete _state_tree;
126
    _state_tree = nullptr;
127
    // Delete events
Augustin Degomme's avatar
Augustin Degomme committed
128
    //delete _event_tree;
129
    _event_tree = nullptr;
130
#ifndef USE_ITC
Clément Vuchener's avatar
Clément Vuchener committed
131
    // Delete links
132 133 134 135
    while (!_links.empty()){
        delete _links.front();
        _links.pop_front();
    }
Clément Vuchener's avatar
Clément Vuchener committed
136
    // Delete variables
137 138
    for(auto & _variable : _variables){
        delete _variable.second;
139
    }
Mathieu Faverge's avatar
Mathieu Faverge committed
140
    _variables.clear();
Augustin Degomme's avatar
Augustin Degomme committed
141
#endif
142
}
143 144

void Container::add_child(Container *child) {
145
    if(child != nullptr){
146 147
        _children.push_back(child);
    }
148 149
}

Augustin Degomme's avatar
Augustin Degomme committed
150
void Container::add_view_child(Container *child) {
151
    if(child != nullptr){
152 153
        _view_children.push_back(child);
    }
Augustin Degomme's avatar
Augustin Degomme committed
154 155
}

156
void Container::add_current_state(const Date &end) {
Augustin Degomme's avatar
Augustin Degomme committed
157
#ifdef USE_ITC
158
    State* new_state=_intervalsOfContainer.back()->add_state(
Augustin Degomme's avatar
Augustin Degomme committed
159 160 161 162 163 164 165
        _current_states.top().start,
        end,
        _current_states.top().type,
        _current_states.top().value,
        this,
        _current_states.top().opt);

166
    if (_n_states!=0)
Augustin Degomme's avatar
Augustin Degomme committed
167 168 169 170
        (_intervalsOfContainer.back()->_statechanges[_intervalsOfContainer.back()->_n_statechanges-1]).set_right_state(new_state);
    else {
        _n_states++;
        _intervalsOfContainer.back()->add_statechange(new_state->get_start_time(), NULL, new_state);
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
    }
    if(_intervalsOfContainer.back()->add_statechange(end, new_state,0)==false){
#ifdef BOOST_SERIALIZE
        if(Info::Splitter::split)dump_last_itc();
#endif
        //this interval is full, create a new one
        IntervalOfContainer* itc=new IntervalOfContainer();

        State* first_state=itc->add_state(
            _current_states.top().start,
            end,
            _current_states.top().type,
            _current_states.top().value,
            this,
            _current_states.top().opt);

        _intervalsOfContainer.push_back(itc);
        //add the state to the new intervalOfContainer
        itc->add_statechange(end, first_state,0);
    }
Augustin Degomme's avatar
Augustin Degomme committed
191 192

#else
193
    State *new_state = new State(
Clément Vuchener's avatar
Clément Vuchener committed
194
        _current_states.top().start,
195
        end,
Clément Vuchener's avatar
Clément Vuchener committed
196
        _current_states.top().type,
197
        this,
198 199
        _current_states.top().value,
        _current_states.top().opt);
200

201 202 203 204 205
    // Set the change to the new state
    if (!_states.empty())
        _states.back()->set_right_state(new_state);
    else {
        _n_states++;
206
        _states.push_back(new StateChange(new_state->get_start_time(), nullptr, new_state));
207
    }
208

209 210
    // Set the change from the new state
    _states.push_back(new StateChange(end, new_state));
Augustin Degomme's avatar
Augustin Degomme committed
211
#endif
212
    _n_states++;
213 214
}

215
void Container::set_state(const Date &time, StateType *type, EntityValue *value, map<string, Value *> &opt) {
216

217

Clément Vuchener's avatar
Clément Vuchener committed
218
    if (!_current_states.empty()) {
219
        add_current_state(time);
Clément Vuchener's avatar
Clément Vuchener committed
220 221
        _current_states.pop();
    }
222

Mathieu Faverge's avatar
Mathieu Faverge committed
223 224
    current_state_t t(time, type, value, opt);
    _current_states.push(t);
225 226
}

227
void Container::push_state(const Date &time, StateType *type, EntityValue *value, map<string, Value *> &opt) {
Clément Vuchener's avatar
Clément Vuchener committed
228
    if (!_current_states.empty())
229
        add_current_state(time);
230 231

    current_state_t t(time, type, value, opt);
Mathieu Faverge's avatar
Mathieu Faverge committed
232
    _current_states.push(t);
233 234
}

235
void Container::pop_state(const Date &time) {
Clément Vuchener's avatar
Clément Vuchener committed
236
    if (!_current_states.empty()) {
237
        add_current_state(time);
Clément Vuchener's avatar
Clément Vuchener committed
238
        _current_states.pop();
239
    }
240

Clément Vuchener's avatar
Clément Vuchener committed
241 242
    if (!_current_states.empty()) {
        _current_states.top().start = time;
243 244
    }
}
245

246
void Container::reset_state(const Date &time) {
247 248 249 250 251 252 253 254
    if (!_current_states.empty()) {
        add_current_state(time);
        while( !_current_states.empty() ){
            _current_states.pop();
        }
    }
}

255
void Container::new_event(const Date &time, EventType *type, EntityValue *value, map<string, Value *> &opt) {
Augustin Degomme's avatar
Augustin Degomme committed
256
#ifdef USE_ITC
257
    _intervalsOfContainer.back()->add_event(time,  type,this, value, opt);
Augustin Degomme's avatar
Augustin Degomme committed
258
#else
259
    _events.push_back(new Event(time, type, this, value, opt));
260
    _n_events++;
Augustin Degomme's avatar
Augustin Degomme committed
261
#endif
262
}
Clément Vuchener's avatar
Clément Vuchener committed
263

264

265 266
void Container::start_link(const Date &time, LinkType *type, Container *source,
                           EntityValue *value, const String &key, map<std::string, Value *> &opt)
267
{
268 269
    map<String, std::list<current_link_t>, String::less_than>::iterator i = _current_received_links.find(key);

270
    if (i == _current_received_links.end())
271
    {
272
        //no message is to be ended, just push the new one in the list
273
        current_link_t t(time, type, source, value, opt);
274 275 276
        map<String, std::list<current_link_t>, String::less_than>::iterator it = _current_sent_links.find(key);
        if (it == _current_sent_links.end()) {
            //printf ("received a send order for a new key\n");
277 278 279 280 281 282 283 284 285 286
            _current_sent_links[key] = std::list<current_link_t>();
            _current_sent_links[key].push_back(t);
        }
        else{
            //printf ("received a send order for an existing key\n");
            _current_sent_links[key].push_back(t);
        }

    }
    else
287
    {
288 289
        //if the key exists, we need to end a message, the first one correponnding to the key
        current_link_t* mess = &(*i).second.front();
290 291 292 293
        for (map<string, Value *>::const_iterator j = opt.begin();
             j != opt.end(); j++)
        {
            mess->opt[(*j).first] = (*j).second;
294
        }
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
#ifdef USE_ITC
        if( _intervalsOfContainer.back()->add_link(time,
                                                   mess->start,
                                                   type,
                                                   this,
                                                   source,
                                                   mess->source,
                                                   value,
                                                   mess->opt)==false){
#ifdef BOOST_SERIALIZE
            if(Info::Splitter::split)dump_last_itc();
#endif
            //this interval is full, create a new one
            IntervalOfContainer* itc=new IntervalOfContainer();
            _intervalsOfContainer.push_back(itc);
            //add the state to the new intervalOfContainer
            _intervalsOfContainer.back()->add_link(time,
                                                   mess->start,
                                                   type,
                                                   this,
                                                   source,
                                                   mess->source,
                                                   value,
                                                   mess->opt);
        }
#else
        _links.push_back(new Link(
                             time,
                             mess->start,
                             type,
                             this,
                             source,
                             mess->source,
                             value,
                             mess->opt));
#endif
331 332
        //remove the first element from the list for that key
        (*i).second.pop_front();
333

334
        if ((*i).second.empty())_current_received_links.erase(i);
Augustin Degomme's avatar
Augustin Degomme committed
335

336
    }
Clément Vuchener's avatar
Clément Vuchener committed
337 338
}

339
void Container::end_link(const Date &time, Container *destination, const String &key, map<string, Value *> &opt) {
340 341

    map<String, std::list<current_link_t>, String::less_than>::iterator i = _current_sent_links.find(key);
342
    if (i == _current_sent_links.end())
343
    {
344
        //no message is to be ended, just push the new one in the list
345
        current_link_t t(time, nullptr, destination, nullptr, opt);
346

347 348 349
        map<String, std::list<current_link_t>, String::less_than>::iterator it = _current_received_links.find(key);
        if (it == _current_received_links.end()) {
            //printf ("received a receive order for a new key\n");
350 351 352 353 354 355 356
            _current_received_links[key] = std::list<current_link_t>();
            _current_received_links[key].push_back(t);
        }
        else{
            //printf ("received a receive order for an existing key\n");
            _current_received_links[key].push_back(t);
        }
357 358 359
    }
    else
    {
360

361 362 363
        //if the key exists, we need to end a message, the first one correponnding to the key
        current_link_t* mess = &(*i).second.front();

364 365 366 367 368

        for (map<string, Value *>::const_iterator j = opt.begin();
             j != opt.end(); j++)
        {
            mess->opt[(*j).first] = (*j).second;
369
        }
370 371 372 373 374 375 376 377 378 379 380 381
#ifdef USE_ITC
        if(_intervalsOfContainer.back()->add_link(mess->start,
                                                  time,
                                                  mess->type,
                                                  this,
                                                  mess->source,
                                                  destination,
                                                  mess->value,
                                                  mess->opt)==false){
#ifdef BOOST_SERIALIZE
            if(Info::Splitter::split)dump_last_itc();
#endif
Augustin Degomme's avatar
Augustin Degomme committed
382
            //this interval is full, create a new one
383 384
            IntervalOfContainer* itc=new IntervalOfContainer();
            _intervalsOfContainer.push_back(itc);
Augustin Degomme's avatar
Augustin Degomme committed
385
            //add the state to the new intervalOfContainer
386
            _intervalsOfContainer.back()->add_link(mess->start,
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406
                                                   time,
                                                   mess->type,
                                                   this,
                                                   mess->source,
                                                   destination,
                                                   mess->value,
                                                   mess->opt);
        }
#else
        _links.push_back(new Link(
                             mess->start,
                             time,
                             mess->type,
                             this,
                             mess->source,
                             destination,
                             mess->value,
                             mess->opt));
#endif

407 408
        //remove the first element from the list for that key
        (*i).second.pop_front();
409

410
        if ((*i).second.empty())_current_sent_links.erase(i);
411
    }
Clément Vuchener's avatar
Clément Vuchener committed
412
}
Clément Vuchener's avatar
Clément Vuchener committed
413

414
void Container::set_variable(const Date &time, VariableType *type, const Double &value) {
Augustin Degomme's avatar
Augustin Degomme committed
415
#ifdef USE_ITC
416
    int i=0;
Augustin Degomme's avatar
Augustin Degomme committed
417
    IntervalOfContainer* itc= _intervalsOfContainer.back();
418
    for(i=0;i< itc->_n_variables && itc->_variables[i].get_type()!=type; i++) ;
Augustin Degomme's avatar
Augustin Degomme committed
419 420

    if (i==itc->_n_variables) {
421
        itc->set_variable(this, type);
Augustin Degomme's avatar
Augustin Degomme committed
422 423 424 425 426
        itc->_variables[i].add_value(time, value);
    }
    else {
        itc->_variables[i].add_value(time, value);
    }
427

Augustin Degomme's avatar
Augustin Degomme committed
428
#else
429
    map<VariableType *, Variable *>::iterator i = _variables.find(type);
Clément Vuchener's avatar
Clément Vuchener committed
430
    if (i == _variables.end()) {
431
        _variables[type] = new Variable(this, type);
432
        _variables[type]->add_value(time, value);
Clément Vuchener's avatar
Clément Vuchener committed
433 434 435
        _n_variables++;
    }
    else {
436
        (*i).second->add_value(time, value);
Clément Vuchener's avatar
Clément Vuchener committed
437
    }
Augustin Degomme's avatar
Augustin Degomme committed
438
#endif
Clément Vuchener's avatar
Clément Vuchener committed
439 440
}

441
void Container::add_variable(const Date &time, VariableType *type, const Double &value) {
Augustin Degomme's avatar
Augustin Degomme committed
442
#ifdef USE_ITC
443
    int i=0;
Augustin Degomme's avatar
Augustin Degomme committed
444
    IntervalOfContainer* itc= _intervalsOfContainer.back();
445
    for(i=0;i< itc->_n_variables && itc->_variables[i].get_type()!=type; i++) ;
Augustin Degomme's avatar
Augustin Degomme committed
446 447

    if (i==itc->_n_variables) {
448 449

        itc->set_variable(this, type);
Augustin Degomme's avatar
Augustin Degomme committed
450 451 452 453 454 455
        itc->_variables[i].add_value(time, value);
    }
    else {
        itc->_variables[i].add_value(time,itc->_variables[i].get_last_value()+ value);
    }
#else
456
    map<VariableType *, Variable *>::iterator i = _variables.find(type);
Clément Vuchener's avatar
Clément Vuchener committed
457
    if (i == _variables.end()) {
458
        _variables[type] = new Variable(this, type);
459
        _variables[type]->add_value(time, value);
Clément Vuchener's avatar
Clément Vuchener committed
460 461 462
        _n_variables++;
    }
    else {
463
        (*i).second->add_value(time, (*i).second->get_last_value() + value);
Clément Vuchener's avatar
Clément Vuchener committed
464
    }
Augustin Degomme's avatar
Augustin Degomme committed
465
#endif
Clément Vuchener's avatar
Clément Vuchener committed
466 467
}

468
void Container::sub_variable(const Date &time, VariableType *type, const Double &value) {
Augustin Degomme's avatar
Augustin Degomme committed
469
#ifdef USE_ITC
470
    int i=0;
Augustin Degomme's avatar
Augustin Degomme committed
471
    IntervalOfContainer* itc= _intervalsOfContainer.back();
472
    for(i=0;i< itc->_n_variables && itc->_variables[i].get_type()!=type; i++) ;
Augustin Degomme's avatar
Augustin Degomme committed
473 474

    if (i==itc->_n_variables) {
475
        itc->set_variable(this, type);
Augustin Degomme's avatar
Augustin Degomme committed
476 477 478 479 480 481
        itc->_variables[i].add_value(time, value);
    }
    else {
        itc->_variables[i].add_value(time,itc->_variables[i].get_last_value()- value);
    }
#else
482
    map<VariableType *, Variable *>::iterator i = _variables.find(type);
Clément Vuchener's avatar
Clément Vuchener committed
483
    if (i == _variables.end()) {
484
        _variables[type] = new Variable(this, type);
485
        _variables[type]->add_value(time, -value);
Clément Vuchener's avatar
Clément Vuchener committed
486 487 488
        _n_variables++;
    }
    else {
489
        (*i).second->add_value(time, (*i).second->get_last_value() - value);
Clément Vuchener's avatar
Clément Vuchener committed
490
    }
Augustin Degomme's avatar
Augustin Degomme committed
491
#endif
Clément Vuchener's avatar
Clément Vuchener committed
492
}
Mathieu Faverge's avatar
Mathieu Faverge committed
493

Mathieu Faverge's avatar
Mathieu Faverge committed
494 495 496
Name
Container::get_Name() const
{
497 498
    return _name;
}
Mathieu Faverge's avatar
Mathieu Faverge committed
499

Mathieu Faverge's avatar
Mathieu Faverge committed
500 501 502 503 504 505 506 507 508 509 510 511
std::string
Container::get_name() const
{
    return _name.get_name();
}

std::string
Container::get_alias() const
{
    return _name.get_alias();
}

512 513 514
const Container *Container::get_parent() const {
    return _parent;
}
Mathieu Faverge's avatar
Mathieu Faverge committed
515

516 517 518
const ContainerType *Container::get_type() const {
    return _type;
}
Mathieu Faverge's avatar
Mathieu Faverge committed
519

520
const Container::Vector * Container::get_children() const {
521
    return &_children;
522
}
Mathieu Faverge's avatar
Mathieu Faverge committed
523

Augustin Degomme's avatar
Augustin Degomme committed
524 525 526 527 528 529 530 531 532 533 534 535
const Container::Vector * Container::get_view_children() const {
    return &_view_children;
}

void Container::clear_children() {
    _children.clear();
}

void Container::clear_view_children() {
    _view_children.clear();
}

536
Date Container::get_creation_time() const {
537 538
    return _creation_time;
}
Mathieu Faverge's avatar
Mathieu Faverge committed
539

540
Date Container::get_destruction_time() const {
541 542
    return _destruction_time;
}
Mathieu Faverge's avatar
Mathieu Faverge committed
543

544
StateChange::Tree *Container::get_states() const {
545
    return _state_tree;
546
}
Clément Vuchener's avatar
Clément Vuchener committed
547

548
Event::Tree *Container::get_events() const {
549
    return _event_tree;
Clément Vuchener's avatar
Clément Vuchener committed
550 551
}

552
const Link::Vector *Container::get_links() const {
Clément Vuchener's avatar
Clément Vuchener committed
553 554 555
    return &_links;
}

556
const map<VariableType *, Variable *> *Container::get_variables() const {
Clément Vuchener's avatar
Clément Vuchener committed
557 558 559
    return &_variables;
}

560
const map<string, Value *> *Container::get_extra_fields() const {
561 562 563
    return &_extra_fields;
}

564
unsigned int Container::get_variable_number() const {
Clément Vuchener's avatar
Clément Vuchener committed
565
    return _n_variables;
Clément Vuchener's avatar
Clément Vuchener committed
566
}
567

568 569 570 571 572
unsigned int Container::get_state_number() const {
    return _n_states;
}

unsigned int Container::get_event_number() const {
573 574 575
    return _n_events;
}

576 577 578 579 580 581 582 583
#ifdef USE_ITC


const std::list<IntervalOfContainer* >* Container::get_intervalsOfContainer() const{
    return &_intervalsOfContainer;
}


584 585 586 587 588 589 590 591 592 593 594 595 596
void Container::set_intervalsOfContainer(std::list<IntervalOfContainer* >* itc) {
    _intervalsOfContainer.assign(itc->begin(),itc->end());

}

#ifdef BOOST_SERIALIZE
/*!
 * \fn dump(std::string path, std::filename) const
 * \brief Dump all IntervalOfContainers to disk
 */
void Container::dump(std::string path, std::string filename,const Date &time){

    if (_destruction_time.get_value() == 0.0)
597
        destroy(time);
598

599 600
    int _uid=Serializer<Container>::Instance().getUid(this);
    int n=0;
601 602 603 604 605 606 607 608 609 610 611 612

    list<IntervalOfContainer* > ::const_iterator it_end1= _intervalsOfContainer.end();
    for(list<IntervalOfContainer *>::const_iterator it = _intervalsOfContainer.begin() ;
        it != it_end1;
        it++){

        if( ( *it)->_loaded ==true){
            char* name=(char*)malloc(512*sizeof(char*));
            sprintf(name, "%s/%s/%d_%d",path.c_str(),filename.c_str(),_uid ,n);
            (*it)->_loaded=false;
            SerializerDispatcher::Instance().dump(*it, name);

613
        }
614 615 616 617 618 619 620 621 622 623 624 625 626 627
        n++;
    }
}

/*!
 * \fn dump_last_itc() const
 * \brief Dumps the last finished IntervalOfContainer to disk
 */
void Container::dump_last_itc(){
    int _uid=Serializer<Container>::Instance().getUid(this);
    if(_intervalsOfContainer.back()->_loaded==true){
        char* name=(char*)malloc(512*sizeof(char));//free in the dump_on_disk
        sprintf(name, "%s/%s/%d_%d",Info::Splitter::path.c_str(),Info::Splitter::filename.c_str(),_uid ,(int)_intervalsOfContainer.size()-1);
        SerializerDispatcher::Instance().dump(_intervalsOfContainer.back(), name);
628
    }
629 630
}
#endif
631
#endif
632

633
void Container::destroy(const Date &time) {
Kevin Coulomb's avatar
Kevin Coulomb committed
634 635 636 637
    if (!_current_states.empty()) {
        add_current_state(time);
        _current_states.pop();
    }
638 639 640
    _destruction_time = time;
}

641 642 643 644

#ifdef BOOST_SERIALIZE

void Container::loadItcInside(Interval* splitInterval){
645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690
    _states.clear();
    _links.clear();
    _variables.clear();
    delete _events;
    _n_states=0;
    _n_events=0;
    _events=NULL;


    bool loading=true;
    int _uid=Serializer<Container>::Instance().getUid(this);
    //Info::Render::_x_max_visible= Info::Render::_x_max_visible==0.0 ? 10000000 : Info::Render::_x_max_visible;

    // printf("min: %lf, max: %lf\n", Info::Render::_x_min_visible, Info::Render::_x_max_visible);

    //test if we are past the last element of the container -> if yes, load its last itc

    int i=0;



    list<IntervalOfContainer* > ::const_iterator it_end1= _intervalsOfContainer.end();
    for(list<IntervalOfContainer *>::const_iterator it = _intervalsOfContainer.begin() ;
        it != it_end1;
        it++){

        if(((*it)->_beginning<=splitInterval->_left && (*it)->_end>=splitInterval->_left) ||
           ((*it)->_beginning>=splitInterval->_left && (*it)->_beginning<=splitInterval->_right)) {

            if((*it)->_loaded==false){
                char* name=(char*)malloc(512*sizeof(char));
                sprintf(name, "%s/%d_%d",Info::Splitter::path.c_str(),_uid ,i);
                //printf("%s : need to load itc beginning at %lf and finishing at %lf, file %s \n", _name.to_string().c_str(), (*it)->_beginning.get_value(), (*it)->_end.get_value(), name);
                SerializerDispatcher::Instance().load(*it, name);
                //loading=(*it)->retrieve(name);
                if(loading==true)(*it)->_loaded=true;
                // else printf("bug de loading\n");

            }

        }else{
            //if the itc is loaded, unload it !
            if((*it)->_loaded==true){
                (*it)->unload();
                (*it)->_loaded=false;
                // printf("%s :unload itc beginning at %lf and finishing at %lf \n", _name.to_string().c_str(), (*it)->_beginning.get_value(), (*it)->_end.get_value());
691
            }
692 693 694 695 696 697

        }
        i++;



698
    }
699 700 701 702 703 704

    //  free(name);


}

705 706
void Container::loadPreview(){

707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739
    _n_states=0;
    _n_events=0;
    _events=NULL;
    StateType* type=new StateType(Name(String("Aggregated Data")), _type,  map<std::string, Value *>());
    list<IntervalOfContainer* > ::const_iterator it_end= _intervalsOfContainer.end();
    for(list<IntervalOfContainer *>::const_iterator it = _intervalsOfContainer.begin() ;
        it != it_end;
        it++){
        if((*it)->_states_values_map!=NULL && (*it)->_states_values_map->size()!=0){

            map<EntityValue*, double>::iterator it2;
            double begin = (*it)->_beginning.get_value();
            // show content:

            for ( it2=(*it)->_states_values_map->begin() ; it2 != (*it)->_states_values_map->end(); it2++ ){
                State* t= new State(begin, begin + (*it2).second , type, this,(*it2).first,  map<std::string, Value *>());

                if(_n_states==0){
                    StateChange* sc=new StateChange(begin, NULL, t);
                    _states.push_back(sc);
                    _n_states++;
                }else{
                    _states.back()->set_right_state(t);

                }
                begin += (*it2).second;
                StateChange* sc=new StateChange(begin,t, NULL);

                _states.push_back(sc);
                _n_states++;
            }
        }

740
    }
741 742 743 744 745 746 747

    /*   if(_n_events==0)_event_tree=NULL;
     else _event_tree = new BinaryTree<Event>(_events, _n_events);

     if(_n_states==0)_state_tree=NULL;
     else _state_tree = new BinaryTree<StateChange>(_states,_n_states);*/

748 749 750 751
}

#endif

752
void Container::finish(const Date &time) {
Augustin Degomme's avatar
Augustin Degomme committed
753 754

#ifdef USE_ITC
755 756 757 758 759 760 761 762 763 764 765 766
    //	if( Info::Splitter::split==false && Info::Splitter::preview ==false){

    //boolean to check if the intervalOfcontainer is fully inside the visible interval, in order not to check each state if yes
    //		bool fully_contained=false;

    if(_event_tree)delete _event_tree;
    if(_state_tree!=NULL)delete _state_tree;
    _n_variables=0;
    _event_tree=NULL;
    _state_tree=NULL;

    if(Info::Splitter::load_splitted==false){
767
        if (_destruction_time.get_value() == 0.0)
768 769
            destroy(time);

Augustin Degomme's avatar
Augustin Degomme committed
770

771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801

        _states.clear();
        _links.clear();
        _variables.clear();
        delete _events;
        _n_states=0;
        _n_events=0;
        _n_variables=0;
        _events=NULL;
    }

    //iterates through all intervalOfContainers
    list<IntervalOfContainer* > ::const_iterator it_end= _intervalsOfContainer.end();
    for(list<IntervalOfContainer *>::const_iterator it = _intervalsOfContainer.begin() ;
        it != it_end;
        it++){
        //only work with intervalOfContainers which are loaded in memory
        if(((*it)->_loaded)==true){
            //add all statechanges to the global one
            if((*it)->_n_statechanges!=0){
                for(int i=0; i< (*it)->_n_statechanges; i++){
                    _states.push_back(&((*it)->_statechanges[i]));
                    _n_states++;
                }
            }

            if((*it)->_n_events!=0)
                for(int i=0; i< (*it)->_n_events; i++){
                    if(_events==NULL){
                        _events=(Event**)malloc((_n_events+N)*sizeof(Event*));
                        memset(_events, 0, (_n_events+N)*sizeof(Event*));
Augustin Degomme's avatar
Augustin Degomme committed
802
                    }
803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838
                    _events[_n_events]=(&((*it)->_events[i]));
                    _n_events++;
                    if(_n_events%N==0)_events=(Event**)realloc(_events,(_n_events+N)*sizeof(Event*));
                }

            if((*it)->_n_links!=0)
                for(int i=0; i< (*it)->_n_links; i++){
                    _links.push_back(&((*it)->_links[i]));
                }

            if((*it)->_n_variables!=0)
                for(int i=0; i< (*it)->_n_variables; i++){
                    VariableType* type=((*it)->_variables[i]).get_type();

                    if (_variables.find(type)==_variables.end()){
                        _variables.insert(std::pair<VariableType*, Variable*>(type,&((*it)->_variables[i])));

                        //printf("%s inserting variable %s %d\n", this->get_name().to_string().c_str(),((*it)->_variables[i]).get_type()->get_name().to_string().c_str(), ((*it)->_variables[i]).get_values()->size());
                        _n_variables++;
                    }else{
                        if(((*it)->_variables[i]).get_values()!=NULL){
                            /* int nb_items=0;
                             for(nb_items=0; nb_items<((*it)->_variables[i]).get_values()->size(); nb_items++){
                             pair<Date, Double> t= ((*it)->_variables[i]).get_values()->[nb_items];
                             printf("add first %lf value %lf\n", t.first.get_value(), t.second.get_value());
                             _variables[type]->add_value(t.first, t.second);

                             }*/
                            std::list<std::pair<Date, Double> >::const_iterator  it_end2=((*it)->_variables[i]).get_values()->end();
                            std::list<std::pair<Date, Double> >::const_iterator  it_val = ((*it)->_variables[i]).get_values()->begin();
                            for(;
                                it_val!=it_end2 ;
                                it_val++){
                                pair<Date, Double> t= *it_val;

                                _variables[type]->add_value(t.first, t.second);
Augustin Degomme's avatar
Augustin Degomme committed
839
                            }
840
                        }
Augustin Degomme's avatar
Augustin Degomme committed
841
                    }
842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860
                }
        }


        //  }

        /*if(_n_states!=0 && (_states.back()->get_right_state()!=NULL)) {
         //add a new state at the end if not already presently
         StateChange* end = new StateChange(_destruction_time,_states.back()->get_right_state(), NULL );
         _states.push_back(end);
         _n_states++;

         }*/

    }
    if(_n_events==0)_event_tree=NULL;
    else _event_tree = new BinaryTree<Event>(_events, _n_events);

    if(_n_states==0)_state_tree=NULL;
Augustin Degomme's avatar
Augustin Degomme committed
861 862
    else _state_tree = new BinaryTree<StateChange>(_states,_n_states);
#else
863 864
    if (_destruction_time.get_value() == 0.0)
        destroy(time);
865 866
    _event_tree = new Event::Tree(_events, _n_events);
    _state_tree = new StateChange::Tree(_states,_n_states);
Augustin Degomme's avatar
Augustin Degomme committed
867
#endif
868 869 870
}


871

Mathieu Faverge's avatar
Mathieu Faverge committed
872
void Container::fill_stat( Statistic * stat, Interval I ) {
873

874
    // If the container is a proc -> no child container
875 876
    if(this->get_children()->empty()) {
        browse_stat_link(this,stat,I);
877
    }
878
    Node<StateChange>  *sauv = nullptr;
Mathieu Faverge's avatar
Mathieu Faverge committed
879
    Node<StateChange> **prev = &sauv;
880 881
    Node<StateChange>  *node = nullptr;
    if( this->get_states() != nullptr) {
Mathieu Faverge's avatar
Mathieu Faverge committed
882 883
        node = this->get_states()->get_root();
    }
Kevin Coulomb's avatar
Kevin Coulomb committed
884
    double tmp;
Kevin Coulomb's avatar
Kevin Coulomb committed
885 886
    browse_stat_state(node,stat,I,prev);
    // To add the first partial state of the interval
Mathieu Faverge's avatar
Mathieu Faverge committed
887 888 889 890 891 892
    if( sauv &&
        sauv->get_element() &&
        sauv->get_element()->get_right_state() )
    {
        if( sauv->get_element()->get_right_state()->get_end_time() > I._left)
        {
Kevin Coulomb's avatar
Kevin Coulomb committed
893
            if( sauv->get_element()->get_right_state()->get_end_time() > I._right)
Mathieu Faverge's avatar
Mathieu Faverge committed
894
            {
Kevin Coulomb's avatar
Kevin Coulomb committed
895
                tmp = I._right - I._left;
Mathieu Faverge's avatar
Mathieu Faverge committed
896
            }
Kevin Coulomb's avatar
Kevin Coulomb committed
897
            else
Mathieu Faverge's avatar
Mathieu Faverge committed
898
            {
Kevin Coulomb's avatar
Kevin Coulomb committed
899
                tmp = sauv->get_element()->get_right_state()->get_end_time() - I._left;
Mathieu Faverge's avatar
Mathieu Faverge committed
900
            }
Kevin Coulomb's avatar
Kevin Coulomb committed
901 902

            stat->add_state(sauv->get_element()->get_right_state()->get_value(),tmp);
Kevin Coulomb's avatar
Kevin Coulomb committed
903 904 905
        }
    }

906
    stat->set_nb_event(this->get_event_number());
907 908 909
}


Kevin Coulomb's avatar
Kevin Coulomb committed
910
void browse_stat_state(Node<StateChange> * node, Statistic * stats, Interval I, Node<StateChange>** prev){
911

912 913 914
    if( ! node ||
        ! node->get_element())
        return;
915

916
    // If the node is in the interval
917
    if(node->get_element()->get_time() <= I._right &&
918
       node->get_element()->get_time() >= I._left){
919

920
        if(node->get_left_child())
Kevin Coulomb's avatar
Kevin Coulomb committed
921
            browse_stat_state(node->get_left_child(),stats,I,prev);
922
        if(node->get_right_child())
Kevin Coulomb's avatar
Kevin Coulomb committed
923
            browse_stat_state(node->get_right_child(),stats,I,prev);
924

925

926
        //Add the right state of the state change
Kevin Coulomb's avatar
Kevin Coulomb committed
927
        if(node->get_element()->get_right_state())
928 929 930
        {
            if(node->get_element()->get_right_state()->get_end_time() < I._right){
                stats->add_state(node->get_element()->get_right_state()->get_value(),node->get_element()->get_right_state()->get_duration());
Kevin Coulomb's avatar
Kevin Coulomb committed
931 932
            }
            else{
933
                stats->add_state(node->get_element()->get_right_state()->get_value(),I._right - node->get_element()->get_right_state()->get_start_time());
Kevin Coulomb's avatar
Kevin Coulomb committed
934
            }
935
        }
936
    }
937

938 939 940
    // Else if after the interval
    else if(node->get_element()->get_time() > I._right ){
        if(node->get_left_child()){
Kevin Coulomb's avatar
Kevin Coulomb committed
941
            browse_stat_state(node->get_left_child(),stats,I,prev);
942 943
        }
    }
944

Kevin Coulomb's avatar
Kevin Coulomb committed
945 946 947 948 949 950
    else{        // Else node is before the interval
        if( !(*prev) ){
            *prev = node;
        }

        if(node->get_element()->get_right_state()){
951
            if(node->get_element()->get_right_state()->get_start_time() >=
Kevin Coulomb's avatar
Kevin Coulomb committed
952 953
               (*prev)->get_element()->get_right_state()->get_start_time()){
                *prev = node;
Kevin Coulomb's avatar
Kevin Coulomb committed
954
            }
Kevin Coulomb's avatar
Kevin Coulomb committed
955 956 957
        }

        if(node->get_right_child()){
Kevin Coulomb's avatar
Kevin Coulomb committed
958
            browse_stat_state(node->get_right_child(),stats,I,prev);
959 960
        }
    }
961
}
962

963

Kevin Coulomb's avatar
Kevin Coulomb committed
964 965 966
void browse_stat_link(const Container * cont, Statistic * S, Interval I){
    if(!cont)
        return;
967 968

    Link::VectorIt const  &it_end = cont->get_links()->end();
Kevin Coulomb's avatar
Kevin Coulomb committed
969
    for(list<Link *>::const_iterator it = cont->get_links()->begin() ;
970
        it != it_end;
Kevin Coulomb's avatar
Kevin Coulomb committed
971 972 973 974 975 976 977 978 979 980
        it++){
        if( (*it)->get_source() == cont  &&
            (*it)->get_destination() != cont){
            S->add_link(cont);
        }
        else if((*it)->get_source() != cont  &&
                (*it)->get_destination() == cont){
            S->add_link(cont);
        }
    }
981
    browse_stat_link(cont->get_parent(), S, std::move(I));
982 983
}

Olivier Lagrasse's avatar
Olivier Lagrasse committed
984
int Container::get_depth(){
985
    return _depth;
Olivier Lagrasse's avatar
Olivier Lagrasse committed
986
}