110448Snilay@cs.wisc.edu/* Copyright (c) 2012 Massachusetts Institute of Technology
210448Snilay@cs.wisc.edu *
310448Snilay@cs.wisc.edu * Permission is hereby granted, free of charge, to any person obtaining a copy
410448Snilay@cs.wisc.edu * of this software and associated documentation files (the "Software"), to deal
510448Snilay@cs.wisc.edu * in the Software without restriction, including without limitation the rights
610448Snilay@cs.wisc.edu * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
710448Snilay@cs.wisc.edu * copies of the Software, and to permit persons to whom the Software is
810448Snilay@cs.wisc.edu * furnished to do so, subject to the following conditions:
910448Snilay@cs.wisc.edu *
1010448Snilay@cs.wisc.edu * The above copyright notice and this permission notice shall be included in
1110448Snilay@cs.wisc.edu * all copies or substantial portions of the Software.
1210448Snilay@cs.wisc.edu *
1310448Snilay@cs.wisc.edu * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1410448Snilay@cs.wisc.edu * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1510448Snilay@cs.wisc.edu * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1610448Snilay@cs.wisc.edu * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1710448Snilay@cs.wisc.edu * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1810448Snilay@cs.wisc.edu * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1910448Snilay@cs.wisc.edu * THE SOFTWARE.
2010448Snilay@cs.wisc.edu */
2110448Snilay@cs.wisc.edu
2210447Snilay@cs.wisc.edu#include "util/Result.h"
2310447Snilay@cs.wisc.edu
2410447Snilay@cs.wisc.edu#include <iostream>
2510447Snilay@cs.wisc.edu
2610447Snilay@cs.wisc.edu#include "libutil/Log.h"
2710447Snilay@cs.wisc.edu#include "libutil/Assert.h"
2810447Snilay@cs.wisc.edu
2910447Snilay@cs.wisc.edunamespace DSENT
3010447Snilay@cs.wisc.edu{
3110447Snilay@cs.wisc.edu    using std::ostream;
3210447Snilay@cs.wisc.edu    using std::endl;
3310447Snilay@cs.wisc.edu
3410447Snilay@cs.wisc.edu    Result::SubResult::SubResult(const Result* sub_result_, const String& producer_, double num_results_)
3510447Snilay@cs.wisc.edu        : m_result_(sub_result_), m_producer_(producer_), m_num_results_(num_results_)
3610447Snilay@cs.wisc.edu    {
3710447Snilay@cs.wisc.edu        // Check if the result is not a null pointer
3810447Snilay@cs.wisc.edu        ASSERT((sub_result_ != NULL), "Internal error: sub_result_ is null");
3910447Snilay@cs.wisc.edu
4010447Snilay@cs.wisc.edu        // Check if the number of results greater than 0
4110447Snilay@cs.wisc.edu        ASSERT((num_results_ >= 0), "Internal error: num_results_ (" + String(num_results_) + ") is less than 0");
4210447Snilay@cs.wisc.edu    }
4310447Snilay@cs.wisc.edu
4410447Snilay@cs.wisc.edu    Result::SubResult::~SubResult()
4510447Snilay@cs.wisc.edu    {}
4610447Snilay@cs.wisc.edu
4710447Snilay@cs.wisc.edu    const Result* Result::SubResult::getResult() const
4810447Snilay@cs.wisc.edu    {
4910447Snilay@cs.wisc.edu        return m_result_;
5010447Snilay@cs.wisc.edu    }
5110447Snilay@cs.wisc.edu
5210447Snilay@cs.wisc.edu    const String& Result::SubResult::getProducer() const
5310447Snilay@cs.wisc.edu    {
5410447Snilay@cs.wisc.edu        return m_producer_;
5510447Snilay@cs.wisc.edu    }
5610447Snilay@cs.wisc.edu
5710447Snilay@cs.wisc.edu    double Result::SubResult::getNumResults() const
5810447Snilay@cs.wisc.edu    {
5910447Snilay@cs.wisc.edu        return m_num_results_;
6010447Snilay@cs.wisc.edu    }
6110447Snilay@cs.wisc.edu
6210447Snilay@cs.wisc.edu    Result::SubResult* Result::SubResult::clone() const
6310447Snilay@cs.wisc.edu    {
6410447Snilay@cs.wisc.edu        return new SubResult(*this);
6510447Snilay@cs.wisc.edu    }
6610447Snilay@cs.wisc.edu
6710447Snilay@cs.wisc.edu    Result::SubResult::SubResult(const SubResult& sub_result_)
6810447Snilay@cs.wisc.edu        : m_result_(sub_result_.m_result_), m_producer_(sub_result_.m_producer_), m_num_results_(sub_result_.m_num_results_)
6910447Snilay@cs.wisc.edu    {}
7010447Snilay@cs.wisc.edu
7110447Snilay@cs.wisc.edu    Result::Result()
7210447Snilay@cs.wisc.edu    {}
7310447Snilay@cs.wisc.edu
7410447Snilay@cs.wisc.edu    Result::Result(const String& result_name_)
7510447Snilay@cs.wisc.edu        : m_result_name_(result_name_)
7610447Snilay@cs.wisc.edu    {}
7710447Snilay@cs.wisc.edu
7810447Snilay@cs.wisc.edu    Result::~Result()
7910447Snilay@cs.wisc.edu    {
8010447Snilay@cs.wisc.edu        // Clear all sub results
8110447Snilay@cs.wisc.edu        for(vector<SubResult*>::iterator it = m_sub_results_.begin();
8210447Snilay@cs.wisc.edu            it != m_sub_results_.end(); ++it)
8310447Snilay@cs.wisc.edu        {
8410447Snilay@cs.wisc.edu            SubResult* sub_result = (*it);
8510447Snilay@cs.wisc.edu            delete sub_result;
8610447Snilay@cs.wisc.edu        }
8710447Snilay@cs.wisc.edu    }
8810447Snilay@cs.wisc.edu
8910447Snilay@cs.wisc.edu    const String& Result::getName() const
9010447Snilay@cs.wisc.edu    {
9110447Snilay@cs.wisc.edu        return m_result_name_;
9210447Snilay@cs.wisc.edu    }
9310447Snilay@cs.wisc.edu
9410447Snilay@cs.wisc.edu    void Result::setValue(double /* value_ */)
9510447Snilay@cs.wisc.edu    {
9610447Snilay@cs.wisc.edu        throw LibUtil::Exception("[Error] " + getName() + " -> Cannot set the value of a non-atomic result!");
9710447Snilay@cs.wisc.edu        return;
9810447Snilay@cs.wisc.edu    }
9910447Snilay@cs.wisc.edu
10010447Snilay@cs.wisc.edu    void Result::addValue(double /* value_ */)
10110447Snilay@cs.wisc.edu    {
10210447Snilay@cs.wisc.edu        throw LibUtil::Exception("[Error] " + getName() +
10310447Snilay@cs.wisc.edu                " -> Cannot add the value of a non-atomic result");
10410447Snilay@cs.wisc.edu        return;
10510447Snilay@cs.wisc.edu    }
10610447Snilay@cs.wisc.edu
10710447Snilay@cs.wisc.edu    double Result::getValue() const
10810447Snilay@cs.wisc.edu    {
10910447Snilay@cs.wisc.edu        throw LibUtil::Exception("[Error] " + getName() + " -> Cannot get the value of a non-atomic result!");
11010447Snilay@cs.wisc.edu        return 0.0;
11110447Snilay@cs.wisc.edu    }
11210447Snilay@cs.wisc.edu
11310447Snilay@cs.wisc.edu    void Result::addSubResult(const Result* sub_result_, const String& result_producer_, double num_results_)
11410447Snilay@cs.wisc.edu    {
11510447Snilay@cs.wisc.edu        SubResult* new_sub_result = new SubResult(sub_result_, result_producer_, num_results_);
11610447Snilay@cs.wisc.edu        m_sub_results_.push_back(new_sub_result);
11710447Snilay@cs.wisc.edu        return;
11810447Snilay@cs.wisc.edu    }
11910447Snilay@cs.wisc.edu
12010447Snilay@cs.wisc.edu    void Result::removeAllSubResults()
12110447Snilay@cs.wisc.edu    {
12210447Snilay@cs.wisc.edu        // Clear all sub results
12310447Snilay@cs.wisc.edu        for(vector<SubResult*>::iterator it = m_sub_results_.begin();
12410447Snilay@cs.wisc.edu            it != m_sub_results_.end(); ++it)
12510447Snilay@cs.wisc.edu        {
12610447Snilay@cs.wisc.edu            SubResult* sub_result = (*it);
12710447Snilay@cs.wisc.edu            delete sub_result;
12810447Snilay@cs.wisc.edu        }
12910447Snilay@cs.wisc.edu        m_sub_results_.clear();
13010447Snilay@cs.wisc.edu        return;
13110447Snilay@cs.wisc.edu    }
13210447Snilay@cs.wisc.edu
13310447Snilay@cs.wisc.edu    double Result::calculateSum() const
13410447Snilay@cs.wisc.edu    {
13510447Snilay@cs.wisc.edu        double sum = 0.0;
13610447Snilay@cs.wisc.edu
13710447Snilay@cs.wisc.edu        // Loop through all sub results and calculate the sum
13810447Snilay@cs.wisc.edu        for(vector<SubResult*>::const_iterator it = m_sub_results_.begin();
13910447Snilay@cs.wisc.edu            it != m_sub_results_.end(); ++it)
14010447Snilay@cs.wisc.edu        {
14110447Snilay@cs.wisc.edu            const SubResult* temp_sub_result = (*it);
14210447Snilay@cs.wisc.edu            const Result* temp_result = temp_sub_result->getResult();
14310447Snilay@cs.wisc.edu            double num_results = temp_sub_result->getNumResults();
14410447Snilay@cs.wisc.edu            sum += temp_result->calculateSum()*num_results;
14510447Snilay@cs.wisc.edu        }
14610447Snilay@cs.wisc.edu        return sum;
14710447Snilay@cs.wisc.edu    }
14810447Snilay@cs.wisc.edu
14910447Snilay@cs.wisc.edu    void Result::print(const String& prepend_str_, int detail_level_, ostream& ost_) const
15010447Snilay@cs.wisc.edu    {
15110447Snilay@cs.wisc.edu        print(prepend_str_, 1.0, detail_level_, ost_);
15210447Snilay@cs.wisc.edu        return;
15310447Snilay@cs.wisc.edu    }
15410447Snilay@cs.wisc.edu
15510447Snilay@cs.wisc.edu    Result* Result::clone() const
15610447Snilay@cs.wisc.edu    {
15710447Snilay@cs.wisc.edu        return new Result(*this);
15810447Snilay@cs.wisc.edu    }
15910447Snilay@cs.wisc.edu
16010447Snilay@cs.wisc.edu    Result::Result(const Result& result_)
16110447Snilay@cs.wisc.edu    {
16210447Snilay@cs.wisc.edu        // Copy the result name
16310447Snilay@cs.wisc.edu        m_result_name_ = result_.m_result_name_;
16410447Snilay@cs.wisc.edu
16510447Snilay@cs.wisc.edu        // Clone all sub results
16610447Snilay@cs.wisc.edu        for(vector<SubResult*>::const_iterator it = m_sub_results_.begin();
16710447Snilay@cs.wisc.edu            it != m_sub_results_.end(); ++it)
16810447Snilay@cs.wisc.edu        {
16910447Snilay@cs.wisc.edu            const SubResult* temp_sub_result = (*it);
17010447Snilay@cs.wisc.edu            SubResult* new_sub_result = temp_sub_result->clone();
17110447Snilay@cs.wisc.edu            m_sub_results_.push_back(new_sub_result);
17210447Snilay@cs.wisc.edu        }
17310447Snilay@cs.wisc.edu    }
17410447Snilay@cs.wisc.edu
17510447Snilay@cs.wisc.edu    void Result::print(const String& prepend_str_, double num_results_, int detail_level_, ostream& ost_) const
17610447Snilay@cs.wisc.edu    {
17710447Snilay@cs.wisc.edu        // Go down to lower level if detail_level_ > 0, else print the sthe sthe sthe sum
17810447Snilay@cs.wisc.edu        if(detail_level_ > 0)
17910447Snilay@cs.wisc.edu        {
18010447Snilay@cs.wisc.edu            for(vector<SubResult*>::const_iterator it = m_sub_results_.begin();
18110447Snilay@cs.wisc.edu                    it != m_sub_results_.end(); ++it)
18210447Snilay@cs.wisc.edu            {
18310447Snilay@cs.wisc.edu                const SubResult* temp_sub_result = (*it);
18410447Snilay@cs.wisc.edu                const Result* temp_result = temp_sub_result->getResult();
18510447Snilay@cs.wisc.edu                const String& temp_producer = temp_sub_result->getProducer();
18610447Snilay@cs.wisc.edu                const String& temp_result_name = temp_result->getName();
18710447Snilay@cs.wisc.edu                double temp_num_results = temp_sub_result->getNumResults();
18810447Snilay@cs.wisc.edu                String temp_prepend_str = prepend_str_ + "->" + temp_producer;
18910447Snilay@cs.wisc.edu
19010447Snilay@cs.wisc.edu                if(!temp_result_name.empty())
19110447Snilay@cs.wisc.edu                {
19210447Snilay@cs.wisc.edu                    temp_prepend_str += ":" + temp_result_name;
19310447Snilay@cs.wisc.edu                }
19410447Snilay@cs.wisc.edu                temp_result->print(temp_prepend_str, num_results_*temp_num_results, detail_level_ - 1, ost_);
19510447Snilay@cs.wisc.edu            }
19610447Snilay@cs.wisc.edu        }
19710447Snilay@cs.wisc.edu        else
19810447Snilay@cs.wisc.edu        {
19910447Snilay@cs.wisc.edu            ost_ << prepend_str_ << " = " << calculateSum()*num_results_;
20010447Snilay@cs.wisc.edu            ost_ << " (" << calculateSum() << " * " << num_results_ << ")" << endl;
20110447Snilay@cs.wisc.edu        }
20210447Snilay@cs.wisc.edu        return;
20310447Snilay@cs.wisc.edu    }
20410447Snilay@cs.wisc.edu
20510447Snilay@cs.wisc.edu    void Result::printHierarchy(const String& prepend_str_, int detail_level_, ostream& ost_) const
20610447Snilay@cs.wisc.edu    {
20710447Snilay@cs.wisc.edu        if(detail_level_ > 0)
20810447Snilay@cs.wisc.edu        {
20910447Snilay@cs.wisc.edu            for(vector<SubResult*>::const_iterator it = m_sub_results_.begin(); it != m_sub_results_.end(); ++it)
21010447Snilay@cs.wisc.edu            {
21110447Snilay@cs.wisc.edu                const SubResult* temp_sub_result = (*it);
21210447Snilay@cs.wisc.edu                const Result* temp_result = temp_sub_result->getResult();
21310447Snilay@cs.wisc.edu                const String& temp_producer = temp_sub_result->getProducer();
21410447Snilay@cs.wisc.edu                const String& temp_result_name = temp_result->getName();
21510447Snilay@cs.wisc.edu                String temp_prepend_str = prepend_str_ + "    ";
21610447Snilay@cs.wisc.edu
21710447Snilay@cs.wisc.edu                ost_ << prepend_str_ << " |--" << temp_producer << "->" << temp_result_name << endl;
21810447Snilay@cs.wisc.edu
21910447Snilay@cs.wisc.edu                temp_result->printHierarchy(temp_prepend_str, detail_level_ - 1, ost_);
22010447Snilay@cs.wisc.edu            }
22110447Snilay@cs.wisc.edu        }
22210447Snilay@cs.wisc.edu        return;
22310447Snilay@cs.wisc.edu    }
22410447Snilay@cs.wisc.edu
22510447Snilay@cs.wisc.edu    AtomicResult::AtomicResult(const String& result_name_, double value_)
22610447Snilay@cs.wisc.edu        : Result(result_name_), m_value_(value_)
22710447Snilay@cs.wisc.edu    {}
22810447Snilay@cs.wisc.edu
22910447Snilay@cs.wisc.edu    AtomicResult::~AtomicResult()
23010447Snilay@cs.wisc.edu    {}
23110447Snilay@cs.wisc.edu
23210447Snilay@cs.wisc.edu    void AtomicResult::setValue(double value_)
23310447Snilay@cs.wisc.edu    {
23410447Snilay@cs.wisc.edu        m_value_ = value_;
23510447Snilay@cs.wisc.edu        return;
23610447Snilay@cs.wisc.edu    }
23710447Snilay@cs.wisc.edu
23810447Snilay@cs.wisc.edu    void AtomicResult::addValue(double value_)
23910447Snilay@cs.wisc.edu    {
24010447Snilay@cs.wisc.edu        m_value_ += value_;
24110447Snilay@cs.wisc.edu        return;
24210447Snilay@cs.wisc.edu    }
24310447Snilay@cs.wisc.edu
24410447Snilay@cs.wisc.edu    double AtomicResult::getValue() const
24510447Snilay@cs.wisc.edu    {
24610447Snilay@cs.wisc.edu        return m_value_;
24710447Snilay@cs.wisc.edu    }
24810447Snilay@cs.wisc.edu
24910447Snilay@cs.wisc.edu    double AtomicResult::calculateSum() const
25010447Snilay@cs.wisc.edu    {
25110447Snilay@cs.wisc.edu        return m_value_;
25210447Snilay@cs.wisc.edu    }
25310447Snilay@cs.wisc.edu
25410447Snilay@cs.wisc.edu    AtomicResult* AtomicResult::clone() const
25510447Snilay@cs.wisc.edu    {
25610447Snilay@cs.wisc.edu        return new AtomicResult(*this);
25710447Snilay@cs.wisc.edu    }
25810447Snilay@cs.wisc.edu
25910447Snilay@cs.wisc.edu    AtomicResult::AtomicResult(const AtomicResult& atomic_result_)
26010447Snilay@cs.wisc.edu        : Result(atomic_result_), m_value_(atomic_result_.m_value_)
26110447Snilay@cs.wisc.edu    {}
26210447Snilay@cs.wisc.edu
26310447Snilay@cs.wisc.edu    void AtomicResult::print(const String& prepend_str_, double num_results_, int /* detail_level_ */, ostream& ost_) const
26410447Snilay@cs.wisc.edu    {
26510447Snilay@cs.wisc.edu        ost_ << prepend_str_ << " = " << m_value_*num_results_;
26610447Snilay@cs.wisc.edu        ost_ << " (" << m_value_ << " * " << num_results_ << ")" << endl;
26710447Snilay@cs.wisc.edu        return;
26810447Snilay@cs.wisc.edu    }
26910447Snilay@cs.wisc.edu} // namespace DSENT
27010447Snilay@cs.wisc.edu
271