From 172244b353ec9b68effd119026b01a4123fe5bdf Mon Sep 17 00:00:00 2001
From: Augustin Degomme <augustin.degomme@imag.fr>
Date: Mon, 13 Jun 2011 20:30:17 +0000
Subject: [PATCH] feature : add IntervalOfContainers which are described in
 https://gforge.inria.fr/plugins/wiki/index.php?NewDataStructPage&id=1596&type=g
 A new IntervalOfContainer is built only when a certain (10000 for the moment)
 number of StateChanges or Links are attached to it. (initially only
 StateChanges were taken into account, but Links are created in parent
 containers without States, so they were all allocated in the same
 IntevalOfContainers, making them huge).

This is not activated right now by default, but can be turned on by setting the flag USE_ITC before compiling to perform tests.
---
 src/CMakeLists.txt            |   2 +
 src/src.pro                   |   2 +
 src/trace/Container.cpp       | 278 ++++++++++++++++++++++++++++++++--
 src/trace/Container.hpp       |  10 ++
 src/trace/DrawTrace.hpp       |  69 ++++++---
 src/trace/Entity.cpp          |  10 +-
 src/trace/Entity.hpp          |   2 +
 src/trace/EntityType.cpp      |  15 +-
 src/trace/StateChange.cpp     |   8 +
 src/trace/StateChange.hpp     |   2 +
 src/trace/Variable.cpp        |   2 +-
 src/trace/Variable.hpp        |   2 +-
 src/trace/tree/BinaryTree.hpp | 135 +++++++++++++++++
 13 files changed, 496 insertions(+), 41 deletions(-)

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 764b2449..5558f59b 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -81,6 +81,7 @@ SET(VITE_HDRS
   trace/DrawTrace.hpp
   trace/DrawTree.hpp
   trace/Trace.hpp
+  trace/IntervalOfContainer.hpp
   # Render headers
   render/Palette.hpp
   render/Render.hpp
@@ -176,6 +177,7 @@ SET(VITE_SRCS
   trace/Variable.cpp
   trace/Container.cpp
   trace/Trace.cpp
+  trace/IntervalOfContainer.cpp
   # Render code files
   render/Palette.cpp
   render/Geometry.cpp
diff --git a/src/src.pro b/src/src.pro
index 94be4a71..2cb9b311 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -142,6 +142,7 @@ HEADERS += common/common.hpp  \
            trace/tree/BinaryTree.hpp \
            trace/tree/Node.hpp       \
            trace/tree/Interval.hpp   \
+		   trace/IntervalOfContainer.hpp
 # Statistics headers
            statistics/Stats_window.hpp \
            statistics/Statistic.hpp    \
@@ -194,6 +195,7 @@ SOURCES += common/Message.cpp \
            trace/Container.cpp 	    \
            trace/tree/Interval.cpp  \
            trace/Trace.cpp 	    \
+		   trace/IntervalOfContainer.cpp\
 # Parser code files
            parser/Parser.cpp               \
            parser/ParserFactory.cpp        \
diff --git a/src/trace/Container.cpp b/src/trace/Container.cpp
index 16736635..7c7f05f4 100644
--- a/src/trace/Container.cpp
+++ b/src/trace/Container.cpp
@@ -62,6 +62,14 @@
 /* -- */
 #include "trace/Container.hpp"
 /* -- */
+#ifdef USE_ITC
+#include "trace/IntervalOfContainer.hpp"
+
+
+//number of Events before reallocation of the array
+#define N 1000
+
+#endif
 using namespace std;
 
 
@@ -74,6 +82,11 @@ Container::Container(Name name, Date creation_time, ContainerType *type, Contain
         _depth = parent->_depth+1;
     else
         _depth=0;
+
+#ifdef USE_ITC
+	IntervalOfContainer * itc= new IntervalOfContainer();
+    _intervalsOfContainer.push_back(itc);
+#endif
 }
 
 template <class T>
@@ -88,14 +101,21 @@ Container::~Container() {
 		  MyDelete<Container>);
     _children.clear();
     _children.resize(0);
-    
+    #ifdef USE_ITC
+	std::for_each(_intervalsOfContainer.begin(), 
+		  _intervalsOfContainer.end(), 
+		  MyDelete<IntervalOfContainer>);
+	_intervalsOfContainer.clear();
+	
+#endif
+
     // Delete states
-    delete _state_tree;
+   // delete _state_tree;
     _state_tree = NULL;
     // Delete events
-    delete _event_tree;
+    //delete _event_tree;
     _event_tree = NULL;
-    
+ #ifndef USE_ITC
     // Delete links
     while (!_links.empty()){
         delete _links.front();
@@ -108,6 +128,9 @@ Container::~Container() {
         delete (*it).second;
     }
     _variables.clear();
+#endif
+
+
 }
 
 void Container::add_child(Container *child) {
@@ -123,7 +146,42 @@ void Container::add_view_child(Container *child) {
 }
 
 void Container::add_current_state(Date end) {
-    State *new_state = new State(
+#ifdef USE_ITC
+	State* new_state=_intervalsOfContainer.back()->add_state(
+        _current_states.top().start,
+        end,
+        _current_states.top().type,
+        _current_states.top().value,
+        this,
+        _current_states.top().opt);
+
+	if (_n_states!=0)
+        (_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);
+	}
+		if(_intervalsOfContainer.back()->add_statechange(end, new_state,0)==false){
+            
+				//dump_last_itc();
+                //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);
+            }
+
+#else
+	State *new_state = new State(
         _current_states.top().start,
         end,
         _current_states.top().type,
@@ -141,6 +199,7 @@ void Container::add_current_state(Date end) {
   
     // Set the change from the new state
     _states.push_back(new StateChange(end, new_state));
+#endif
     _n_states++;
 }
 
@@ -174,8 +233,12 @@ void Container::pop_state(Date time) {
 }
 
 void Container::new_event(Date time, EventType *type, EntityValue *value, map<string, Value *> &opt) {
+#ifdef USE_ITC
+	_intervalsOfContainer.back()->add_event(time,  type,this, value, opt);
+#else
     _events.push_back(new Event(time, type, this, value, opt));
     _n_events++;
+#endif
 }
 
 
@@ -195,7 +258,30 @@ void Container::start_link(Date time, LinkType *type, Container *source,
 	{
 	    (*i).second.opt[(*j).first] = (*j).second;
         }
-
+#ifdef USE_ITC
+	if( _intervalsOfContainer.back()->add_link(time,
+			             (*i).second.start,
+			             type,
+			             this,
+			             source,
+			             (*i).second.source,
+			             value,
+			             ((*i).second).opt)==false){
+				//dump_last_itc();
+                //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,
+			             (*i).second.start,
+			             type,
+			             this,
+			             source,
+			             (*i).second.source,
+			             value,
+			             ((*i).second).opt);
+            }
+#else
 	_links.push_back(new Link(
 			     time,
 			     (*i).second.start,
@@ -205,7 +291,9 @@ void Container::start_link(Date time, LinkType *type, Container *source,
 			     (*i).second.source,
 			     value,
 			     (*i).second.opt));
+#endif
 	_current_links.erase(i);
+
     }
 }
 
@@ -223,7 +311,30 @@ void Container::end_link(Date time, Container *destination, String key, map<stri
 	{
 	    (*i).second.opt[(*j).first] = (*j).second;
         }
-
+#ifdef USE_ITC
+	if(_intervalsOfContainer.back()->add_link((*i).second.start,
+			     time,
+			     (*i).second.type,
+			     this,
+			     (*i).second.source,
+			     destination,
+			     (*i).second.value,
+			     (*i).second.opt)==false){
+				//dump_last_itc();
+            //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((*i).second.start,
+			     time,
+			     (*i).second.type,
+			     this,
+			     (*i).second.source,
+			     destination,
+			     (*i).second.value,
+			     (*i).second.opt);
+            }
+#else
 	_links.push_back(new Link(
 			     (*i).second.start,
 			     time,
@@ -233,11 +344,31 @@ void Container::end_link(Date time, Container *destination, String key, map<stri
 			     destination,
 			     (*i).second.value,
 			     (*i).second.opt));
+#endif
 	_current_links.erase(i);
     }
 }
 
 void Container::set_variable(Date time, VariableType *type, Double value) {
+#ifdef USE_ITC
+	int i=0;
+    IntervalOfContainer* itc= _intervalsOfContainer.back();
+    for(i=0;i< itc->_n_variables && itc->_variables[i].get_type()!=type; i++);
+
+    if (i==itc->_n_variables) {
+        itc->_n_variables++;
+        itc->_variables=(Variable*)realloc(itc->_variables, itc->_n_variables*sizeof(Variable));
+        memset(itc->_variables+(itc->_n_variables-1)*sizeof(Variable),0,sizeof(Variable));
+        _variables[type] = new Variable(this, type);
+        _n_variables++;
+		Variable* v=new(&itc->_variables[i]) Variable (this, type);
+        //itc->_variables[i].set_values(this, type);
+        itc->_variables[i].add_value(time, value);
+    }
+    else {
+        itc->_variables[i].add_value(time, value);
+    }
+#else
     map<VariableType *, Variable *>::iterator i = _variables.find(type);
     if (i == _variables.end()) {
         _variables[type] = new Variable(this, type);
@@ -247,9 +378,29 @@ void Container::set_variable(Date time, VariableType *type, Double value) {
     else {
         (*i).second->add_value(time, value);
     }
+#endif
 }
 
 void Container::add_variable(Date time, VariableType *type, Double value) {
+#ifdef USE_ITC
+	int i=0;
+    IntervalOfContainer* itc= _intervalsOfContainer.back();
+    for(i=0;i< itc->_n_variables && itc->_variables[i].get_type()!=type; i++);
+
+    if (i==itc->_n_variables) {
+        itc->_n_variables++;
+        itc->_variables=(Variable*)realloc(itc->_variables, itc->_n_variables*sizeof(Variable));
+        memset(itc->_variables+(itc->_n_variables-1)*sizeof(Variable),0,sizeof(Variable));
+        _variables[type] = new Variable(this, type);
+        _n_variables++;
+        
+		Variable* v=new(&itc->_variables[i]) Variable (this, type);
+        itc->_variables[i].add_value(time, value);
+    }
+    else {
+        itc->_variables[i].add_value(time,itc->_variables[i].get_last_value()+ value);
+    }
+#else
     map<VariableType *, Variable *>::iterator i = _variables.find(type);
     if (i == _variables.end()) {
         _variables[type] = new Variable(this, type);
@@ -259,11 +410,30 @@ void Container::add_variable(Date time, VariableType *type, Double value) {
     else {
         (*i).second->add_value(time, (*i).second->get_last_value() + value);
     }
-
+#endif
 }
 
 void Container::sub_variable(Date time, VariableType *type, Double value) {
-    map<VariableType *, Variable *>::iterator i = _variables.find(type);
+#ifdef USE_ITC
+	int i=0;
+    IntervalOfContainer* itc= _intervalsOfContainer.back();
+    for(i=0;i< itc->_n_variables && itc->_variables[i].get_type()!=type; i++);
+
+    if (i==itc->_n_variables) {
+        itc->_n_variables++;
+        itc->_variables=(Variable*)realloc(itc->_variables, itc->_n_variables*sizeof(Variable));
+        memset(itc->_variables+(itc->_n_variables-1)*sizeof(Variable),0,sizeof(Variable));
+        _variables[type] = new Variable(this, type);
+        _n_variables++;
+		
+		Variable* v=new(&itc->_variables[i]) Variable (this, type);
+        itc->_variables[i].add_value(time, value);
+    }
+    else {
+        itc->_variables[i].add_value(time,itc->_variables[i].get_last_value()- value);
+    }
+#else
+	map<VariableType *, Variable *>::iterator i = _variables.find(type);
     if (i == _variables.end()) {
         _variables[type] = new Variable(this, type);
         _variables[type]->add_value(time, -value);
@@ -272,6 +442,7 @@ void Container::sub_variable(Date time, VariableType *type, Double value) {
     else {
         (*i).second->add_value(time, (*i).second->get_last_value() - value);
     }
+#endif
 }
 
 Name Container::get_name() const {
@@ -351,10 +522,99 @@ void Container::destroy(const Date &time) {
 }
 
 void Container::finish(const Date &time) {
+
+#ifdef USE_ITC
+//	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(_n_events!=0)delete _event_tree;
+		if(_n_states!=0)delete _state_tree;
+  
+		_states.clear();
+		_links.clear();
+		_variables.clear();
+		//delete _events;
+		_n_states=0;
+		_n_events=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*));
+                        }
+                        _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]))));
+                           _n_variables++;
+                        }else{
+							if(((*it)->_variables[i]).get_values()!=NULL){
+                                std::list<std::pair<Date, Double> >::const_iterator  it_val = ((*it)->_variables[i]).get_values()->begin();
+								for(;
+									it_val!=((*it)->_variables[i]).get_values()->end();
+									it++){
+                                    pair<Date, Double> t= *it_val;
+                                    _variables[type]->add_value(t.first, t.second);
+									}
+                                }
+                            }
+                                                  
+                    }
+                }           
+            
+          //  }
+            
+         /*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;
+    else _state_tree = new BinaryTree<StateChange>(_states,_n_states);
+#else
     if (_destruction_time.get_value() == 0.0)
         destroy(time);
     _event_tree = new Event::Tree(_events, _n_events);
     _state_tree = new StateChange::Tree(_states,_n_states);
+#endif
 }
 
 
diff --git a/src/trace/Container.hpp b/src/trace/Container.hpp
index 4627b185..cb5560fb 100644
--- a/src/trace/Container.hpp
+++ b/src/trace/Container.hpp
@@ -50,6 +50,9 @@ template <typename E> class Node;
 template <typename E> class BinaryTree;
 class Statistic;
 class Interval;
+#ifdef USE_ITC
+struct IntervalOfContainer;
+#endif
 /*!
  * \class Container
  * \brief Contains others containers or entities
@@ -73,7 +76,11 @@ private:
     StateChange::Vector       _states;
     StateChange::Tree        *_state_tree;
     unsigned int              _n_events;
+	#ifdef USE_ITC
+	Event**					_events;
+	#else
     Event::Vector             _events;
+	#endif
     Event::Tree              *_event_tree;
     Link::Vector              _links;
     unsigned int              _n_variables;
@@ -81,6 +88,9 @@ private:
     std::map<std::string, Value *>       _extra_fields;
     int                       _depth;/* The container depth within the datastructure. The _depth of seed is equal to 0 */
 
+	#ifdef USE_ITC
+    std::list<IntervalOfContainer* >        _intervalsOfContainer;
+	#endif
     /*
      * Temporary stores states before complete definition
      */
diff --git a/src/trace/DrawTrace.hpp b/src/trace/DrawTrace.hpp
index 8d48dd33..0a04b10a 100644
--- a/src/trace/DrawTrace.hpp
+++ b/src/trace/DrawTrace.hpp
@@ -315,8 +315,12 @@ public:
         _container_positions[container] = position + size; // First line after children
         
         // Use one line for states and events
-        if (!container->get_states()->empty() || !container->get_events()->empty()) {
-            size++;
+#ifdef USE_ITC
+        if ((container->get_states()!=NULL && !container->get_states()->empty() )|| (container->get_events()!=NULL && !container->get_events()->empty())) {
+#else
+		if ((!container->get_states()->empty() )|| (!container->get_events()->empty())) {
+#endif
+			size++;
             _entity_containers.push_back(container);
         }
         
@@ -392,17 +396,30 @@ public:
 	        
                 state_tree = container->get_states();
                 event_tree = container->get_events();
-                if (!state_tree->empty() || !event_tree->empty()) {
-                    // Browse states
-                    DrawTree<T, StateChange>(draw_object, position, lvl_zoom,
-                                             _container_height, _container_v_space, _state_height, _state_v_space)
-                        .draw_tree(state_tree, *interval);
-                    
-                    // Browse events
-                    DrawTree<T, Event>(draw_object, position, lvl_zoom,
-                                       _container_height, _container_v_space, _state_height, _state_v_space)
-                        .draw_tree(event_tree, *interval);
+#ifdef USE_ITC
+                if(state_tree!=NULL){
+#endif
+                    if ( !state_tree->empty() ) {
+                    //printf("drawing states for %s\n", container->get_name().to_string().c_str());
+                        // Browse states
+                        DrawTree<T, StateChange>(draw_object, position, lvl_zoom,
+                                                 _container_height, _container_v_space, _state_height, _state_v_space)
+                            .draw_tree(state_tree, *interval);
+				    }
+#ifdef USE_ITC
+				}
+				if(event_tree!=NULL){
+#endif
+				    if ( !event_tree->empty()){
+				        //printf("drawing events for %s\n", container->get_name().to_string().c_str());
+                        // Browse events
+                        DrawTree<T, Event>(draw_object, position, lvl_zoom,
+                                           _container_height, _container_v_space, _state_height, _state_v_space)
+                            .draw_tree(event_tree, *interval);
+                    }
+#ifdef USE_ITC
                 }
+#endif
             }
         }/* end for (!_stack_states.empty()) */
 
@@ -456,7 +473,7 @@ public:
           
                 container = *c;
                 position = (int)_container_positions[container];
-                if (!container->get_states()->empty() || !container->get_events()->empty())
+				if ((container->get_states()!=NULL && !container->get_states()->empty()) ||(container->get_events()!=NULL && !container->get_events()->empty()))
                     position++;
                 // Browse variables
                 variable_map = container->get_variables();
@@ -587,7 +604,11 @@ public:
         
         // Now browsing for the events of the container root
         // Verification if it is a clic on an event
+#ifndef USE_ITC
         if ((!container->get_events()->empty() || !container->get_states()->empty()) && yr < _container_height+_container_v_space) {
+#else
+		if (((container->get_states()!=NULL && !container->get_states()->empty()) ||(container->get_events()!=NULL && !container->get_events()->empty())) && yr < _container_height+_container_v_space) {
+#endif
             if (!Info::Render::_no_events)
                 if ((event = find_event(container, x, d))) {
                 *Message::get_instance() << "<center><strong>Event</strong></center>"
@@ -616,7 +637,11 @@ public:
             }
         }
         else {
-            if (!container->get_events()->empty() || !container->get_states()->empty())
+#ifndef USE_ITC
+			if ((container->get_states()!=NULL && !container->get_states()->empty()) ||(container->get_events()!=NULL && !container->get_events()->empty()))
+#else
+			if (!container->get_events()->empty() || !container->get_states()->empty())
+#endif
                 yr -= _container_height+_container_v_space;
             const std::map<VariableType *, Variable *> *variable_map = container->get_variables();
             std::map<VariableType *, Variable *>::const_iterator i = variable_map->begin();
@@ -669,7 +694,11 @@ public:
         
         // Calculate the size of the container (without its children)
         int size = 0;
-        if (!container->get_states()->empty() || !container->get_events()->empty())
+#ifdef USE_ITC
+		if ((container->get_states()!=NULL && !container->get_states()->empty()) ||(container->get_events()!=NULL && !container->get_events()->empty()))
+#else
+		if (!container->get_states()->empty() || !container->get_events()->empty())
+#endif
             size++;
         if (container->get_variable_number() > 0)
             size += container->get_variable_number();
@@ -708,7 +737,11 @@ public:
         _container_positions[container] = position + size; // First line after children
         
         // Use one line for states and events
-        if (!container->get_states()->empty() || !container->get_events()->empty()) {
+#ifdef USE_ITC
+		if ((container->get_states()!=NULL && !container->get_states()->empty()) ||(container->get_events()!=NULL && !container->get_events()->empty())){
+#else
+		if (!container->get_states()->empty() || !container->get_events()->empty()) {
+#endif
             size++;
         }
         
@@ -763,7 +796,7 @@ public:
      * \brief Returns the event that occurs at the time x in the container
      */
     const Event *find_event(const Container *container, Element_pos x, Element_pos d) {
-        if(!container)
+        if(!container || container->get_events()==NULL)
             return NULL;
     
         Node<Event> *node = container->get_events()->get_root();
@@ -789,7 +822,7 @@ public:
      * \brief Returns the state at the time x
      */
     const State * find_state(const Container *container, Element_pos x) {
-        if(!container)
+        if(!container || container->get_states()==NULL)
             return NULL;
     
         Node<StateChange> *node = container->get_states()->get_root();
diff --git a/src/trace/Entity.cpp b/src/trace/Entity.cpp
index 8dfa9e8a..668fb5e0 100644
--- a/src/trace/Entity.cpp
+++ b/src/trace/Entity.cpp
@@ -50,12 +50,15 @@
 #include "trace/values/Values.hpp"
 #include "trace/EntityTypes.hpp"
 #include "trace/Entitys.hpp"
+#include "trace/Entity.hpp"
 /* -- */
 using namespace std;
 
 Entity::Entity(Container *container, map<std::string, Value *> opt): _container(container)/*, _extra_fields(opt)*/ {
  if(opt.empty())_extra_fields=NULL;
-	else _extra_fields=new map<std::string, Value *>(opt);
+	else{ _extra_fields=new map<std::string, Value *>(opt);
+	opt.clear();
+	}
 			
 
 }
@@ -77,3 +80,8 @@ Entity::~Entity(){
 //         (*it).second = NULL;
 //     }
 }
+
+void Entity::clear(){
+	if(_extra_fields !=NULL)delete _extra_fields;     
+	_extra_fields=NULL;
+}
\ No newline at end of file
diff --git a/src/trace/Entity.hpp b/src/trace/Entity.hpp
index f81798ea..5af30ea8 100644
--- a/src/trace/Entity.hpp
+++ b/src/trace/Entity.hpp
@@ -79,6 +79,8 @@ public:
     const std::map<std::string, Value *> *get_extra_fields() const;
 
      ~Entity();
+
+	void clear();
 };
 
 #endif
diff --git a/src/trace/EntityType.cpp b/src/trace/EntityType.cpp
index 64c86831..d3b19688 100644
--- a/src/trace/EntityType.cpp
+++ b/src/trace/EntityType.cpp
@@ -53,17 +53,10 @@ using namespace std;
 
 EntityType::EntityType(Name name, ContainerType *container_type, map<std::string, Value *>& opt):
     _name(name), _container_type(container_type) {
-		if (!opt.empty()) {
-			_extra_fields=new map<std::string, Value *>();
-			map<std::string , Value * >::iterator cur = opt.end();
-		   for(map<std::string, Value *>::iterator it = opt.begin();
-				it != cur;
-				it++){
-				_extra_fields->insert(*it);
-			}
-		   opt.clear();
-		}
-		else _extra_fields=NULL;
+	if(opt.empty())_extra_fields=NULL;
+	else{ _extra_fields=new map<std::string, Value *>(opt);
+	opt.clear();
+	}
 
 }
 
diff --git a/src/trace/StateChange.cpp b/src/trace/StateChange.cpp
index 2ae55f6e..b147e0a1 100644
--- a/src/trace/StateChange.cpp
+++ b/src/trace/StateChange.cpp
@@ -90,3 +90,11 @@ StateChange::~StateChange(){
     delete _right;
     _right = NULL;
 }
+void StateChange::clear(){
+        if(_left!=NULL){
+            _left->clear();
+            //free(_left_state);
+         //  Alloc<State2>::Instance().free(_left_state);
+        }
+           
+}
\ No newline at end of file
diff --git a/src/trace/StateChange.hpp b/src/trace/StateChange.hpp
index 03293563..53906ddd 100644
--- a/src/trace/StateChange.hpp
+++ b/src/trace/StateChange.hpp
@@ -69,6 +69,8 @@ public:
     const State *get_left_state() const;
     const State *get_right_state() const;
     ~StateChange();
+
+	void clear();
 };
 
 #endif
diff --git a/src/trace/Variable.cpp b/src/trace/Variable.cpp
index 2e74a0d0..f7125728 100644
--- a/src/trace/Variable.cpp
+++ b/src/trace/Variable.cpp
@@ -88,7 +88,7 @@ Double Variable::get_max() const {
     return _max;
 }
 
-const VariableType *Variable::get_type() const {
+VariableType *Variable::get_type() const {
     return _type;
 }
 
diff --git a/src/trace/Variable.hpp b/src/trace/Variable.hpp
index d1be638d..be9deba2 100644
--- a/src/trace/Variable.hpp
+++ b/src/trace/Variable.hpp
@@ -103,7 +103,7 @@ public:
     /*!
      * \brief Get the type of the variable
      */
-    const VariableType *get_type() const;
+    VariableType *get_type() const;
 
 };
 
diff --git a/src/trace/tree/BinaryTree.hpp b/src/trace/tree/BinaryTree.hpp
index acd5bf92..16b9504d 100644
--- a/src/trace/tree/BinaryTree.hpp
+++ b/src/trace/tree/BinaryTree.hpp
@@ -56,6 +56,141 @@ private:
     Node<E> *_root;
 
 public:
+
+ /*!
+     * \brief Constructor
+     * \param list List from which the tree is made
+     * \param size Number of element in the list
+     */
+    BinaryTree(E * list[], unsigned int size) {
+        if (size == 0 || list==NULL ||list[0]==NULL) {
+            _root = NULL;
+            return;
+        }
+    
+        // Calculate n and m as size = 2^n - 1 + m and m < 2^n
+        int n = 0;
+        unsigned int a = 1;
+        while (size >= 2*a - 1) {
+            a *= 2;
+            n++;
+        }
+        int m = size - a + 1;
+        
+        // Initialize the array
+        Node<E> **temp = new Node<E> *[n+1];
+        int start = 0;
+        int i = 0;
+        for (i = 0; i < n+1; i++)
+            temp[i] = NULL;
+        
+        i = 0;
+        // Reads elements from the list and empty it
+       for (unsigned int j=0; j<size; j++)  {
+            E *element = list[j];
+            
+            while (temp[i]) // Find the first free element in temp
+                i++;
+            
+            temp[i] = new Node<E>(element);
+            
+            if (i == 0 && m > 0) { // The node is a leaf and its depth is n+1
+                m--;
+                if (m == 0)
+                    start = 1;
+            }
+            
+            if (i < n && temp[i+1]) { // The node has a parent
+                temp[i]->_parent = temp[i+1];
+                temp[i+1]->_right_child = temp[i];
+            }
+            
+            if (i > 0 && temp[i-1]) { // The node is not a leaf
+                temp[i]->_left_child = temp[i-1];
+                temp[i-1]->_parent = temp[i];
+                while (i > 0) {
+                    i--;
+                    temp[i] = NULL;
+                }
+                i = start;
+            }
+        }
+        
+        _root = temp[n-1+start];
+        
+        delete[] temp;
+       // delete[] list;
+    }
+    
+    
+     /*!
+     * \brief Constructor
+     * \param list List from which the tree is made
+     * \param size Number of element in the list
+     */
+    BinaryTree(E * list, unsigned int size) {
+        if (size == 0 || list==NULL) {
+            _root = NULL;
+            return;
+        }
+    
+        // Calculate n and m as size = 2^n - 1 + m and m < 2^n
+        int n = 0;
+        unsigned int a = 1;
+        while (size >= 2*a - 1) {
+            a *= 2;
+            n++;
+        }
+        int m = size - a + 1;
+        
+        // Initialize the array
+        Node<E> **temp = new Node<E> *[n+1];
+        int start = 0;
+        int i = 0;
+        for (i = 0; i < n+1; i++)
+            temp[i] = NULL;
+        
+        i = 0;
+        // Reads elements from the list and empty it
+       for (unsigned int j=0; j<size; j++)  {
+            E *element = &(list[j]);
+            
+            while (temp[i]) // Find the first free element in temp
+                i++;
+            
+            temp[i] = new Node<E>(element);
+            
+            if (i == 0 && m > 0) { // The node is a leaf and its depth is n+1
+                m--;
+                if (m == 0)
+                    start = 1;
+            }
+            
+            if (i < n && temp[i+1]) { // The node has a parent
+                temp[i]->_parent = temp[i+1];
+                temp[i+1]->_right_child = temp[i];
+            }
+            
+            if (i > 0 && temp[i-1]) { // The node is not a leaf
+                temp[i]->_left_child = temp[i-1];
+                temp[i-1]->_parent = temp[i];
+                while (i > 0) {
+                    i--;
+                    temp[i] = NULL;
+                }
+                i = start;
+            }
+        }
+        
+        _root = temp[n-1+start];
+        
+        delete[] temp;
+       // delete[] list;
+    }
+    
+    
+    
+    
     /*!
      * \brief Constructor
      * \param list List from which the tree is made
-- 
GitLab