Mentions légales du service

Skip to content
Snippets Groups Projects
Commit 172244b3 authored by Augustin Degomme's avatar Augustin Degomme
Browse files

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.
parent 09b2bf7b
Branches
Tags
No related merge requests found
......@@ -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
......
......@@ -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 \
......
......@@ -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
}
......
......@@ -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
*/
......
......@@ -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();
......
......@@ -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
......@@ -79,6 +79,8 @@ public:
const std::map<std::string, Value *> *get_extra_fields() const;
~Entity();
void clear();
};
#endif
......@@ -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();
}
}
......
......@@ -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
......@@ -69,6 +69,8 @@ public:
const State *get_left_state() const;
const State *get_right_state() const;
~StateChange();
void clear();
};
#endif
......
......@@ -88,7 +88,7 @@ Double Variable::get_max() const {
return _max;
}
const VariableType *Variable::get_type() const {
VariableType *Variable::get_type() const {
return _type;
}
......@@ -103,7 +103,7 @@ public:
/*!
* \brief Get the type of the variable
*/
const VariableType *get_type() const;
VariableType *get_type() const;
};
......
......@@ -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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment