<commit_before>/**

 * @file core/common/renderers/DocumentsRenderer.cpp
 * @author Ian Yang
 * @date Created <2010-06-11 13:03:57>
 */
#include "DocumentsRenderer.h"
#include "SubDocPropValueRenderer.h"
#include <common/Keys.h>
#include <query-manager/ActionItem.h>
#include <glog/logging.h>

#include <boost/assert.hpp>

namespace
{
const izenelib::util::UString::EncodingType kEncoding =
    izenelib::util::UString::UTF_8;
}

namespace sf1r {

using namespace izenelib::driver;
using driver::Keys;

template <class DocumentResultsType>
void renderPropertyList(
    SplitPropValueRenderer& splitRenderer,
    const std::vector<DisplayProperty>& propertyList,
    const DocumentResultsType& docResults,
    std::size_t column,
    Value& newResource
)
{
    // full text and snippet properties
    std::size_t summaryIndex = 0;
    std::string propertyValueBuffer;

    for (std::size_t p = 0; p < propertyList.size(); ++p)
    {
        const std::string& propertyName = propertyList[p].propertyString_;

        const PropertyValue::PropertyValueStrType& snippetText =
            docResults.snippetTextOfDocumentInPage_[p][column];

        if (propertyList[p].isSplitPropertyValue_)
        {
            splitRenderer.renderPropValue(
                propertyName, snippetText, newResource[propertyName]
            );
        }
        else if (propertyList[p].isSubDocPropertyValue_)
        {
            propertyValueBuffer = propstr_to_str(snippetText, kEncoding);
            SubDocPropValueRenderer::renderSubDocPropValue(
                propertyName, propertyValueBuffer, newResource[propertyName]
            );
        }
        else
        {
            propertyValueBuffer = propstr_to_str(snippetText, kEncoding);
            // remove dummy token @@ALL@@ from result
            if (propertyName == "ACL_ALLOW" && propertyValueBuffer == "@@ALL@@")
            {
                propertyValueBuffer = "";
            }

            newResource[propertyName] = propertyValueBuffer;
        }

        if (propertyList[p].isSummaryOn_)
        {
            BOOST_ASSERT(summaryIndex < docResults.rawTextOfSummaryInPage_.size());

            propertyValueBuffer = propstr_to_str(docResults.rawTextOfSummaryInPage_[summaryIndex][column], kEncoding);

            const std::string& summaryPropertyName =
                propertyList[p].summaryPropertyAlias_;

            newResource[summaryPropertyName] = propertyValueBuffer;
            ++summaryIndex;
        }
    }
}

DocumentsRenderer::DocumentsRenderer(const MiningSchema& miningSchema, int topKNum)
    : splitRenderer_(miningSchema)
    , TOP_K_NUM(topKNum)
{
}

/**
 * @brief Render documents in response
 *
 * Dummy token @@ALL@@ is removed from ACL_ALLOW.
 */
void DocumentsRenderer::renderDocuments(
    const std::vector<DisplayProperty>& propertyList,
    const RawTextResultFromMIA& result,
    izenelib::driver::Value& resources
)
{
    std::vector<sf1r::wdocid_t> widList;
    result.getWIdList(widList);

    std::size_t resultCount = widList.size();

    for (std::size_t i = 0; i < resultCount; ++i)
    {
        Value& newResource = resources();

        newResource[Keys::_id] = widList[i];

        renderPropertyList(splitRenderer_, propertyList,
            result, i, newResource);

        if (result.numberOfDuplicatedDocs_.size()
            == widList.size())
        {
            newResource[Keys::_duplicated_document_count] =
                result.numberOfDuplicatedDocs_[i];
        }

//         if (result.topKtids_.size()
//             == widList.size())
//         {
//             newResource[Keys::_tid] =
//                 result.topKtids_[i];
//         }
    }
}

/**
 * @brief Render documents in response
 *
 * Dummy token @@ALL@@ is removed from ACL_ALLOW.
 */
void DocumentsRenderer::renderDocuments(
    const std::vector<DisplayProperty>& propertyList,
    const KeywordSearchResult& searchResult,
    izenelib::driver::Value& resources
)
{
    std::string strBuffer;

    std::size_t indexInTopK = searchResult.start_ % TOP_K_NUM;

    BOOST_ASSERT(indexInTopK + searchResult.count_ <= searchResult.topKDocs_.size());

    std::vector<sf1r::wdocid_t> topKWDocs;
    searchResult.getTopKWDocs(topKWDocs);

    for (std::size_t i = 0; i < searchResult.count_; ++i, ++indexInTopK)
    {
        Value& newResource = resources();
        newResource[Keys::_id] = topKWDocs[indexInTopK];
        newResource[Keys::_rank] = searchResult.topKRankScoreList_[indexInTopK];

        if (searchResult.topKCustomRankScoreList_.size()
                == searchResult.topKDocs_.size())
        {
            newResource[Keys::_custom_rank] = searchResult.topKCustomRankScoreList_[indexInTopK];
        }

        renderPropertyList(splitRenderer_, propertyList,
            searchResult, i, newResource);

        if (searchResult.numberOfDuplicatedDocs_.size()
            == searchResult.topKDocs_.size())
        {
            newResource[Keys::_duplicated_document_count] =
                searchResult.numberOfDuplicatedDocs_[indexInTopK];
        }

        if (searchResult.numberOfSimilarDocs_.size()
            == searchResult.topKDocs_.size())
        {
            newResource[Keys::_similar_document_count] =
                searchResult.numberOfSimilarDocs_[indexInTopK];
        }

        if (searchResult.topKtids_.size()
            == searchResult.topKDocs_.size())
        {
            newResource[Keys::_tid] =
                searchResult.topKtids_[indexInTopK];
        }

        if (searchResult.docCategories_.size()
            == searchResult.topKDocs_.size())
        {
            Value& documentCategories = newResource[Keys::_categories];
            std::string categoryValueBuffer;
            for(std::size_t c = 0;
                c < searchResult.docCategories_[indexInTopK].size(); ++c)
            {
                documentCategories() = propstr_to_str(searchResult.docCategories_[indexInTopK][c], kEncoding);
            }
        }
    }
}

void DocumentsRenderer::renderRelatedQueries(
    const KeywordSearchResult& miaResult,
    izenelib::driver::Value& relatedQueries
)
{
    std::string tmpstr;
    for (std::size_t i = 0; i < miaResult.relatedQueryList_.size(); ++i)
    {
        miaResult.relatedQueryList_[i].convertString(tmpstr, kEncoding);
        relatedQueries() = tmpstr;
    }
}

void DocumentsRenderer::renderTaxonomy(
    const KeywordSearchResult& miaResult,
    izenelib::driver::Value& taxonomy
)
{
    if (miaResult.taxonomyString_.empty())
    {
        return;
    }

    BOOST_ASSERT(miaResult.taxonomyString_.size() == miaResult.taxonomyLevel_.size());
    BOOST_ASSERT(miaResult.taxonomyString_.size() == miaResult.numOfTGDocs_.size());
    std::vector<Value*> taxonomyParents;
    taxonomyParents.push_back(&taxonomy[Keys::labels]);
    for (std::size_t i = 0; i < miaResult.taxonomyString_.size(); ++i)
    {
        std::size_t currentLevel = miaResult.taxonomyLevel_[i];
        BOOST_ASSERT(currentLevel < taxonomyParents.size());

        Value& parent = *(taxonomyParents[currentLevel]);
        Value& newLabel = parent();
        newLabel[Keys::label] = propstr_to_str(miaResult.taxonomyString_[i], kEncoding);
        newLabel[Keys::document_count] = miaResult.numOfTGDocs_[i];

        // alternative for the parent of next level
        std::size_t nextLevel = currentLevel + 1;
        taxonomyParents.resize(nextLevel + 1);
        taxonomyParents[nextLevel] = &newLabel[Keys::sub_labels];
    }
}

void DocumentsRenderer::renderNameEntity(
    const KeywordSearchResult& miaResult,
    izenelib::driver::Value& nameEntity
)
{
    std::string tmpstr;
    for (std::size_t i = 0; i < miaResult.neList_.size(); ++i)
    {
        Value& newNameEntity = nameEntity();
        miaResult.neList_[i].type.convertString(tmpstr, kEncoding);
        newNameEntity[Keys::type] = tmpstr;

        Value& nameEntityList = newNameEntity[Keys::name_entity_list];
        typedef std::vector<NEItem>::const_iterator const_iterator;
        for (const_iterator item = miaResult.neList_[i].item_list.begin(),
                         itemEnd = miaResult.neList_[i].item_list.end();
             item != itemEnd; ++item)
        {
            Value& newNameEntityItem = nameEntityList();
            item->text.convertString(tmpstr, kEncoding);
            newNameEntityItem[Keys::name_entity_item] = tmpstr;
            newNameEntityItem[Keys::document_support_count] = item->doc_list.size();
        }
    }
}

void DocumentsRenderer::renderFaceted(
    const KeywordSearchResult& miaResult,
    izenelib::driver::Value& faceted)
{
  const std::list<sf1r::faceted::OntologyRepItem>& item_list = miaResult.onto_rep_.item_list;
  if( item_list.empty())
  {
      return;
  }

  std::vector<Value*> parents;
  parents.push_back(&faceted[Keys::labels]);
  std::list<sf1r::faceted::OntologyRepItem>::const_iterator it = item_list.begin();
  while(it!=item_list.end())
  {
      const sf1r::faceted::OntologyRepItem& item = *it;
      std::size_t currentLevel = item.level-1;
      BOOST_ASSERT(currentLevel < parents.size());

      std::string tmpstr;
      Value& parent = *(parents[currentLevel]);
      Value& newLabel = parent();
      item.text.convertString(tmpstr, kEncoding);
      newLabel[Keys::label] = tmpstr;
      newLabel[Keys::id] = item.id;
      newLabel[Keys::document_count] = item.doc_count;
#ifdef ONTOLOGY
      cout<<"currentLevel is "<<currentLevel<<endl;
      cout<<"parents.size() is "<<parents.size()<<endl;
      //cout<<"convertBuffer is "<<convertBuffer<<endl;
      cout<<"itemid is "<<item.id<<endl;
      cout<<"item.doc_count is "<<item.doc_count<<endl;
#endif
      // alternative for the parent of next level
      std::size_t nextLevel = currentLevel + 1;
      parents.resize(nextLevel + 1);
      parents[nextLevel] = &newLabel[Keys::sub_labels];
      ++it;
  }
}

void DocumentsRenderer::renderGroup(
    const KeywordSearchResult& miaResult,
    izenelib::driver::Value& groupResult
)
{
    const std::list<sf1r::faceted::OntologyRepItem>& item_list = miaResult.groupRep_.stringGroupRep_;
    if (item_list.empty())
    {
        return;
    }

    std::vector<Value*> parents;
    parents.push_back(&groupResult);
    std::string tmpstr;
    for (std::list<sf1r::faceted::OntologyRepItem>::const_iterator it = item_list.begin();
            it != item_list.end(); ++it)
    {
        const sf1r::faceted::OntologyRepItem& item = *it;
        // group level start from 0
        std::size_t currentLevel = item.level;
        BOOST_ASSERT(currentLevel < parents.size());

        Value& parent = *(parents[currentLevel]);
        Value& newLabel = parent();
        // alternative for the parent of next level
        std::size_t nextLevel = currentLevel + 1;
        parents.resize(nextLevel + 1);
        item.text.convertString(tmpstr, kEncoding);
        if (currentLevel == 0)
        {
            newLabel[Keys::property] = tmpstr;
            newLabel[Keys::document_count] = item.doc_count;
            parents[nextLevel] = &newLabel[Keys::labels];
        }
        else
        {
            newLabel[Keys::label] = tmpstr;
            newLabel[Keys::document_count] = item.doc_count;
            parents[nextLevel] = &newLabel[Keys::sub_labels];
        }
    }
}

void DocumentsRenderer::renderAttr(
    const KeywordSearchResult& miaResult,
    izenelib::driver::Value& attrResult
)
{
    const std::list<sf1r::faceted::OntologyRepItem>& item_list = miaResult.attrRep_.item_list;
    if (item_list.empty())
    {
        return;
    }

    Value* parent = NULL;
    std::string tmpstr;
    for (std::list<sf1r::faceted::OntologyRepItem>::const_iterator it = item_list.begin();
        it != item_list.end(); ++it)
    {
        const sf1r::faceted::OntologyRepItem& item = *it;

        item.text.convertString(tmpstr, kEncoding);
        // attribute name
        if (item.level == 0)
        {
            Value& newLabel = attrResult();
            newLabel[Keys::attr_name] = tmpstr;
            newLabel[Keys::document_count] = item.doc_count;
            newLabel[Keys::score] = item.score;
            parent = &newLabel[Keys::labels];
        }
        // attribute value
        else
        {
            BOOST_ASSERT(parent);
            Value& newLabel = (*parent)();
            newLabel[Keys::label] = tmpstr;
            newLabel[Keys::document_count] = item.doc_count;
            newLabel[Keys::score] = item.score;
        }
    }
}

void DocumentsRenderer::renderTopGroupLabel(const KeywordSearchResult& miaResult,
                                            izenelib::driver::Value& renderValue)
{
    using faceted::GroupParam;

    const GroupParam::GroupLabelScoreMap& topLabels = miaResult.autoSelectGroupLabels_;
    if (topLabels.empty())
        return;

    for (GroupParam::GroupLabelScoreMap::const_iterator labelIt = topLabels.begin();
         labelIt != topLabels.end(); ++labelIt)
    {
        Value& propValue = renderValue();
        propValue[Keys::group_property] = labelIt->first;

        Value& labelValue = propValue[Keys::group_label];
        const GroupParam::GroupPathScoreVec& pathVec = labelIt->second;

        for (GroupParam::GroupPathScoreVec::const_iterator pathIt = pathVec.begin();
             pathIt != pathVec.end(); ++pathIt)
        {
            Value& pathValue = labelValue();
            for (GroupParam::GroupPath::const_iterator nodeIt = pathIt->first.begin();
                 nodeIt != pathIt->first.end(); ++nodeIt)
            {
                pathValue() = *nodeIt;
            }
        }
    }
}

} // namespace sf1r
<commit_msg>fix a small bug<commit_after>/**

 * @file core/common/renderers/DocumentsRenderer.cpp
 * @author Ian Yang
 * @date Created <2010-06-11 13:03:57>
 */
#include "DocumentsRenderer.h"
#include "SubDocPropValueRenderer.h"
#include <common/Keys.h>
#include <query-manager/ActionItem.h>
#include <glog/logging.h>

#include <boost/assert.hpp>

namespace
{
const izenelib::util::UString::EncodingType kEncoding =
    izenelib::util::UString::UTF_8;
}

namespace sf1r {

using namespace izenelib::driver;
using driver::Keys;

template <class DocumentResultsType>
void renderPropertyList(
    SplitPropValueRenderer& splitRenderer,
    const std::vector<DisplayProperty>& propertyList,
    const DocumentResultsType& docResults,
    std::size_t column,
    Value& newResource
)
{
    // full text and snippet properties
    std::size_t summaryIndex = 0;
    std::string propertyValueBuffer;

    for (std::size_t p = 0; p < propertyList.size(); ++p)
    {
        const std::string& propertyName = propertyList[p].propertyString_;

        const PropertyValue::PropertyValueStrType& snippetText =
            docResults.snippetTextOfDocumentInPage_[p][column];

        if (propertyList[p].isSplitPropertyValue_)
        {
            splitRenderer.renderPropValue(
                propertyName, snippetText, newResource[propertyName]
            );
        }
        else if (propertyList[p].isSubDocPropertyValue_)
        {
            propertyValueBuffer = propstr_to_str(snippetText, kEncoding);
            SubDocPropValueRenderer::renderSubDocPropValue(
                propertyName, propertyValueBuffer, newResource[propertyName]
            );
        }
        else
        {
            propertyValueBuffer = propstr_to_str(snippetText, kEncoding);
            // remove dummy token @@ALL@@ from result
            if (propertyName == "ACL_ALLOW" && propertyValueBuffer == "@@ALL@@")
            {
                propertyValueBuffer = "";
            }

            newResource[propertyName] = propertyValueBuffer;
        }

        if (propertyList[p].isSummaryOn_)
        {
            BOOST_ASSERT(summaryIndex < docResults.rawTextOfSummaryInPage_.size());

            propertyValueBuffer = propstr_to_str(docResults.rawTextOfSummaryInPage_[summaryIndex][column], kEncoding);

            const std::string& summaryPropertyName =
                propertyList[p].summaryPropertyAlias_;

            newResource[summaryPropertyName] = propertyValueBuffer;
            ++summaryIndex;
        }
    }
}

DocumentsRenderer::DocumentsRenderer(const MiningSchema& miningSchema, int topKNum)
    : splitRenderer_(miningSchema)
    , TOP_K_NUM(topKNum)
{
}

/**
 * @brief Render documents in response
 *
 * Dummy token @@ALL@@ is removed from ACL_ALLOW.
 */
void DocumentsRenderer::renderDocuments(
    const std::vector<DisplayProperty>& propertyList,
    const RawTextResultFromMIA& result,
    izenelib::driver::Value& resources
)
{
    std::vector<sf1r::wdocid_t> widList;
    result.getWIdList(widList);

    std::size_t resultCount = widList.size();

    for (std::size_t i = 0; i < resultCount; ++i)
    {
        Value& newResource = resources();

        newResource[Keys::_id] = widList[i];

        renderPropertyList(splitRenderer_, propertyList,
            result, i, newResource);

        if (result.numberOfDuplicatedDocs_.size()
            == widList.size())
        {
            newResource[Keys::_duplicated_document_count] =
                result.numberOfDuplicatedDocs_[i];
        }

//         if (result.topKtids_.size()
//             == widList.size())
//         {
//             newResource[Keys::_tid] =
//                 result.topKtids_[i];
//         }
    }
}

/**
 * @brief Render documents in response
 *
 * Dummy token @@ALL@@ is removed from ACL_ALLOW.
 */
void DocumentsRenderer::renderDocuments(
    const std::vector<DisplayProperty>& propertyList,
    const KeywordSearchResult& searchResult,
    izenelib::driver::Value& resources
)
{
    std::string strBuffer;

    std::size_t indexInTopK = searchResult.start_ % TOP_K_NUM;

    BOOST_ASSERT(indexInTopK + searchResult.count_ <= searchResult.topKDocs_.size());

    std::vector<sf1r::wdocid_t> topKWDocs;
    searchResult.getTopKWDocs(topKWDocs);

    std::size_t scoreListSize = searchResult.topKRankScoreList_.size();

    for (std::size_t i = 0; i < searchResult.count_; ++i, ++indexInTopK)
    {
        Value& newResource = resources();
        newResource[Keys::_id] = topKWDocs[indexInTopK];

        if (indexInTopK < scoreListSize)
            newResource[Keys::_rank] = searchResult.topKRankScoreList_[indexInTopK];

        if (searchResult.topKCustomRankScoreList_.size()
                == searchResult.topKDocs_.size())
        {
            newResource[Keys::_custom_rank] = searchResult.topKCustomRankScoreList_[indexInTopK];
        }

        renderPropertyList(splitRenderer_, propertyList,
            searchResult, i, newResource);

        if (searchResult.numberOfDuplicatedDocs_.size()
            == searchResult.topKDocs_.size())
        {
            newResource[Keys::_duplicated_document_count] =
                searchResult.numberOfDuplicatedDocs_[indexInTopK];
        }

        if (searchResult.numberOfSimilarDocs_.size()
            == searchResult.topKDocs_.size())
        {
            newResource[Keys::_similar_document_count] =
                searchResult.numberOfSimilarDocs_[indexInTopK];
        }

        if (searchResult.topKtids_.size()
            == searchResult.topKDocs_.size())
        {
            newResource[Keys::_tid] =
                searchResult.topKtids_[indexInTopK];
        }

        if (searchResult.docCategories_.size()
            == searchResult.topKDocs_.size())
        {
            Value& documentCategories = newResource[Keys::_categories];
            std::string categoryValueBuffer;
            for(std::size_t c = 0;
                c < searchResult.docCategories_[indexInTopK].size(); ++c)
            {
                documentCategories() = propstr_to_str(searchResult.docCategories_[indexInTopK][c], kEncoding);
            }
        }
    }
}

void DocumentsRenderer::renderRelatedQueries(
    const KeywordSearchResult& miaResult,
    izenelib::driver::Value& relatedQueries
)
{
    std::string tmpstr;
    for (std::size_t i = 0; i < miaResult.relatedQueryList_.size(); ++i)
    {
        miaResult.relatedQueryList_[i].convertString(tmpstr, kEncoding);
        relatedQueries() = tmpstr;
    }
}

void DocumentsRenderer::renderTaxonomy(
    const KeywordSearchResult& miaResult,
    izenelib::driver::Value& taxonomy
)
{
    if (miaResult.taxonomyString_.empty())
    {
        return;
    }

    BOOST_ASSERT(miaResult.taxonomyString_.size() == miaResult.taxonomyLevel_.size());
    BOOST_ASSERT(miaResult.taxonomyString_.size() == miaResult.numOfTGDocs_.size());
    std::vector<Value*> taxonomyParents;
    taxonomyParents.push_back(&taxonomy[Keys::labels]);
    for (std::size_t i = 0; i < miaResult.taxonomyString_.size(); ++i)
    {
        std::size_t currentLevel = miaResult.taxonomyLevel_[i];
        BOOST_ASSERT(currentLevel < taxonomyParents.size());

        Value& parent = *(taxonomyParents[currentLevel]);
        Value& newLabel = parent();
        newLabel[Keys::label] = propstr_to_str(miaResult.taxonomyString_[i], kEncoding);
        newLabel[Keys::document_count] = miaResult.numOfTGDocs_[i];

        // alternative for the parent of next level
        std::size_t nextLevel = currentLevel + 1;
        taxonomyParents.resize(nextLevel + 1);
        taxonomyParents[nextLevel] = &newLabel[Keys::sub_labels];
    }
}

void DocumentsRenderer::renderNameEntity(
    const KeywordSearchResult& miaResult,
    izenelib::driver::Value& nameEntity
)
{
    std::string tmpstr;
    for (std::size_t i = 0; i < miaResult.neList_.size(); ++i)
    {
        Value& newNameEntity = nameEntity();
        miaResult.neList_[i].type.convertString(tmpstr, kEncoding);
        newNameEntity[Keys::type] = tmpstr;

        Value& nameEntityList = newNameEntity[Keys::name_entity_list];
        typedef std::vector<NEItem>::const_iterator const_iterator;
        for (const_iterator item = miaResult.neList_[i].item_list.begin(),
                         itemEnd = miaResult.neList_[i].item_list.end();
             item != itemEnd; ++item)
        {
            Value& newNameEntityItem = nameEntityList();
            item->text.convertString(tmpstr, kEncoding);
            newNameEntityItem[Keys::name_entity_item] = tmpstr;
            newNameEntityItem[Keys::document_support_count] = item->doc_list.size();
        }
    }
}

void DocumentsRenderer::renderFaceted(
    const KeywordSearchResult& miaResult,
    izenelib::driver::Value& faceted)
{
  const std::list<sf1r::faceted::OntologyRepItem>& item_list = miaResult.onto_rep_.item_list;
  if( item_list.empty())
  {
      return;
  }

  std::vector<Value*> parents;
  parents.push_back(&faceted[Keys::labels]);
  std::list<sf1r::faceted::OntologyRepItem>::const_iterator it = item_list.begin();
  while(it!=item_list.end())
  {
      const sf1r::faceted::OntologyRepItem& item = *it;
      std::size_t currentLevel = item.level-1;
      BOOST_ASSERT(currentLevel < parents.size());

      std::string tmpstr;
      Value& parent = *(parents[currentLevel]);
      Value& newLabel = parent();
      item.text.convertString(tmpstr, kEncoding);
      newLabel[Keys::label] = tmpstr;
      newLabel[Keys::id] = item.id;
      newLabel[Keys::document_count] = item.doc_count;
#ifdef ONTOLOGY
      cout<<"currentLevel is "<<currentLevel<<endl;
      cout<<"parents.size() is "<<parents.size()<<endl;
      //cout<<"convertBuffer is "<<convertBuffer<<endl;
      cout<<"itemid is "<<item.id<<endl;
      cout<<"item.doc_count is "<<item.doc_count<<endl;
#endif
      // alternative for the parent of next level
      std::size_t nextLevel = currentLevel + 1;
      parents.resize(nextLevel + 1);
      parents[nextLevel] = &newLabel[Keys::sub_labels];
      ++it;
  }
}

void DocumentsRenderer::renderGroup(
    const KeywordSearchResult& miaResult,
    izenelib::driver::Value& groupResult
)
{
    const std::list<sf1r::faceted::OntologyRepItem>& item_list = miaResult.groupRep_.stringGroupRep_;
    if (item_list.empty())
    {
        return;
    }

    std::vector<Value*> parents;
    parents.push_back(&groupResult);
    std::string tmpstr;
    for (std::list<sf1r::faceted::OntologyRepItem>::const_iterator it = item_list.begin();
            it != item_list.end(); ++it)
    {
        const sf1r::faceted::OntologyRepItem& item = *it;
        // group level start from 0
        std::size_t currentLevel = item.level;
        BOOST_ASSERT(currentLevel < parents.size());

        Value& parent = *(parents[currentLevel]);
        Value& newLabel = parent();
        // alternative for the parent of next level
        std::size_t nextLevel = currentLevel + 1;
        parents.resize(nextLevel + 1);
        item.text.convertString(tmpstr, kEncoding);
        if (currentLevel == 0)
        {
            newLabel[Keys::property] = tmpstr;
            newLabel[Keys::document_count] = item.doc_count;
            parents[nextLevel] = &newLabel[Keys::labels];
        }
        else
        {
            newLabel[Keys::label] = tmpstr;
            newLabel[Keys::document_count] = item.doc_count;
            parents[nextLevel] = &newLabel[Keys::sub_labels];
        }
    }
}

void DocumentsRenderer::renderAttr(
    const KeywordSearchResult& miaResult,
    izenelib::driver::Value& attrResult
)
{
    const std::list<sf1r::faceted::OntologyRepItem>& item_list = miaResult.attrRep_.item_list;
    if (item_list.empty())
    {
        return;
    }

    Value* parent = NULL;
    std::string tmpstr;
    for (std::list<sf1r::faceted::OntologyRepItem>::const_iterator it = item_list.begin();
        it != item_list.end(); ++it)
    {
        const sf1r::faceted::OntologyRepItem& item = *it;

        item.text.convertString(tmpstr, kEncoding);
        // attribute name
        if (item.level == 0)
        {
            Value& newLabel = attrResult();
            newLabel[Keys::attr_name] = tmpstr;
            newLabel[Keys::document_count] = item.doc_count;
            newLabel[Keys::score] = item.score;
            parent = &newLabel[Keys::labels];
        }
        // attribute value
        else
        {
            BOOST_ASSERT(parent);
            Value& newLabel = (*parent)();
            newLabel[Keys::label] = tmpstr;
            newLabel[Keys::document_count] = item.doc_count;
            newLabel[Keys::score] = item.score;
        }
    }
}

void DocumentsRenderer::renderTopGroupLabel(const KeywordSearchResult& miaResult,
                                            izenelib::driver::Value& renderValue)
{
    using faceted::GroupParam;

    const GroupParam::GroupLabelScoreMap& topLabels = miaResult.autoSelectGroupLabels_;
    if (topLabels.empty())
        return;

    for (GroupParam::GroupLabelScoreMap::const_iterator labelIt = topLabels.begin();
         labelIt != topLabels.end(); ++labelIt)
    {
        Value& propValue = renderValue();
        propValue[Keys::group_property] = labelIt->first;

        Value& labelValue = propValue[Keys::group_label];
        const GroupParam::GroupPathScoreVec& pathVec = labelIt->second;

        for (GroupParam::GroupPathScoreVec::const_iterator pathIt = pathVec.begin();
             pathIt != pathVec.end(); ++pathIt)
        {
            Value& pathValue = labelValue();
            for (GroupParam::GroupPath::const_iterator nodeIt = pathIt->first.begin();
                 nodeIt != pathIt->first.end(); ++nodeIt)
            {
                pathValue() = *nodeIt;
            }
        }
    }
}

} // namespace sf1r
<|endoftext|>


<commit_before>#include "parser.h"

#include <cstdlib>

#include "additionexpression.h"
#include "assignmentexpression.h"
#include "booleanliteralexpression.h"
#include "expression.h"
#include "expressionfactory.h"
#include "intliteralexpression.h"
#include "lexerexception.h"
#include "log.h"
#include "parserexception.h"
#include "parserstate.h"
#include "quitexpression.h"
#include "stringliteralexpression.h"
#include "token.h"
#include "tokensource.h"
#include "variableexpression.h"

namespace peachy {

  Parser::~Parser() {}

  Expression * Parser::nextExpression() {
    return nextExpression(PARSER_NEED_TOKEN);
  }

  Expression * Parser::nextExpression(ParserState state) {
    while(true) {
      fillTokenBuffer();
      switch(state) {
        case PARSER_NEED_TOKEN:
          if(tokenBuffer.size() > 0) {
            state = PARSER_DEFAULT;
            break;
          }
          return expressionFactory->createQuitExpression();
        case PARSER_DEFAULT: {
          switch(tokenBuffer.front()->getTokenType()) {
            case TOKEN_EOF:
              return expressionFactory->createQuitExpression();
            case TOKEN_IDENTIFIER:
              logger->debug("in token identifier");
              VariableExpression * ve =
                expressionFactory->createVariableExpression();
              ve->setVariableName(tokenBuffer[0]->getData());
              tokenBuffer.pop_front();
              switch(tokenBuffer[0]->getTokenType()) {
                case TOKEN_EOF:
                case TOKEN_IDENTIFIER:
                case TOKEN_INTEGER:
                case TOKEN_STRING:
                  return ve;
                case TOKEN_OPERATOR:
                  if(tokenBuffer[0]->getData().compare("<-") == 0) {
                    AssignmentExpression * ae =
                      expressionFactory->createAssignmentExpression();
                    ae->setLValue(ve);
                    tokenBuffer.pop_front();
                    ae->setRValue(nextExpression(PARSER_DEFAULT));
                    logger->debug(ae->toString());
                    return ae;
                  } else if(tokenBuffer[0]->getData().compare("->") == 0) {
                    AssignmentExpression * ae =
                      expressionFactory->createAssignmentExpression();
                    ae->setRValue(ve);
                    tokenBuffer.pop_front();
                    ae->setLValue(nextExpression(PARSER_DEFAULT));
                    logger->debug(ae->toString());
                    return ae;
                  } else if(tokenBuffer[0]->getData().compare("+") == 0) {
                    AdditionExpression * addEx =
                      expressionFactory->createAdditionExpression();
                    addEx->setLValue(ve);
                    tokenBuffer.pop_front();
                    addEx->setRValue(nextExpression(PARSER_DEFAULT));
                    logger->debug(addEx->toString());
                    return addEx;
                  } else {
                    errorMessage = std::string("Unexpected operator following variable ").append(ve->getVariableName());
                    state = PARSER_ERROR;
                    break;
                  }
                  break;
                default:
                  errorMessage = std::string("Unexpected token type");
                  state = PARSER_ERROR;
              }
              break;
            case TOKEN_INTEGER:
              IntLiteralExpression * ile =
                expressionFactory->createIntLiteralExpression();
              ile->setValue(atoi(tokenBuffer.front()->getData().c_str()));
              tokenBuffer.pop_front();
              switch(tokenBuffer[0]->getTokenType()) {
                case TOKEN_EOF:
                case TOKEN_IDENTIFIER:
                case TOKEN_INTEGER:
                case TOKEN_KEYWORD:
                  return ile;
                case TOKEN_OPERATOR:
                  if(tokenBuffer[0]->getData().compare("+") == 0) {
                    AdditionExpression * addEx =
                      expressionFactory->createAdditionExpression();
                    addEx->setLValue(ile);
                    tokenBuffer.pop_front();
                    addEx->setRValue(nextExpression(PARSER_DEFAULT));
                    logger->debug(addEx->toString());
                    return addEx;
                  } else if(tokenBuffer[0]->getData().compare("<-") == 0 ) {
                    errorMessage = std::string("Invalid assignment");
                    state = PARSER_ERROR;
                    break;
                  } else if(tokenBuffer[0]->getData().compare("->") == 0 ) {
                    AssignmentExpression * ae =
                      expressionFactory->createAssignmentExpression();
                    ae->setRValue(ile);
                    tokenBuffer.pop_front();
                    Expression * lValue = nextExpression(PARSER_DEFAULT);
                    ae->setLValue(lValue);
                    logger->debug(ae->toString());
                    return ae;
                  } else {
                    errorMessage = std::string("Unexpected operator");
                    state = PARSER_ERROR;
                    break;
                  }
                default:
                  errorMessage = std::string("Unexpected token: ").append(tokenBuffer[0]->toString());
                  state = PARSER_ERROR;
              }
              break;
            case TOKEN_OPERATOR:
              errorMessage = std::string("Unexpected operator");
              state = PARSER_ERROR;
              break;
            case TOKEN_STRING:
              StringLiteralExpression * sle =
                expressionFactory->createStringLiteralExpression();
              sle->setStringValue(tokenBuffer.front()->getData());
              tokenBuffer.pop_front();
              switch(tokenBuffer[0]->getTokenType()) {
                case TOKEN_EOF:
                case TOKEN_IDENTIFIER:
                case TOKEN_INTEGER:
                case TOKEN_KEYWORD:
                case TOKEN_STRING:
                  return sle;
                case TOKEN_OPERATOR:
                  if(tokenBuffer[0]->getData().compare("+") == 0) {
                    AdditionExpression * addEx =
                      expressionFactory->createAdditionExpression();
                    addEx->setLValue(sle);
                    tokenBuffer.pop_front();
                    addEx->setRValue(nextExpression(PARSER_DEFAULT));
                    logger->debug(addEx->toString());
                    return addEx;
                  } else if(tokenBuffer[0]->getData().compare("->") == 0) {
                    tokenBuffer.pop_front();
                    AssignmentExpression * ae =
                      expressionFactory->createAssignmentExpression();
                    ae->setRValue(sle);
                    ae->setLValue(nextExpression(PARSER_DEFAULT));
                    return ae;
                  } else {
                    errorMessage = std::string("Unexpected operator");
                    state = PARSER_ERROR;
                    break;
                  }
                default:
                  errorMessage = std::string("Unexpected token: ").append(tokenBuffer[0]->toString());
                  state = PARSER_ERROR;
              }
              break;
            case TOKEN_KEYWORD: {
              if(tokenBuffer[0]->getData().compare("while") == 0) {
                logger->debug("while keyword encountered");
                tokenBuffer.pop_front();
                switch(tokenBuffer[0]->getTokenType()) {
                  case TOKEN_LEFT_PARENTHESIS: {
                    logger->debug("Next token after while is left paren");
                    tokenBuffer.pop_front();
                    logger->debug("recursing");
                    Expression * condition = nextExpression(PARSER_DEFAULT);
                    logger->debug("finished recursing");
                    if(tokenBuffer[0]->getTokenType() != TOKEN_RIGHT_PARENTHESIS) {
                      errorMessage = std::string("Mismatched parentheses");
                      state = PARSER_ERROR;
                    } else {
                      return condition;
                    }
                  }
                  default: {
                    logger->debug("next token after while should be left paren but isnt");
                    errorMessage = std::string("Expected TOKEN_LEFT_PARENTHESIS following while");
                    state = PARSER_ERROR;
                  }
                }
                break;
              } else if(tokenBuffer[0]->getData().compare("true") == 0) {
                logger->debug("true keyword encountered");
                tokenBuffer.pop_front();
                BooleanLiteralExpression * trueExp =
                  expressionFactory->createBooleanLiteralExpression();
                trueExp->setValue(true);
                return trueExp;
              } else if(tokenBuffer[0]->getData().compare("false") == 0) {
                logger->debug("false keyword encountered");
                tokenBuffer.pop_front();
                BooleanLiteralExpression * falseExp =
                  expressionFactory->createBooleanLiteralExpression();
                falseExp->setValue(false);
                return falseExp;
              } else {
                errorMessage = std::string("Unable to handle that keyword");
                state = PARSER_ERROR;
                break;
              }
            }
            default:
              errorMessage = std::string("Unknown token");
              logger->debug("Unknown token follows:");
              logger->debug(tokenBuffer.front()->toString());
              state = PARSER_ERROR;
          }
        }
        case PARSER_ERROR:
          throw ParserException(errorMessage);
        default:
          errorMessage = std::string("Parser in unknown state");
          state = PARSER_ERROR;
      }
    }
  }

  void Parser::fillTokenBuffer() {
    while(tokenBuffer.size() < 3) {
      Token * token = tokenSource->nextToken();
      tokenBuffer.push_back(token);
    }
  }
}
<commit_msg>Fixed case blocks in parser<commit_after>#include "parser.h"

#include <cstdlib>

#include "additionexpression.h"
#include "assignmentexpression.h"
#include "booleanliteralexpression.h"
#include "expression.h"
#include "expressionfactory.h"
#include "intliteralexpression.h"
#include "lexerexception.h"
#include "log.h"
#include "parserexception.h"
#include "parserstate.h"
#include "quitexpression.h"
#include "stringliteralexpression.h"
#include "token.h"
#include "tokensource.h"
#include "variableexpression.h"

namespace peachy {

  Parser::~Parser() {}

  Expression * Parser::nextExpression() {
    return nextExpression(PARSER_NEED_TOKEN);
  }

  Expression * Parser::nextExpression(ParserState state) {
    while(true) {
      fillTokenBuffer();
      switch(state) {
        case PARSER_NEED_TOKEN: {
          if(tokenBuffer.size() > 0) {
            state = PARSER_DEFAULT;
            break;
          }
          return expressionFactory->createQuitExpression();
        } case PARSER_DEFAULT: {
          switch(tokenBuffer.front()->getTokenType()) {
            case TOKEN_EOF: {
              return expressionFactory->createQuitExpression();
            } case TOKEN_IDENTIFIER: {
              logger->debug("in token identifier");
              VariableExpression * ve =
                expressionFactory->createVariableExpression();
              ve->setVariableName(tokenBuffer[0]->getData());
              tokenBuffer.pop_front();
              switch(tokenBuffer[0]->getTokenType()) {
                case TOKEN_EOF:
                case TOKEN_IDENTIFIER:
                case TOKEN_INTEGER:
                case TOKEN_STRING: {
                  return ve;
                } case TOKEN_OPERATOR: {
                  if(tokenBuffer[0]->getData().compare("<-") == 0) {
                    AssignmentExpression * ae =
                      expressionFactory->createAssignmentExpression();
                    ae->setLValue(ve);
                    tokenBuffer.pop_front();
                    ae->setRValue(nextExpression(PARSER_DEFAULT));
                    logger->debug(ae->toString());
                    return ae;
                  } else if(tokenBuffer[0]->getData().compare("->") == 0) {
                    AssignmentExpression * ae =
                      expressionFactory->createAssignmentExpression();
                    ae->setRValue(ve);
                    tokenBuffer.pop_front();
                    ae->setLValue(nextExpression(PARSER_DEFAULT));
                    logger->debug(ae->toString());
                    return ae;
                  } else if(tokenBuffer[0]->getData().compare("+") == 0) {
                    AdditionExpression * addEx =
                      expressionFactory->createAdditionExpression();
                    addEx->setLValue(ve);
                    tokenBuffer.pop_front();
                    addEx->setRValue(nextExpression(PARSER_DEFAULT));
                    logger->debug(addEx->toString());
                    return addEx;
                  } else {
                    errorMessage = std::string("Unexpected operator following variable ").append(ve->getVariableName());
                    state = PARSER_ERROR;
                    break;
                  }
                  break;
                } default: {
                  errorMessage = std::string("Unexpected token type");
                  state = PARSER_ERROR;
                }
              }
              break;
            } case TOKEN_INTEGER: {
              IntLiteralExpression * ile =
                expressionFactory->createIntLiteralExpression();
              ile->setValue(atoi(tokenBuffer.front()->getData().c_str()));
              tokenBuffer.pop_front();
              switch(tokenBuffer[0]->getTokenType()) {
                case TOKEN_EOF:
                case TOKEN_IDENTIFIER:
                case TOKEN_INTEGER:
                case TOKEN_KEYWORD: {
                  return ile;
                } case TOKEN_OPERATOR: {
                  if(tokenBuffer[0]->getData().compare("+") == 0) {
                    AdditionExpression * addEx =
                      expressionFactory->createAdditionExpression();
                    addEx->setLValue(ile);
                    tokenBuffer.pop_front();
                    addEx->setRValue(nextExpression(PARSER_DEFAULT));
                    logger->debug(addEx->toString());
                    return addEx;
                  } else if(tokenBuffer[0]->getData().compare("<-") == 0 ) {
                    errorMessage = std::string("Invalid assignment");
                    state = PARSER_ERROR;
                    break;
                  } else if(tokenBuffer[0]->getData().compare("->") == 0 ) {
                    AssignmentExpression * ae =
                      expressionFactory->createAssignmentExpression();
                    ae->setRValue(ile);
                    tokenBuffer.pop_front();
                    Expression * lValue = nextExpression(PARSER_DEFAULT);
                    ae->setLValue(lValue);
                    logger->debug(ae->toString());
                    return ae;
                  } else {
                    errorMessage = std::string("Unexpected operator");
                    state = PARSER_ERROR;
                    break;
                  }
                } default: {
                  errorMessage = std::string("Unexpected token: ").append(tokenBuffer[0]->toString());
                  state = PARSER_ERROR;
                }
              }
              break;
            } case TOKEN_OPERATOR: {
              errorMessage = std::string("Unexpected operator");
              state = PARSER_ERROR;
              break;
            } case TOKEN_STRING: {
              StringLiteralExpression * sle =
                expressionFactory->createStringLiteralExpression();
              sle->setStringValue(tokenBuffer.front()->getData());
              tokenBuffer.pop_front();
              switch(tokenBuffer[0]->getTokenType()) {
                case TOKEN_EOF:
                case TOKEN_IDENTIFIER:
                case TOKEN_INTEGER:
                case TOKEN_KEYWORD:
                case TOKEN_STRING: {
                  return sle;
                } case TOKEN_OPERATOR: {
                  if(tokenBuffer[0]->getData().compare("+") == 0) {
                    AdditionExpression * addEx =
                      expressionFactory->createAdditionExpression();
                    addEx->setLValue(sle);
                    tokenBuffer.pop_front();
                    addEx->setRValue(nextExpression(PARSER_DEFAULT));
                    logger->debug(addEx->toString());
                    return addEx;
                  } else if(tokenBuffer[0]->getData().compare("->") == 0) {
                    tokenBuffer.pop_front();
                    AssignmentExpression * ae =
                      expressionFactory->createAssignmentExpression();
                    ae->setRValue(sle);
                    ae->setLValue(nextExpression(PARSER_DEFAULT));
                    return ae;
                  } else {
                    errorMessage = std::string("Unexpected operator");
                    state = PARSER_ERROR;
                    break;
                  }
                } default: {
                  errorMessage = std::string("Unexpected token: ").append(tokenBuffer[0]->toString());
                  state = PARSER_ERROR;
                }
              }
              break;
            } case TOKEN_KEYWORD: {
              if(tokenBuffer[0]->getData().compare("while") == 0) {
                logger->debug("while keyword encountered");
                tokenBuffer.pop_front();
                switch(tokenBuffer[0]->getTokenType()) {
                  case TOKEN_LEFT_PARENTHESIS: {
                    logger->debug("Next token after while is left paren");
                    tokenBuffer.pop_front();
                    logger->debug("recursing");
                    Expression * condition = nextExpression(PARSER_DEFAULT);
                    logger->debug("finished recursing");
                    if(tokenBuffer[0]->getTokenType() != TOKEN_RIGHT_PARENTHESIS) {
                      errorMessage = std::string("Mismatched parentheses");
                      state = PARSER_ERROR;
                    } else {
                      return condition;
                    }
                  } default: {
                    logger->debug("next token after while should be left paren but isnt");
                    errorMessage = std::string("Expected TOKEN_LEFT_PARENTHESIS following while");
                    state = PARSER_ERROR;
                  }
                }
                break;
              } else if(tokenBuffer[0]->getData().compare("true") == 0) {
                logger->debug("true keyword encountered");
                tokenBuffer.pop_front();
                BooleanLiteralExpression * trueExp =
                  expressionFactory->createBooleanLiteralExpression();
                trueExp->setValue(true);
                return trueExp;
              } else if(tokenBuffer[0]->getData().compare("false") == 0) {
                logger->debug("false keyword encountered");
                tokenBuffer.pop_front();
                BooleanLiteralExpression * falseExp =
                  expressionFactory->createBooleanLiteralExpression();
                falseExp->setValue(false);
                return falseExp;
              } else {
                errorMessage = std::string("Unable to handle that keyword");
                state = PARSER_ERROR;
                break;
              }
            } default: {
              errorMessage = std::string("Unknown token");
              logger->debug("Unknown token follows:");
              logger->debug(tokenBuffer.front()->toString());
              state = PARSER_ERROR;
            }
          }
        } case PARSER_ERROR: {
          throw ParserException(errorMessage);
        } default: {
          errorMessage = std::string("Parser in unknown state");
          state = PARSER_ERROR;
        }
      }
    }
  }

  void Parser::fillTokenBuffer() {
    while(tokenBuffer.size() < 3) {
      Token * token = tokenSource->nextToken();
      tokenBuffer.push_back(token);
    }
  }
}
<|endoftext|>


<commit_before>// Copyright (c) 2014-2015 The Dash developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "main.h"
#include "activemasternode.h"
#include "masternode-sync.h"
#include "masternode-payments.h"
#include "masternode-budget.h"
#include "masternode.h"
#include "masternodeman.h"
#include "util.h"
#include "addrman.h"

class CMasternodeSync;
CMasternodeSync masternodeSync;

CMasternodeSync::CMasternodeSync()
{
    Reset();
}

bool CMasternodeSync::IsSynced()
{
    return RequestedMasternodeAssets == MASTERNODE_SYNC_FINISHED;
}

bool CMasternodeSync::IsBlockchainSynced()
{
    static bool fBlockchainSynced = false;
    static int64_t lastProcess = GetTime();

    // if the last call to this function was more than 10 minutes ago (client was in sleep mode) reset the sync process
    if(GetTime() - lastProcess > 60*10) {
        Reset();
        fBlockchainSynced = false;
    }
    lastProcess = GetTime();

    if(fBlockchainSynced) return true;

    if (fImporting || fReindex) return false;

    TRY_LOCK(cs_main, lockMain);
    if(!lockMain) return false;

    CBlockIndex* pindex = chainActive.Tip();
    if(pindex == NULL) return false;

    if(pindex->nTime + 600 < GetTime())
        return false;

    fBlockchainSynced = true;

    return true;
}

void CMasternodeSync::Reset()
{
    lastMasternodeList = 0;
    lastMasternodeWinner = 0;
    lastBudgetItem = 0;
    lastFailure = 0;
    nCountFailures = 0;
    sumMasternodeList = 0;
    sumMasternodeWinner = 0;
    sumBudgetItemProp = 0;
    sumBudgetItemFin = 0;
    countMasternodeList = 0;
    countMasternodeWinner = 0;
    countBudgetItemProp = 0;
    countBudgetItemFin = 0;
    RequestedMasternodeAssets = MASTERNODE_SYNC_INITIAL;
    RequestedMasternodeAttempt = 0;
}

void CMasternodeSync::AddedMasternodeList()
{
    lastMasternodeList = GetTime();
}

void CMasternodeSync::AddedMasternodeWinner()
{
    lastMasternodeWinner = GetTime();
}

void CMasternodeSync::AddedBudgetItem()
{
    lastBudgetItem = GetTime();
}

bool CMasternodeSync::IsBudgetPropEmpty()
{
    return sumBudgetItemProp==0 && countBudgetItemProp>0;
}

bool CMasternodeSync::IsBudgetFinEmpty()
{
    return sumBudgetItemFin==0 && countBudgetItemFin>0;
}

void CMasternodeSync::GetNextAsset()
{
    switch(RequestedMasternodeAssets)
    {
        case(MASTERNODE_SYNC_INITIAL):
        case(MASTERNODE_SYNC_FAILED):
            lastMasternodeList = 0;
            lastMasternodeWinner = 0;
            lastBudgetItem = 0;
            lastFailure = 0;
            nCountFailures = 0;
            sumMasternodeList = 0;
            sumMasternodeWinner = 0;
            sumBudgetItemProp = 0;
            sumBudgetItemFin = 0;
            countMasternodeList = 0;
            countMasternodeWinner = 0;
            countBudgetItemProp = 0;
            countBudgetItemFin = 0;
            RequestedMasternodeAssets = MASTERNODE_SYNC_SPORKS;
            ClearFulfilledRequest();
            break;
        case(MASTERNODE_SYNC_SPORKS):
            RequestedMasternodeAssets = MASTERNODE_SYNC_LIST;
            break;
        case(MASTERNODE_SYNC_LIST):
            RequestedMasternodeAssets = MASTERNODE_SYNC_MNW;
            break;
        case(MASTERNODE_SYNC_MNW):
            RequestedMasternodeAssets = MASTERNODE_SYNC_BUDGET;
            break;
        case(MASTERNODE_SYNC_BUDGET):
            LogPrintf("CMasternodeSync::GetNextAsset - Sync has finished\n");
            RequestedMasternodeAssets = MASTERNODE_SYNC_FINISHED;
            break;
    }
    RequestedMasternodeAttempt = 0;
}

void CMasternodeSync::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
{
    if (strCommand == "ssc") { //Sync status count
        int nItemID;
        int nCount;
        vRecv >> nItemID >> nCount;

        if(RequestedMasternodeAssets >= MASTERNODE_SYNC_FINISHED) return;

        //this means we will receive no further communication
        switch(nItemID)
        {
            case(MASTERNODE_SYNC_LIST):
                if(nItemID != RequestedMasternodeAssets) return;
                if(nCount == 0) lastMasternodeList = GetTime();
                sumMasternodeList += nCount;
                countMasternodeList++;
                break;
            case(MASTERNODE_SYNC_MNW):
                if(nItemID != RequestedMasternodeAssets) return;
                if(nCount == 0) lastMasternodeWinner = GetTime();
                sumMasternodeWinner += nCount;
                countMasternodeWinner++;
                break;
            case(MASTERNODE_SYNC_BUDGET_PROP):
                if(RequestedMasternodeAssets != MASTERNODE_SYNC_BUDGET) return;
                if(nCount == 0) lastBudgetItem = GetTime();
                sumBudgetItemProp += nCount;
                countBudgetItemProp++;
                break;
            case(MASTERNODE_SYNC_BUDGET_FIN):
                if(RequestedMasternodeAssets != MASTERNODE_SYNC_BUDGET) return;
                if(nCount == 0) lastBudgetItem = GetTime();
                sumBudgetItemFin += nCount;
                countBudgetItemFin++;
                break;
        }

        LogPrintf("CMasternodeSync:ProcessMessage - ssc - got inventory count %d %d\n", nItemID, nCount);
    }
}

void CMasternodeSync::ClearFulfilledRequest()
{
    TRY_LOCK(cs_vNodes, lockRecv);
    if(!lockRecv) return;

    BOOST_FOREACH(CNode* pnode, vNodes)
    {
        pnode->ClearFulfilledRequest("getspork");
        pnode->ClearFulfilledRequest("mnsync");
        pnode->ClearFulfilledRequest("mnwsync");
        pnode->ClearFulfilledRequest("busync");
    }
}

void CMasternodeSync::Process()
{
    static int tick = 0;

    if(tick++ % MASTERNODE_SYNC_TIMEOUT != 0) return;

    if(IsSynced()) {
        /*
            Resync if we lose all masternodes from sleep/wake or failure to sync originally
        */
        if(mnodeman.CountEnabled() == 0) {
            ClearFulfilledRequest();
            RequestedMasternodeAssets = MASTERNODE_SYNC_INITIAL;
        } else
            return;
    }

    //try syncing again in an hour
    if(RequestedMasternodeAssets == MASTERNODE_SYNC_FAILED && lastFailure + (60*60) < GetTime()) {
        GetNextAsset();
    } else if (RequestedMasternodeAssets == MASTERNODE_SYNC_FAILED) {
        return;
    }

    if(fDebug) LogPrintf("CMasternodeSync::Process() - tick %d RequestedMasternodeAssets %d\n", tick, RequestedMasternodeAssets);

    if(RequestedMasternodeAssets == MASTERNODE_SYNC_INITIAL) GetNextAsset();

    // sporks synced but blockchain is not, wait until we're almost at a recent block to continue
    if(Params().NetworkID() != CBaseChainParams::REGTEST &&
            !IsBlockchainSynced() && RequestedMasternodeAssets > MASTERNODE_SYNC_SPORKS) return;

    TRY_LOCK(cs_vNodes, lockRecv);
    if(!lockRecv) return;

    BOOST_FOREACH(CNode* pnode, vNodes)
    {
        if(Params().NetworkID() == CBaseChainParams::REGTEST){
            if(RequestedMasternodeAttempt <= 2) {
                pnode->PushMessage("getsporks"); //get current network sporks
            } else if(RequestedMasternodeAttempt < 4) {
                mnodeman.DsegUpdate(pnode);
            } else if(RequestedMasternodeAttempt < 6) {
                int nMnCount = mnodeman.CountEnabled()*2;
                pnode->PushMessage("mnget", nMnCount); //sync payees
                uint256 n = 0;
                pnode->PushMessage("mnvs", n); //sync masternode votes
            } else {
                RequestedMasternodeAssets = MASTERNODE_SYNC_FINISHED;
            }
            RequestedMasternodeAttempt++;
            return;
        }

        //set to synced
        if(RequestedMasternodeAssets == MASTERNODE_SYNC_SPORKS){
            if(pnode->HasFulfilledRequest("getspork")) continue;
            pnode->FulfilledRequest("getspork");

            pnode->PushMessage("getsporks"); //get current network sporks
            if(RequestedMasternodeAttempt >= 2) GetNextAsset();
            RequestedMasternodeAttempt++;

            return;
        }

        if (pnode->nVersion >= masternodePayments.GetMinMasternodePaymentsProto()) {

            if(RequestedMasternodeAssets == MASTERNODE_SYNC_LIST) {
                if(fDebug) LogPrintf("CMasternodeSync::Process() - lastMasternodeList %lld (GetTime() - MASTERNODE_SYNC_TIMEOUT) %lld\n", lastMasternodeList, GetTime() - MASTERNODE_SYNC_TIMEOUT);
                if(lastMasternodeList > 0 && lastMasternodeList < GetTime() - MASTERNODE_SYNC_TIMEOUT && RequestedMasternodeAttempt >= 4){ //hasn't received a new item in the last five seconds, so we'll move to the
                    GetNextAsset();
                    return;
                }

                if(pnode->HasFulfilledRequest("mnsync")) continue;
                pnode->FulfilledRequest("mnsync");

                mnodeman.DsegUpdate(pnode);
                RequestedMasternodeAttempt++;
                return;
            }

            if(RequestedMasternodeAssets == MASTERNODE_SYNC_MNW) {
                if(lastMasternodeWinner > 0 && lastMasternodeWinner < GetTime() - MASTERNODE_SYNC_TIMEOUT && RequestedMasternodeAttempt >= 4){ //hasn't received a new item in the last five seconds, so we'll move to the
                    GetNextAsset();
                    return;
                }

                if(pnode->HasFulfilledRequest("mnwsync")) continue;
                pnode->FulfilledRequest("mnwsync");

                CBlockIndex* pindexPrev = chainActive.Tip();
                if(pindexPrev == NULL) return;

                int nMnCount = mnodeman.CountEnabled()*2;
                pnode->PushMessage("mnget", nMnCount); //sync payees
                RequestedMasternodeAttempt++;

                return;
            }
        }

        if (pnode->nVersion >= MIN_BUDGET_PEER_PROTO_VERSION) {

            if(RequestedMasternodeAssets == MASTERNODE_SYNC_BUDGET){
                //we'll start rejecting votes if we accidentally get set as synced too soon
                if(lastBudgetItem > 0 && lastBudgetItem < GetTime() - MASTERNODE_SYNC_TIMEOUT && RequestedMasternodeAttempt >= 4){ //hasn't received a new item in the last five seconds, so we'll move to the
                    //LogPrintf("CMasternodeSync::Process - HasNextFinalizedBudget %d nCountFailures %d IsBudgetPropEmpty %d\n", budget.HasNextFinalizedBudget(), nCountFailures, IsBudgetPropEmpty());
                    //if(budget.HasNextFinalizedBudget() || nCountFailures >= 2 || IsBudgetPropEmpty()) {
                        GetNextAsset();

                        //try to activate our masternode if possible
                        activeMasternode.ManageStatus();
                    // } else { //we've failed to sync, this state will reject the next budget block
                    //     LogPrintf("CMasternodeSync::Process - ERROR - Sync has failed, will retry later\n");
                    //     RequestedMasternodeAssets = MASTERNODE_SYNC_FAILED;
                    //     RequestedMasternodeAttempt = 0;
                    //     lastFailure = GetTime();
                    //     nCountFailures++;
                    // }
                    return;
                }

                if(pnode->HasFulfilledRequest("busync")) continue;
                pnode->FulfilledRequest("busync");

                uint256 n = 0;
                pnode->PushMessage("mnvs", n); //sync masternode votes
                RequestedMasternodeAttempt++;

                return;
            }

        }
    }
}
<commit_msg>cleanup CMasternodeSync a bit<commit_after>// Copyright (c) 2014-2015 The Dash developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "main.h"
#include "activemasternode.h"
#include "masternode-sync.h"
#include "masternode-payments.h"
#include "masternode-budget.h"
#include "masternode.h"
#include "masternodeman.h"
#include "util.h"
#include "addrman.h"

class CMasternodeSync;
CMasternodeSync masternodeSync;

CMasternodeSync::CMasternodeSync()
{
    Reset();
}

bool CMasternodeSync::IsSynced()
{
    return RequestedMasternodeAssets == MASTERNODE_SYNC_FINISHED;
}

bool CMasternodeSync::IsBlockchainSynced()
{
    static bool fBlockchainSynced = false;
    static int64_t lastProcess = GetTime();

    // if the last call to this function was more than 10 minutes ago (client was in sleep mode) reset the sync process
    if(GetTime() - lastProcess > 60*10) {
        Reset();
        fBlockchainSynced = false;
    }
    lastProcess = GetTime();

    if(fBlockchainSynced) return true;

    if (fImporting || fReindex) return false;

    TRY_LOCK(cs_main, lockMain);
    if(!lockMain) return false;

    CBlockIndex* pindex = chainActive.Tip();
    if(pindex == NULL) return false;

    if(pindex->nTime + 600 < GetTime())
        return false;

    fBlockchainSynced = true;

    return true;
}

void CMasternodeSync::Reset()
{
    lastMasternodeList = 0;
    lastMasternodeWinner = 0;
    lastBudgetItem = 0;
    lastFailure = 0;
    nCountFailures = 0;
    sumMasternodeList = 0;
    sumMasternodeWinner = 0;
    sumBudgetItemProp = 0;
    sumBudgetItemFin = 0;
    countMasternodeList = 0;
    countMasternodeWinner = 0;
    countBudgetItemProp = 0;
    countBudgetItemFin = 0;
    RequestedMasternodeAssets = MASTERNODE_SYNC_INITIAL;
    RequestedMasternodeAttempt = 0;
}

void CMasternodeSync::AddedMasternodeList()
{
    lastMasternodeList = GetTime();
}

void CMasternodeSync::AddedMasternodeWinner()
{
    lastMasternodeWinner = GetTime();
}

void CMasternodeSync::AddedBudgetItem()
{
    lastBudgetItem = GetTime();
}

bool CMasternodeSync::IsBudgetPropEmpty()
{
    return sumBudgetItemProp==0 && countBudgetItemProp>0;
}

bool CMasternodeSync::IsBudgetFinEmpty()
{
    return sumBudgetItemFin==0 && countBudgetItemFin>0;
}

void CMasternodeSync::GetNextAsset()
{
    switch(RequestedMasternodeAssets)
    {
        case(MASTERNODE_SYNC_INITIAL):
        case(MASTERNODE_SYNC_FAILED): // should never be used here actually, use Reset() instead
            ClearFulfilledRequest();
            RequestedMasternodeAssets = MASTERNODE_SYNC_SPORKS;
            break;
        case(MASTERNODE_SYNC_SPORKS):
            RequestedMasternodeAssets = MASTERNODE_SYNC_LIST;
            break;
        case(MASTERNODE_SYNC_LIST):
            RequestedMasternodeAssets = MASTERNODE_SYNC_MNW;
            break;
        case(MASTERNODE_SYNC_MNW):
            RequestedMasternodeAssets = MASTERNODE_SYNC_BUDGET;
            break;
        case(MASTERNODE_SYNC_BUDGET):
            LogPrintf("CMasternodeSync::GetNextAsset - Sync has finished\n");
            RequestedMasternodeAssets = MASTERNODE_SYNC_FINISHED;
            break;
    }
    RequestedMasternodeAttempt = 0;
}

void CMasternodeSync::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
{
    if (strCommand == "ssc") { //Sync status count
        int nItemID;
        int nCount;
        vRecv >> nItemID >> nCount;

        if(RequestedMasternodeAssets >= MASTERNODE_SYNC_FINISHED) return;

        //this means we will receive no further communication
        switch(nItemID)
        {
            case(MASTERNODE_SYNC_LIST):
                if(nItemID != RequestedMasternodeAssets) return;
                if(nCount == 0) lastMasternodeList = GetTime();
                sumMasternodeList += nCount;
                countMasternodeList++;
                break;
            case(MASTERNODE_SYNC_MNW):
                if(nItemID != RequestedMasternodeAssets) return;
                if(nCount == 0) lastMasternodeWinner = GetTime();
                sumMasternodeWinner += nCount;
                countMasternodeWinner++;
                break;
            case(MASTERNODE_SYNC_BUDGET_PROP):
                if(RequestedMasternodeAssets != MASTERNODE_SYNC_BUDGET) return;
                if(nCount == 0) lastBudgetItem = GetTime();
                sumBudgetItemProp += nCount;
                countBudgetItemProp++;
                break;
            case(MASTERNODE_SYNC_BUDGET_FIN):
                if(RequestedMasternodeAssets != MASTERNODE_SYNC_BUDGET) return;
                if(nCount == 0) lastBudgetItem = GetTime();
                sumBudgetItemFin += nCount;
                countBudgetItemFin++;
                break;
        }

        LogPrintf("CMasternodeSync:ProcessMessage - ssc - got inventory count %d %d\n", nItemID, nCount);
    }
}

void CMasternodeSync::ClearFulfilledRequest()
{
    TRY_LOCK(cs_vNodes, lockRecv);
    if(!lockRecv) return;

    BOOST_FOREACH(CNode* pnode, vNodes)
    {
        pnode->ClearFulfilledRequest("getspork");
        pnode->ClearFulfilledRequest("mnsync");
        pnode->ClearFulfilledRequest("mnwsync");
        pnode->ClearFulfilledRequest("busync");
    }
}

void CMasternodeSync::Process()
{
    static int tick = 0;

    if(tick++ % MASTERNODE_SYNC_TIMEOUT != 0) return;

    if(IsSynced()) {
        /*
            Resync if we lose all masternodes from sleep/wake or failure to sync originally
        */
        if(mnodeman.CountEnabled() == 0) {
            Reset();
        } else
            return;
    }

    //try syncing again in an hour
    if(RequestedMasternodeAssets == MASTERNODE_SYNC_FAILED && lastFailure + (60*60) < GetTime()) {
        Reset();
    } else if (RequestedMasternodeAssets == MASTERNODE_SYNC_FAILED) {
        return;
    }

    if(fDebug) LogPrintf("CMasternodeSync::Process() - tick %d RequestedMasternodeAssets %d\n", tick, RequestedMasternodeAssets);

    if(RequestedMasternodeAssets == MASTERNODE_SYNC_INITIAL) GetNextAsset();

    // sporks synced but blockchain is not, wait until we're almost at a recent block to continue
    if(Params().NetworkID() != CBaseChainParams::REGTEST &&
            !IsBlockchainSynced() && RequestedMasternodeAssets > MASTERNODE_SYNC_SPORKS) return;

    TRY_LOCK(cs_vNodes, lockRecv);
    if(!lockRecv) return;

    BOOST_FOREACH(CNode* pnode, vNodes)
    {
        if(Params().NetworkID() == CBaseChainParams::REGTEST){
            if(RequestedMasternodeAttempt <= 2) {
                pnode->PushMessage("getsporks"); //get current network sporks
            } else if(RequestedMasternodeAttempt < 4) {
                mnodeman.DsegUpdate(pnode);
            } else if(RequestedMasternodeAttempt < 6) {
                int nMnCount = mnodeman.CountEnabled()*2;
                pnode->PushMessage("mnget", nMnCount); //sync payees
                uint256 n = 0;
                pnode->PushMessage("mnvs", n); //sync masternode votes
            } else {
                RequestedMasternodeAssets = MASTERNODE_SYNC_FINISHED;
            }
            RequestedMasternodeAttempt++;
            return;
        }

        //set to synced
        if(RequestedMasternodeAssets == MASTERNODE_SYNC_SPORKS){
            if(pnode->HasFulfilledRequest("getspork")) continue;
            pnode->FulfilledRequest("getspork");

            pnode->PushMessage("getsporks"); //get current network sporks
            if(RequestedMasternodeAttempt >= 2) GetNextAsset();
            RequestedMasternodeAttempt++;

            return;
        }

        if (pnode->nVersion >= masternodePayments.GetMinMasternodePaymentsProto()) {

            if(RequestedMasternodeAssets == MASTERNODE_SYNC_LIST) {
                if(fDebug) LogPrintf("CMasternodeSync::Process() - lastMasternodeList %lld (GetTime() - MASTERNODE_SYNC_TIMEOUT) %lld\n", lastMasternodeList, GetTime() - MASTERNODE_SYNC_TIMEOUT);
                if(lastMasternodeList > 0 && lastMasternodeList < GetTime() - MASTERNODE_SYNC_TIMEOUT && RequestedMasternodeAttempt >= 4){ //hasn't received a new item in the last five seconds, so we'll move to the
                    GetNextAsset();
                    return;
                }

                if(pnode->HasFulfilledRequest("mnsync")) continue;
                pnode->FulfilledRequest("mnsync");

                mnodeman.DsegUpdate(pnode);
                RequestedMasternodeAttempt++;
                return;
            }

            if(RequestedMasternodeAssets == MASTERNODE_SYNC_MNW) {
                if(lastMasternodeWinner > 0 && lastMasternodeWinner < GetTime() - MASTERNODE_SYNC_TIMEOUT && RequestedMasternodeAttempt >= 4){ //hasn't received a new item in the last five seconds, so we'll move to the
                    GetNextAsset();
                    return;
                }

                if(pnode->HasFulfilledRequest("mnwsync")) continue;
                pnode->FulfilledRequest("mnwsync");

                CBlockIndex* pindexPrev = chainActive.Tip();
                if(pindexPrev == NULL) return;

                int nMnCount = mnodeman.CountEnabled()*2;
                pnode->PushMessage("mnget", nMnCount); //sync payees
                RequestedMasternodeAttempt++;

                return;
            }
        }

        if (pnode->nVersion >= MIN_BUDGET_PEER_PROTO_VERSION) {

            if(RequestedMasternodeAssets == MASTERNODE_SYNC_BUDGET){
                //we'll start rejecting votes if we accidentally get set as synced too soon
                if(lastBudgetItem > 0 && lastBudgetItem < GetTime() - MASTERNODE_SYNC_TIMEOUT && RequestedMasternodeAttempt >= 4){ //hasn't received a new item in the last five seconds, so we'll move to the
                    //LogPrintf("CMasternodeSync::Process - HasNextFinalizedBudget %d nCountFailures %d IsBudgetPropEmpty %d\n", budget.HasNextFinalizedBudget(), nCountFailures, IsBudgetPropEmpty());
                    //if(budget.HasNextFinalizedBudget() || nCountFailures >= 2 || IsBudgetPropEmpty()) {
                        GetNextAsset();

                        //try to activate our masternode if possible
                        activeMasternode.ManageStatus();
                    // } else { //we've failed to sync, this state will reject the next budget block
                    //     LogPrintf("CMasternodeSync::Process - ERROR - Sync has failed, will retry later\n");
                    //     RequestedMasternodeAssets = MASTERNODE_SYNC_FAILED;
                    //     RequestedMasternodeAttempt = 0;
                    //     lastFailure = GetTime();
                    //     nCountFailures++;
                    // }
                    return;
                }

                if(pnode->HasFulfilledRequest("busync")) continue;
                pnode->FulfilledRequest("busync");

                uint256 n = 0;
                pnode->PushMessage("mnvs", n); //sync masternode votes
                RequestedMasternodeAttempt++;

                return;
            }

        }
    }
}
<|endoftext|>


<commit_before>
#include <sys/wait.h>
#include <algorithm>

#include "config/gems_root.hh"
#include "mem/ruby/libruby_internal.hh"
#include "mem/ruby/system/RubyPort.hh"
#include "mem/ruby/system/System.hh"
#include "mem/ruby/eventqueue/RubyEventQueue.hh"
#include "mem/ruby/system/MemoryVector.hh"
#include "mem/ruby/common/Address.hh"
#include "mem/ruby/recorder/Tracer.hh"

string RubyRequestType_to_string(const RubyRequestType& obj)
{
  switch(obj) {
  case RubyRequestType_IFETCH:
    return "IFETCH";
  case RubyRequestType_LD:
    return "LD";
  case RubyRequestType_ST:
    return "ST";
  case RubyRequestType_Locked_Read:
    return "Locked_Read";
  case RubyRequestType_Locked_Write:
    return "Locked_Write";
  case RubyRequestType_RMW_Read:
    return "RMW_Read";
  case RubyRequestType_RMW_Write:
    return "RMW_Write";
  case RubyRequestType_NULL:
  default:
    assert(0);
    return "";
  }
}

RubyRequestType string_to_RubyRequestType(std::string str)
{
  if (str == "IFETCH")
    return RubyRequestType_IFETCH;
  else if (str == "LD")
    return RubyRequestType_LD;
  else if (str == "ST")
    return RubyRequestType_ST;
  else if (str == "Locked_Read")
    return RubyRequestType_Locked_Read;
  else if (str == "Locked_Write")
    return RubyRequestType_Locked_Write;
  else if (str == "RMW_Read")
    return RubyRequestType_RMW_Read;
  else if (str == "RMW_Write")
    return RubyRequestType_RMW_Write;
  else
    assert(0);
  return RubyRequestType_NULL;
}

ostream& operator<<(ostream& out, const RubyRequestType& obj)
{
  out << RubyRequestType_to_string(obj);
  out << flush;
  return out;
}

ostream& operator<<(std::ostream& out, const RubyRequest& obj)
{
  out << hex << "0x" << obj.paddr << flush;
  return out;
}

vector<string> tokenizeString(string str, string delims)
{
  vector<string> tokens;
  char* pch;
  char* tmp;
  const char* c_delims = delims.c_str();
  tmp = new char[str.length()+1];
  strcpy(tmp, str.c_str());
  pch = strtok(tmp, c_delims);
  while (pch != NULL) {
    string tmp_str(pch);
    if (tmp_str == "null") tmp_str = "";
    tokens.push_back(tmp_str);

    pch = strtok(NULL, c_delims);
  }
  delete [] tmp;
  return tokens;
}

/*
 * The current state of M5/Ruby integration breaks the libruby
 * interface.  This code is ifdef'd out for now so that we can move
 * forward with the integration process for non-libruby uses.  We'll
 * have to go back and resolve the libruby compatibility issue at a
 * later date.
 */
#if 0
void libruby_init(const char* cfg_filename)
{
  ifstream cfg_output(cfg_filename);

  vector<RubyObjConf> * sys_conf = new vector<RubyObjConf>;

  string line;
  getline(cfg_output, line) ;
  while ( !cfg_output.eof() ) {
    vector<string> tokens = tokenizeString(line, " ");
    assert(tokens.size() >= 2);
    vector<string> argv;
    for (size_t i=2; i<tokens.size(); i++) {
      std::replace(tokens[i].begin(), tokens[i].end(), '%', ' ');
      std::replace(tokens[i].begin(), tokens[i].end(), '#', '\n');
      argv.push_back(tokens[i]);
    }
    sys_conf->push_back(RubyObjConf(tokens[0], tokens[1], argv));
    tokens.clear();
    argv.clear();
    getline(cfg_output, line);
  }

  RubySystem::create(*sys_conf);
  delete sys_conf;
}
#endif

RubyPortHandle libruby_get_port(const char* port_name, void (*hit_callback)(int64_t access_id))
{
  return static_cast<RubyPortHandle>(RubySystem::getPort(port_name, hit_callback));
}

RubyPortHandle libruby_get_port_by_name(const char* port_name)
{
  return static_cast<RubyPortHandle>(RubySystem::getPortOnly(port_name));
}

void libruby_write_ram(uint64_t paddr, uint8_t* data, int len)
{
  RubySystem::getMemoryVector()->write(Address(paddr), data, len);
}

void libruby_read_ram(uint64_t paddr, uint8_t* data, int len)
{
  RubySystem::getMemoryVector()->read(Address(paddr), data, len);
}

int64_t libruby_issue_request(RubyPortHandle p, struct RubyRequest request)
{
  return static_cast<RubyPort*>(p)->makeRequest(request);
}

int libruby_tick(int n)
{
  RubySystem::getEventQueue()->triggerEvents(RubySystem::getEventQueue()->getTime() + n);
  return 0;
}

void libruby_destroy()
{
}

const char* libruby_last_error()
{
  return "";
}

void libruby_print_config(std::ostream & out)
{
  RubySystem::printConfig(out);
}

void libruby_print_stats(std::ostream & out)
{
  RubySystem::printStats(out);
}
void libruby_playback_trace(char * trace_filename)
{
  RubySystem::getTracer()->playbackTrace(trace_filename);
}

void libruby_start_tracing(char * record_filename) {
  // start the trace
  RubySystem::getTracer()->startTrace(record_filename);
}

void libruby_stop_tracing() {
  // start the trace
  RubySystem::getTracer()->stopTrace();
}

uint64_t libruby_get_time() {
  return RubySystem::getCycleCount(0);
}
<commit_msg>ruby: added data print to ruby request<commit_after>
#include <sys/wait.h>
#include <algorithm>

#include "config/gems_root.hh"
#include "mem/ruby/libruby_internal.hh"
#include "mem/ruby/system/RubyPort.hh"
#include "mem/ruby/system/System.hh"
#include "mem/ruby/eventqueue/RubyEventQueue.hh"
#include "mem/ruby/system/MemoryVector.hh"
#include "mem/ruby/common/Address.hh"
#include "mem/ruby/recorder/Tracer.hh"

string RubyRequestType_to_string(const RubyRequestType& obj)
{
  switch(obj) {
  case RubyRequestType_IFETCH:
    return "IFETCH";
  case RubyRequestType_LD:
    return "LD";
  case RubyRequestType_ST:
    return "ST";
  case RubyRequestType_Locked_Read:
    return "Locked_Read";
  case RubyRequestType_Locked_Write:
    return "Locked_Write";
  case RubyRequestType_RMW_Read:
    return "RMW_Read";
  case RubyRequestType_RMW_Write:
    return "RMW_Write";
  case RubyRequestType_NULL:
  default:
    assert(0);
    return "";
  }
}

RubyRequestType string_to_RubyRequestType(std::string str)
{
  if (str == "IFETCH")
    return RubyRequestType_IFETCH;
  else if (str == "LD")
    return RubyRequestType_LD;
  else if (str == "ST")
    return RubyRequestType_ST;
  else if (str == "Locked_Read")
    return RubyRequestType_Locked_Read;
  else if (str == "Locked_Write")
    return RubyRequestType_Locked_Write;
  else if (str == "RMW_Read")
    return RubyRequestType_RMW_Read;
  else if (str == "RMW_Write")
    return RubyRequestType_RMW_Write;
  else
    assert(0);
  return RubyRequestType_NULL;
}

ostream& operator<<(ostream& out, const RubyRequestType& obj)
{
  out << RubyRequestType_to_string(obj);
  out << flush;
  return out;
}

ostream& operator<<(std::ostream& out, const RubyRequest& obj)
{
  out << hex << "0x" << obj.paddr << " data: 0x" << flush;
  for (int i = 0; i < obj.len; i++) {
    out << (int)obj.data[i];
  }
  out << dec << " type: " << RubyRequestType_to_string(obj.type) << endl;
  return out;
}

vector<string> tokenizeString(string str, string delims)
{
  vector<string> tokens;
  char* pch;
  char* tmp;
  const char* c_delims = delims.c_str();
  tmp = new char[str.length()+1];
  strcpy(tmp, str.c_str());
  pch = strtok(tmp, c_delims);
  while (pch != NULL) {
    string tmp_str(pch);
    if (tmp_str == "null") tmp_str = "";
    tokens.push_back(tmp_str);

    pch = strtok(NULL, c_delims);
  }
  delete [] tmp;
  return tokens;
}

/*
 * The current state of M5/Ruby integration breaks the libruby
 * interface.  This code is ifdef'd out for now so that we can move
 * forward with the integration process for non-libruby uses.  We'll
 * have to go back and resolve the libruby compatibility issue at a
 * later date.
 */
#if 0
void libruby_init(const char* cfg_filename)
{
  ifstream cfg_output(cfg_filename);

  vector<RubyObjConf> * sys_conf = new vector<RubyObjConf>;

  string line;
  getline(cfg_output, line) ;
  while ( !cfg_output.eof() ) {
    vector<string> tokens = tokenizeString(line, " ");
    assert(tokens.size() >= 2);
    vector<string> argv;
    for (size_t i=2; i<tokens.size(); i++) {
      std::replace(tokens[i].begin(), tokens[i].end(), '%', ' ');
      std::replace(tokens[i].begin(), tokens[i].end(), '#', '\n');
      argv.push_back(tokens[i]);
    }
    sys_conf->push_back(RubyObjConf(tokens[0], tokens[1], argv));
    tokens.clear();
    argv.clear();
    getline(cfg_output, line);
  }

  RubySystem::create(*sys_conf);
  delete sys_conf;
}
#endif

RubyPortHandle libruby_get_port(const char* port_name, void (*hit_callback)(int64_t access_id))
{
  return static_cast<RubyPortHandle>(RubySystem::getPort(port_name, hit_callback));
}

RubyPortHandle libruby_get_port_by_name(const char* port_name)
{
  return static_cast<RubyPortHandle>(RubySystem::getPortOnly(port_name));
}

void libruby_write_ram(uint64_t paddr, uint8_t* data, int len)
{
  RubySystem::getMemoryVector()->write(Address(paddr), data, len);
}

void libruby_read_ram(uint64_t paddr, uint8_t* data, int len)
{
  RubySystem::getMemoryVector()->read(Address(paddr), data, len);
}

int64_t libruby_issue_request(RubyPortHandle p, struct RubyRequest request)
{
  return static_cast<RubyPort*>(p)->makeRequest(request);
}

int libruby_tick(int n)
{
  RubySystem::getEventQueue()->triggerEvents(RubySystem::getEventQueue()->getTime() + n);
  return 0;
}

void libruby_destroy()
{
}

const char* libruby_last_error()
{
  return "";
}

void libruby_print_config(std::ostream & out)
{
  RubySystem::printConfig(out);
}

void libruby_print_stats(std::ostream & out)
{
  RubySystem::printStats(out);
}
void libruby_playback_trace(char * trace_filename)
{
  RubySystem::getTracer()->playbackTrace(trace_filename);
}

void libruby_start_tracing(char * record_filename) {
  // start the trace
  RubySystem::getTracer()->startTrace(record_filename);
}

void libruby_stop_tracing() {
  // start the trace
  RubySystem::getTracer()->stopTrace();
}

uint64_t libruby_get_time() {
  return RubySystem::getCycleCount(0);
}
<|endoftext|>


<commit_before>/*
 * This file is part of the CN24 semantic segmentation software,
 * copyright (C) 2015 Clemens-Alexander Brust (ikosa dot de at gmail dot com).
 *
 * For licensing information, see the LICENSE file included with this project.
 */
#include "Log.h"

#include <cstring>

#include "ResizeLayer.h"
#include "Init.h"

#include "ConfigParsing.h"

#ifdef BUILD_OPENMP
#include <omp.h>
#endif

namespace Conv {

ResizeLayer::ResizeLayer (const unsigned int borderx,
			  const unsigned int bordery) :
			  borderx_(borderx), bordery_(bordery) {
  LOGDEBUG << "Instance created, border size: (" << borderx << ", "
  << bordery << ")";
}

ResizeLayer::ResizeLayer (std::string configuration)
: SimpleLayer(configuration) {
  borderx_ = 0;
  bordery_ = 0;
  ParseKernelSizeIfPossible(configuration, "border", borderx_, bordery_);
}

bool ResizeLayer::CreateOutputs (const std::vector< CombinedTensor* >& inputs,
                                  std::vector< CombinedTensor* >& outputs) {
  // This is a simple layer, only one input
  if (inputs.size() != 1) {
    LOGERROR << "Only one input supported!";
    return false;
  }

  // Save input node pointer
  CombinedTensor* input = inputs[0];

  // Check if input node pointer is null
  if (input == nullptr) {
    LOGERROR << "Null pointer input node!";
    return false;
  }

  // Create output
  CombinedTensor* output = new CombinedTensor (input->data.samples(),
					       input->data.width() + borderx_,
					       input->data.height() + bordery_,
					       input->data.maps() );
  // Tell network about the output
  outputs.push_back (output);

  return true;
}

bool ResizeLayer::Connect (const CombinedTensor* input,
                            CombinedTensor* output) {
  if (input == nullptr || output == nullptr) {
    FATAL ("Null pointer given!");
    return false;
  }

  if (input->data.maps() != output->data.maps() ||
      input->data.width() + borderx_ != output->data.width() ||
      input->data.height() + bordery_ != output->data.height() ||
      input->data.samples() != output->data.samples()) {
    FATAL ("Dimensions don't match!");
    return false;
  }

  return true;
}

void ResizeLayer::FeedForward() {
#ifdef BUILD_OPENCL
  output_->data.MoveToCPU(true);
  input_->data.MoveToCPU();
#endif

  output_->data.Clear(0.0);
#pragma omp parallel for default(shared)
  for(unsigned int sample = 0; sample < input_->data.samples(); sample++) {
    for(unsigned int map = 0; map < input_->data.maps(); map++) {
      for(unsigned int y = 0; y < input_->data.height(); y++) {
	const datum* const source =
	  input_->data.data_ptr_const(0, y, map, sample);
	datum* const target =
	  output_->data.data_ptr(borderx_ / 2, y + (bordery_ / 2), map, sample);

	std::memcpy(target, source, sizeof(datum) * input_->data.width());
      }
    }
  }
}

void ResizeLayer::BackPropagate() {
  // Nothing to do here
}

bool ResizeLayer::IsOpenCLAware() {
#ifdef BUILD_OPENCL
  return true;
#else
  return false;
#endif
}

}
<commit_msg>ResizeLayer: Added backpropagation just in case<commit_after>/*
 * This file is part of the CN24 semantic segmentation software,
 * copyright (C) 2015 Clemens-Alexander Brust (ikosa dot de at gmail dot com).
 *
 * For licensing information, see the LICENSE file included with this project.
 */
#include "Log.h"

#include <cstring>

#include "ResizeLayer.h"
#include "Init.h"

#include "ConfigParsing.h"

#ifdef BUILD_OPENMP
#include <omp.h>
#endif

namespace Conv {

ResizeLayer::ResizeLayer (const unsigned int borderx,
			  const unsigned int bordery) :
			  borderx_(borderx), bordery_(bordery) {
  LOGDEBUG << "Instance created, border size: (" << borderx << ", "
  << bordery << ")";
}

ResizeLayer::ResizeLayer (std::string configuration)
: SimpleLayer(configuration) {
  borderx_ = 0;
  bordery_ = 0;
  ParseKernelSizeIfPossible(configuration, "border", borderx_, bordery_);
}

bool ResizeLayer::CreateOutputs (const std::vector< CombinedTensor* >& inputs,
                                  std::vector< CombinedTensor* >& outputs) {
  // This is a simple layer, only one input
  if (inputs.size() != 1) {
    LOGERROR << "Only one input supported!";
    return false;
  }

  // Save input node pointer
  CombinedTensor* input = inputs[0];

  // Check if input node pointer is null
  if (input == nullptr) {
    LOGERROR << "Null pointer input node!";
    return false;
  }

  // Create output
  CombinedTensor* output = new CombinedTensor (input->data.samples(),
					       input->data.width() + borderx_,
					       input->data.height() + bordery_,
					       input->data.maps() );
  // Tell network about the output
  outputs.push_back (output);

  return true;
}

bool ResizeLayer::Connect (const CombinedTensor* input,
                            CombinedTensor* output) {
  if (input == nullptr || output == nullptr) {
    FATAL ("Null pointer given!");
    return false;
  }

  if (input->data.maps() != output->data.maps() ||
      input->data.width() + borderx_ != output->data.width() ||
      input->data.height() + bordery_ != output->data.height() ||
      input->data.samples() != output->data.samples()) {
    FATAL ("Dimensions don't match!");
    return false;
  }

  return true;
}

void ResizeLayer::FeedForward() {
#ifdef BUILD_OPENCL
  output_->data.MoveToCPU(true);
  input_->data.MoveToCPU();
#endif

  output_->data.Clear(0.0);
#pragma omp parallel for default(shared)
  for(unsigned int sample = 0; sample < input_->data.samples(); sample++) {
    for(unsigned int map = 0; map < input_->data.maps(); map++) {
      for(unsigned int y = 0; y < input_->data.height(); y++) {
	const datum* const source =
	  input_->data.data_ptr_const(0, y, map, sample);
	datum* const target =
	  output_->data.data_ptr(borderx_ / 2, y + (bordery_ / 2), map, sample);

	std::memcpy(target, source, sizeof(datum) * input_->data.width());
      }
    }
  }
}

void ResizeLayer::BackPropagate() {
  // Nothing to do here
  if(backprop_enabled_) {
#ifdef BUILD_OPENCL
    input_->delta.MoveToCPU(true);
    output_->delta.MoveToCPU();
#endif

    input_->delta.Clear(0.0);
#pragma omp parallel for default(shared)
    for(unsigned int sample = 0; sample < input_->data.samples(); sample++) {
      for(unsigned int map = 0; map < input_->data.maps(); map++) {
        for(unsigned int y = 0; y < input_->data.height(); y++) {
  	datum* const target =
  	  input_->delta.data_ptr(0, y, map, sample);
  	const datum* const source =
  	  output_->delta.data_ptr_const(borderx_ / 2, y + (bordery_ / 2), map, sample);

  	std::memcpy(target, source, sizeof(datum) * input_->delta.width());
        }
      }
    }

  }
}

bool ResizeLayer::IsOpenCLAware() {
#ifdef BUILD_OPENCL
  return true;
#else
  return false;
#endif
}

}
<|endoftext|>