text:
#ifndef GAME_MWWORLD_CELLSTORE_H
#define GAME_MWWORLD_CELLSTORE_H

#include <algorithm>
#include <stdexcept>
#include <boost/shared_ptr.hpp>

#include "livecellref.hpp"
#include "esmstore.hpp"
#include "cellreflist.hpp"

#include <components/esm/fogstate.hpp>

#include "../mwmechanics/pathgrid.hpp"  // TODO: maybe belongs in mwworld

#include "timestamp.hpp"

namespace ESM
{
    struct CellState;
    struct FogState;
}

namespace MWWorld
{
    class Ptr;

    /// \brief Mutable state of a cell
    class CellStore
    {
        public:

            enum State
            {
                State_Unloaded, State_Preloaded, State_Loaded
            };

        private:

            // Even though fog actually belongs to the player and not cells,
            // it makes sense to store it here since we need it once for each cell.
            // Note this is NULL until the cell is explored to save some memory
            boost::shared_ptr<ESM::FogState> mFogState;

            const ESM::Cell *mCell;
            State mState;
            bool mHasState;
            std::vector<std::string> mIds;
            float mWaterLevel;

            MWWorld::TimeStamp mLastRespawn;

            CellRefList<ESM::Activator>         mActivators;
            CellRefList<ESM::Potion>            mPotions;
            CellRefList<ESM::Apparatus>         mAppas;
            CellRefList<ESM::Armor>             mArmors;
            CellRefList<ESM::Book>              mBooks;
            CellRefList<ESM::Clothing>          mClothes;
            CellRefList<ESM::Container>         mContainers;
            CellRefList<ESM::Creature>          mCreatures;
            CellRefList<ESM::Door>              mDoors;
            CellRefList<ESM::Ingredient>        mIngreds;
            CellRefList<ESM::CreatureLevList>   mCreatureLists;
            CellRefList<ESM::ItemLevList>       mItemLists;
            CellRefList<ESM::Light>             mLights;
            CellRefList<ESM::Lockpick>          mLockpicks;
            CellRefList<ESM::Miscellaneous>     mMiscItems;
            CellRefList<ESM::NPC>               mNpcs;
            CellRefList<ESM::Probe>             mProbes;
            CellRefList<ESM::Repair>            mRepairs;
            CellRefList<ESM::Static>            mStatics;
            CellRefList<ESM::Weapon>            mWeapons;

        public:

            CellStore (const ESM::Cell *cell_);

            const ESM::Cell *getCell() const;

            State getState() const;

            bool hasState() const;
            ///< Does this cell have state that needs to be stored in a saved game file?

            bool hasId (const std::string& id) const;
            ///< May return true for deleted IDs when in preload state. Will return false, if cell is
            /// unloaded.

            Ptr search (const std::string& id);
            ///< Will return an empty Ptr if cell is not loaded. Does not check references in
            /// containers.

            Ptr searchViaHandle (const std::string& handle);
            ///< Will return an empty Ptr if cell is not loaded.

            Ptr searchViaActorId (int id);
            ///< Will return an empty Ptr if cell is not loaded.

            float getWaterLevel() const;

            void setWaterLevel (float level);

            void setFog (ESM::FogState* fog);
            ///< \note Takes ownership of the pointer

            ESM::FogState* getFog () const;

            int count() const;
            ///< Return total number of references, including deleted ones.

            void load (const MWWorld::ESMStore &store, std::vector<ESM::ESMReader> &esm);
            ///< Load references from content file.

            void preload (const MWWorld::ESMStore &store, std::vector<ESM::ESMReader> &esm);
            ///< Build ID list from content file.

            /// Call functor (ref) for each reference. functor must return a bool. Returning
            /// false will abort the iteration.
            /// \return Iteration completed?
            ///
            /// \note Creatures and NPCs are handled last.
            template<class Functor>
            bool forEach (Functor& functor)
            {
                mHasState = true;

                return
                    forEachImp (functor, mActivators) &&
                    forEachImp (functor, mPotions) &&
                    forEachImp (functor, mAppas) &&
                    forEachImp (functor, mArmors) &&
                    forEachImp (functor, mBooks) &&
                    forEachImp (functor, mClothes) &&
                    forEachImp (functor, mContainers) &&
                    forEachImp (functor, mDoors) &&
                    forEachImp (functor, mIngreds) &&
                    forEachImp (functor, mItemLists) &&
                    forEachImp (functor, mLights) &&
                    forEachImp (functor, mLockpicks) &&
                    forEachImp (functor, mMiscItems) &&
                    forEachImp (functor, mProbes) &&
                    forEachImp (functor, mRepairs) &&
                    forEachImp (functor, mStatics) &&
                    forEachImp (functor, mWeapons) &&
                    forEachImp (functor, mCreatures) &&
                    forEachImp (functor, mNpcs) &&
                    forEachImp (functor, mCreatureLists);
            }

            bool isExterior() const;

            Ptr searchInContainer (const std::string& id);

            void loadState (const ESM::CellState& state);

            void saveState (ESM::CellState& state) const;

            void writeFog (ESM::ESMWriter& writer) const;

            void readFog (ESM::ESMReader& reader);

            void writeReferences (ESM::ESMWriter& writer) const;

            void readReferences (ESM::ESMReader& reader, const std::map<int, int>& contentFileMap);

            void respawn ();
            ///< Check mLastRespawn and respawn references if necessary. This is a no-op if the cell is not loaded.

            template <class T>
            CellRefList<T>& get() {
                throw std::runtime_error ("Storage for this type not exist in cells");
            }

            bool isPointConnected(const int start, const int end) const;

            std::list<ESM::Pathgrid::Point> aStarSearch(const int start, const int end) const;

        private:

            template<class Functor, class List>
            bool forEachImp (Functor& functor, List& list)
            {
                for (typename List::List::iterator iter (list.mList.begin()); iter!=list.mList.end();
                    ++iter)
                {
                    if (!iter->mData.getCount())
                        continue;
                    if (!functor (MWWorld::Ptr(&*iter, this)))
                        return false;
                }
                return true;
            }

            /// Run through references and store IDs
            void listRefs(const MWWorld::ESMStore &store, std::vector<ESM::ESMReader> &esm);

            void loadRefs(const MWWorld::ESMStore &store, std::vector<ESM::ESMReader> &esm);

            void loadRef (ESM::CellRef& ref, bool deleted, const ESMStore& store);
            ///< Make case-adjustments to \a ref and insert it into the respective container.
            ///
            /// Invalid \a ref objects are silently dropped.

            MWMechanics::PathgridGraph mPathgridGraph;
    };

    template<>
    inline CellRefList<ESM::Activator>& CellStore::get<ESM::Activator>()
    {
        mHasState = true;
        return mActivators;
    }

    template<>
    inline CellRefList<ESM::Potion>& CellStore::get<ESM::Potion>()
    {
        mHasState = true;
        return mPotions;
    }

    template<>
    inline CellRefList<ESM::Apparatus>& CellStore::get<ESM::Apparatus>()
    {
        mHasState = true;
        return mAppas;
    }

    template<>
    inline CellRefList<ESM::Armor>& CellStore::get<ESM::Armor>()
    {
        mHasState = true;
        return mArmors;
    }

    template<>
    inline CellRefList<ESM::Book>& CellStore::get<ESM::Book>()
    {
        mHasState = true;
        return mBooks;
    }

    template<>
    inline CellRefList<ESM::Clothing>& CellStore::get<ESM::Clothing>()
    {
        mHasState = true;
        return mClothes;
    }

    template<>
    inline CellRefList<ESM::Container>& CellStore::get<ESM::Container>()
    {
        mHasState = true;
        return mContainers;
    }

    template<>
    inline CellRefList<ESM::Creature>& CellStore::get<ESM::Creature>()
    {
        mHasState = true;
        return mCreatures;
    }

    template<>
    inline CellRefList<ESM::Door>& CellStore::get<ESM::Door>()
    {
        mHasState = true;
        return mDoors;
    }

    template<>
    inline CellRefList<ESM::Ingredient>& CellStore::get<ESM::Ingredient>()
    {
        mHasState = true;
        return mIngreds;
    }

    template<>
    inline CellRefList<ESM::CreatureLevList>& CellStore::get<ESM::CreatureLevList>()
    {
        mHasState = true;
        return mCreatureLists;
    }

    template<>
    inline CellRefList<ESM::ItemLevList>& CellStore::get<ESM::ItemLevList>()
    {
        mHasState = true;
        return mItemLists;
    }

    template<>
    inline CellRefList<ESM::Light>& CellStore::get<ESM::Light>()
    {
        mHasState = true;
        return mLights;
    }

    template<>
    inline CellRefList<ESM::Lockpick>& CellStore::get<ESM::Lockpick>()
    {
        mHasState = true;
        return mLockpicks;
    }

    template<>
    inline CellRefList<ESM::Miscellaneous>& CellStore::get<ESM::Miscellaneous>()
    {
        mHasState = true;
        return mMiscItems;
    }

    template<>
    inline CellRefList<ESM::NPC>& CellStore::get<ESM::NPC>()
    {
        mHasState = true;
        return mNpcs;
    }

    template<>
    inline CellRefList<ESM::Probe>& CellStore::get<ESM::Probe>()
    {
        mHasState = true;
        return mProbes;
    }

    template<>
    inline CellRefList<ESM::Repair>& CellStore::get<ESM::Repair>()
    {
        mHasState = true;
        return mRepairs;
    }

    template<>
    inline CellRefList<ESM::Static>& CellStore::get<ESM::Static>()
    {
        mHasState = true;
        return mStatics;
    }

    template<>
    inline CellRefList<ESM::Weapon>& CellStore::get<ESM::Weapon>()
    {
        mHasState = true;
        return mWeapons;
    }

    bool operator== (const CellStore& left, const CellStore& right);
    bool operator!= (const CellStore& left, const CellStore& right);
}

#endif

max_stars_repo_name: Bodillium/openmw

max_issues_repo_name: Bodillium/openmw

max_forks_repo_name: Bodillium/openmw


text:
/*

CandyPoker
https://github.com/sweeterthancandy/CandyPoker

MIT License

Copyright (c) 2019 Gerry Candy

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

*/
#include <thread>
#include <numeric>
#include <fstream>
#include <atomic>

#include <boost/format.hpp>
#include <boost/timer/timer.hpp>
#include <boost/log/trivial.hpp>

#include "app/pretty_printer.h"

#include "ps/base/algorithm.h"
#include "ps/base/board_combination_iterator.h"
#include "ps/base/cards.h"
#include "ps/base/frontend.h"
#include "ps/base/holdem_board_decl.h"
#include "ps/base/rank_hasher.h"
#include "ps/base/suit_hasher.h"
#include "ps/base/tree.h"

#include "ps/eval/class_cache.h"
#include "ps/eval/evaluator_6_card_map.h"
#include "ps/eval/instruction.h"
#include "ps/support/config.h"
#include "ps/support/index_sequence.h"

#include "ps/support/command.h"
//#include <boost/program_options.hpp>

using namespace ps;

namespace {

struct frequency_table_observer{
        virtual ~frequency_table_observer()=default;
        virtual void observe(card_vector const& cv, ranking_t r)=0;
        virtual void emit(std::vector<Pretty::LineItem >& lines)const=0;
};
struct frequency_table_observer_excluse_stat : frequency_table_observer{
        using self_type = frequency_table_observer_excluse_stat;
        using order_fun_type = std::function<size_t(std::string const&)>;
        virtual void emit(std::vector<Pretty::LineItem >& lines)const override{
                using namespace Pretty;
                lines.emplace_back(std::vector<std::string>{stat_name(), "Count", "Prob", "Cum"});
                lines.emplace_back(LineBreak);

                std::vector<decltype(&*freq_table_.cbegin())> aux;
                size_t sigma = 0;
                for(auto const& _ : freq_table_){
                        aux.emplace_back(&_);
                        sigma += _.second;
                }
                if( order_fun_){
                        std::sort(aux.begin(), aux.end(), [this](auto const& l, auto const& r){
                                return order_fun_(l->first) > order_fun_(r->first);
                        });
                } else {
                        std::sort(aux.begin(), aux.end(), [](auto const& l, auto const& r){
                                return l->second > r->second;
                        });
                }
                size_t cum_total = 0;
                for(auto const& _ : aux){
                        cum_total += _->second;
                        auto pct = _->second * 100.0 / sigma;
                        auto cum_pct = cum_total * 100.0 / sigma;

                        std::vector<std::string> line;
                        line.push_back(_->first);
                        line.push_back(boost::lexical_cast<std::string>(_->second));
                        line.push_back(boost::lexical_cast<std::string>(pct));
                        line.push_back(boost::lexical_cast<std::string>(cum_pct));

                        lines.push_back(line);
                }
        }
protected:
        virtual std::string stat_name()const{ return "Rank"; }
        void choose(std::string const& tag){
                ++freq_table_[tag];
        }
        self_type& order_with(order_fun_type f){
                order_fun_ = f;
                return *this;
        }
        self_type& decl_row(std::string const& name){
                freq_table_[name];
                return *this;
        }
private:

        order_fun_type order_fun_;
        std::map<std::string, size_t> freq_table_;
};

struct freq_obs_flop_rank : frequency_table_observer_excluse_stat{
        freq_obs_flop_rank(){
                static std::map<std::string, int> aux = {
                        {"Royal Flush"   ,10},
                        {"Straight Flush", 9},
                        {"Quads"         , 8},
                        {"Full House"    , 7},
                        {"Flush"         , 6},
                        {"Straight"      , 5},
                        {"Trips"         , 4},
                        {"Two pair"      , 3},
                        {"One pair"      , 2},
                        {"High Card"     , 1},
                };
                auto f = [_=aux](std::string const& name){
                        return _.find(name)->second;
                };
                order_with(f);
        }
        virtual void observe(card_vector const& cv, ranking_t r)override{
                static rank_world rankdev;
                auto rd = rankdev[r];
                choose(rd.name());
        }
};
struct freq_obs_flush_draw : frequency_table_observer_excluse_stat{
        freq_obs_flush_draw(){
                auto f = [](std::string const& name){
                        return name == "Flush"       ? 3 :
                               name == "Four-Flush"  ? 2 :
                               name == "Three-Flush" ? 1 :
                                                       0
                        ;
                };
                order_with(f);
                decl_row("Flush");
                decl_row("Four-Flush");
                decl_row("Three-Flush");
        }
        virtual void observe(card_vector const& cv, ranking_t r)override{
                auto suit_val = suit_hasher::create(cv);
                auto name = [suit_val](){
                        if( suit_hasher::has_flush(suit_val)){
                                return "Flush";
                        } else if( suit_hasher::has_four_flush(suit_val)){
                                return "Four-Flush";
                        } else if( suit_hasher::has_three_flush(suit_val)){
                                return "Three-Flush";
                        } else {
                                return "None";
                        }
                }();
                choose(name);
        }
        virtual std::string stat_name()const override{ return "Flush Draw"; }
};
namespace permutations{
        static constexpr std::array<size_t, 4> choose_4_5_0 = {  1,2,3,4};
        static constexpr std::array<size_t, 4> choose_4_5_1 = {0,  2,3,4};
        static constexpr std::array<size_t, 4> choose_4_5_2 = {0,1,  3,4};
        static constexpr std::array<size_t, 4> choose_4_5_3 = {0,1,2,  4};
        static constexpr std::array<size_t, 4> choose_4_5_4 = {0,1,2,3  };
        static constexpr std::array<std::array<size_t, 4>, 5> choose_4_5 = {
                choose_4_5_0, choose_4_5_1, choose_4_5_2, choose_4_5_3, choose_4_5_4
        };
} // end namespace permutations

struct freq_obs_straight_draw : frequency_table_observer_excluse_stat{
        freq_obs_straight_draw(){
                // 01234
                for(size_t idx=0;idx+4<13;++idx){
                        auto proto_val = prime_rank_map::create(idx,idx+1,idx+2,idx+3,idx+4);
                        straight_.insert(proto_val);
                }
                // 0123
                for(size_t idx=0;idx+3<13;++idx){
                        auto proto_val = prime_rank_map::create(idx,idx+1,idx+2,idx+3);
                        four_straight_.insert(proto_val);
                }
                //  0_234_6
                for(size_t idx=0;idx+6<13;++idx){
                        auto proto_val = prime_rank_map::create(idx,idx+2,idx+3,idx+4,idx+6);
                        double_gutter_.insert(proto_val);
                }

                auto f = [](std::string const& name){
                        return name == "Straight"       ? 3 :
                               name == "Four-Straight"  ? 2 :
                               name == "Double-Gutter"  ? 1 :
                                                       0
                        ;
                };
                order_with(f);
                decl_row("Straight");
                decl_row("Four-Straight");
                decl_row("Double-Gutter");
        }
        virtual void observe(card_vector const& cv, ranking_t r)override{
                BOOST_ASSERT(cv.size() == 5 );

                auto name = [&](){
                        auto R = prime_rank_map::create(cv);
                        if( straight_.count(R)){
                                return "Straight";
                        }
                        for(size_t idx=0;idx!=5;++idx){
                                auto const& p = permutations::choose_4_5[idx];
                                auto val = prime_rank_map::create_from_cards(cv[p[0]],
                                                                             cv[p[1]],
                                                                             cv[p[2]],
                                                                             cv[p[3]]);
                                if( four_straight_.count(val) ){
                                        return "Four-Straight";
                                }
                        }
                        if( double_gutter_.count(R) ){
                                return "Double-Gutter";
                        }
                        return "None";
                }();
                choose(name);
        }
        virtual std::string stat_name()const override{ return "Straight Draw"; }
private:
        std::set<prime_rank_map::prime_rank_t> straight_;
        std::set<prime_rank_map::prime_rank_t> four_straight_;
        std::set<prime_rank_map::prime_rank_t> double_gutter_;
};
struct freq_obs_flop_rank_user : frequency_table_observer_excluse_stat{
        freq_obs_flop_rank_user(){
                static std::map<std::string, int> aux = {
                        {"Royal Flush"        ,11},
                        {"Straight Flush"     ,10},
                        {"Quads"              , 9},
                        {"Full House"         , 8},
                        {"Flush"              , 7},
                        {"Straight"           , 6},
                        {"Trips"              , 5},
                        {"Two pair"           , 4},
                        {"One pair"           , 3},
                        {"High Card - 2 Overs", 2},
                        {"High Card - 1 Over", 1},
                        {"High Card - Unders" , 0},
                };
                auto f = [_=aux](std::string const& name){
                        return _.find(name)->second;
                };
                order_with(f);
        }
        virtual void observe(card_vector const& cv, ranking_t r)override{
                BOOST_ASSERT(cv.size()==5 && "precondition failed");
                static rank_world rankdev;
                auto rd = rankdev[r];
                auto name = [&]()->std::string{
                        switch(rd.category()){
                        case HR_HighCard:
                        {
                                auto max_board_rank = std::max({card_rank_from_id(cv[0]),
                                                                card_rank_from_id(cv[1]),
                                                                card_rank_from_id(cv[2])});
                                auto max_hand_rank = std::max({card_rank_from_id(cv[3]),
                                                               card_rank_from_id(cv[4])});
                                auto min_hand_rank = std::min({card_rank_from_id(cv[3]),
                                                               card_rank_from_id(cv[4])});
                                if( max_board_rank < min_hand_rank ){
                                        return "High Card - 2 Overs";
                                } else if( max_board_rank < max_hand_rank ){
                                        return "High Card - 1 Over";
                                } else{
                                        return "High Card - Unders";
                                }
                                break;
                        }
                        default:
                                return rd.name();
                        }
                }();
                choose(name);
        }
        virtual std::string stat_name()const override{ return "Detailed Rank"; }
};

struct frequency_table_builder{
        frequency_table_builder(){
        }
        frequency_table_builder& use_observer(std::shared_ptr<frequency_table_observer> ptr){
                obs_.push_back(ptr);
                return *this;
        }
        void add(card_vector const& cv){
                ranking_t R;
                switch(cv.size()){
                case 5:
                        R = eval->rank(cv[0],cv[1],cv[2],cv[3],cv[4]);
                        break;
                case 6:
                        R = eval->rank(cv[0],cv[1],cv[2],cv[3],cv[4],cv[5]);
                        break;
                case 7:
                        R = eval->rank(cv[0],cv[1],cv[2],cv[3],cv[4],cv[5],cv[6]);
                        break;
                default:
                        R = 0;
                }

                for(auto& _ : obs_){
                        _->observe(cv, R);
                }
        }
        void display(std::string const& title)const{
                using namespace Pretty;

                std::vector< LineItem > lines;
                lines.emplace_back(LineBreak);
                bool first = true;
                for(auto& _ : obs_){
                        if( ! first ){
                                lines.emplace_back(LineBreak);
                        }
                        _->emit(lines);
                        first = false;
                }
                lines.emplace_back(LineBreak);
                RenderTablePretty(std::cout, lines);
        }
private:
        evaluator_6_card_map* eval = evaluator_6_card_map::instance();
        std::vector<std::shared_ptr<frequency_table_observer> > obs_;
};

struct FlopZilla : Command{
        enum{ Debug = 1 };
        explicit
        FlopZilla(std::vector<std::string> const& args):args_{args}{}
        virtual int Execute()override{

                enum{ DefaultDealCount = 3};
                size_t deal_count = DefaultDealCount;
                card_vector board;
                holdem_hand_vector hv;
                frontend::range front_range;

                int arg_ptr = 0;
                // first parse options
                for(;arg_ptr < args_.size();){
                        switch(args_.size()-arg_ptr){
                        default:
                        case 2:
                        if( args_[arg_ptr] == "--deal" ){
                                deal_count = boost::lexical_cast<size_t>(args_[arg_ptr+1]);
                                if( ! (3 <= deal_count && deal_count <= 5 ) ){
                                        std::cerr << "bad deal count\n";
                                        return EXIT_FAILURE;
                                }
                                arg_ptr += 2;
                                continue;
                        }
                        if( args_[arg_ptr] == "--board"){
                                std::string board_s = args_[arg_ptr+1];
                                board = card_vector::parse(board_s);
                                if( ! (3 <= board.size() && board.size() <= 5 ) ){
                                        std::cerr << "unable to parse board (" << board_s << ")\n";
                                        return EXIT_FAILURE;
                                }
                                arg_ptr += 2;
                                continue;
                        }
                        case 1:
                                // fallback to implicit option
                        front_range = frontend::parse(args_[arg_ptr]);
                        hv = expand(front_range).to_holdem_vector();
                        ++arg_ptr;
                        }
                }
                if( hv.empty()){
                        std::cerr << "need range\n";
                        return EXIT_FAILURE;
                }
                if( arg_ptr != args_.size()){
                        std::cerr << "unable to parse options at " << args_[arg_ptr] << "\n";
                        return EXIT_FAILURE;
                }

                if( Debug ){
                        std::cout << "board => " << board << "\n"; // __CandyPrint__(cxx-print-scalar,board)
                        std::cout << "front_range => " << front_range << "\n"; // __CandyPrint__(cxx-print-scalar,front_range)
                        std::cout << "expand(front_range) => " << expand(front_range) << "\n"; // __CandyPrint__(cxx-print-scalar,expand(front_range))
                        std::cout << "hv => " << hv << "\n"; // __CandyPrint__(cxx-print-scalar,hv)
                }

                frequency_table_builder freq_table;
                freq_table
                        .use_observer(std::make_shared<freq_obs_flop_rank>())
                        .use_observer(std::make_shared<freq_obs_flush_draw>())
                        .use_observer(std::make_shared<freq_obs_straight_draw>())
                        .use_observer(std::make_shared<freq_obs_flop_rank_user>())
                ;

                if( board.size() ){
                        auto const& b = board;
                        for(size_t idx=0;idx!=hv.size();++idx){
                                auto hd = hv.decl_at(idx);

                                if( b.mask() & hd.mask())
                                        continue;

                                auto full = b;
                                full.push_back(hd.first());
                                full.push_back(hd.second());

                                freq_table.add(full);
                        }
                } else {
                        for(board_combination_iterator iter(deal_count),end;iter!=end;++iter){
                                auto const& b = *iter;

                                for(size_t idx=0;idx!=hv.size();++idx){
                                        auto hd = hv.decl_at(idx);

                                        if( b.mask() & hd.mask())
                                                continue;

                                        auto full = b;
                                        full.push_back(hd.first());
                                        full.push_back(hd.second());

                                        freq_table.add(full);
                                }
                        }
                }

                std::stringstream title;
                title << "FlopZilla for " << args_.at(0);
                freq_table.display(title.str());
                return EXIT_SUCCESS;
        }
private:
        std::vector<std::string> args_;
};
static TrivialCommandDecl<FlopZilla> FlopZillaDecl{"flopzilla"};

struct PokerProbability : Command{
        explicit
        PokerProbability(std::vector<std::string> const& args):args_{args}{}
        virtual int Execute()override{

                frequency_table_builder tab_5;
                tab_5.use_observer(std::make_shared<freq_obs_flop_rank>());
                frequency_table_builder tab_7;
                tab_7.use_observer(std::make_shared<freq_obs_flop_rank>());

                for(board_combination_iterator iter(5),end;iter!=end;++iter){
                        tab_5.add(*iter);
                }
                tab_5.display("5-Card Probability Table");
                for(board_combination_iterator iter(7),end;iter!=end;++iter){
                        tab_7.add(*iter);
                }
                tab_7.display("7-Card Probability Table");
                return EXIT_SUCCESS;
        }
private:
        std::vector<std::string> args_;
};
static TrivialCommandDecl<PokerProbability> PokerProbabilityDecl{"poker-prob"};

/*
        Command that can rank all hands

                <ps> hand-ranking --board 8s7s2d <opt_range>

        From this, every possible hand is then valuatied, and ranked from
        strongest absolute value, to lowest absolute value.
 */
struct HandRanking : Command{
        explicit
        HandRanking(std::vector<std::string> const& args):args_{args}{}
        virtual int Execute()override{

                enum{ Debug = false };

                holdem_hand_vector hv;
                frontend::range front_range;
                card_vector board;

                boost::optional<holdem_id> specific_hand;

                int arg_ptr = 0;
                // first parse options
                for(;arg_ptr < args_.size();){
                        switch(args_.size()-arg_ptr){
                        default:
                        case 2:
                        if( args_[arg_ptr] == "--board"){
                                std::string board_s = args_[arg_ptr+1];
                                board = card_vector::parse(board_s);
                                if( ! (3 <= board.size() && board.size() <= 5 ) ){
                                        std::cerr << "unable to parse board (" << board_s << ")\n";
                                        return EXIT_FAILURE;
                                }
                                arg_ptr += 2;
                                continue;
                        }
                        if( args_[arg_ptr] == "--hand"){
                                std::string s = args_[arg_ptr+1];
                                specific_hand = holdem_hand_decl::parse(s).id();
                                arg_ptr += 2;
                                continue;
                        }
                        case 1:
                                // fallback to implicit option
                        front_range = frontend::parse(args_[arg_ptr]);
                        hv = expand(front_range).to_holdem_vector();
                        ++arg_ptr;
                        }
                }
                if( hv.empty()){
                        hv = expand(frontend::parse("100%")).to_holdem_vector();
                }
                if( Debug ){
                        std::cout << "board => " << board << "\n"; // __CandyPrint__(cxx-print-scalar,board)
                        std::cout << "hv => " << hv << "\n"; // __CandyPrint__(cxx-print-scalar,hv)
                        std::cout << "hv.size() => " << hv.size() << "\n"; // __CandyPrint__(cxx-print-scalar,hv.size())
                }

                evaluator_6_card_map* eval = evaluator_6_card_map::instance();

                std::map<holdem_id, std::vector<ranking_t> > M;

                auto emit = [&](holdem_id id, auto const& cv){
                        // assume that cv makes sense, no doubles etc
                        ranking_t R = eval->rank(board[0],cv[1],cv[2],cv[3],cv[4],cv[5],cv[6]);
                        evaluator_6_card_map* eval = evaluator_6_card_map::instance();
                        M[id].push_back(R);
                };

                card_vector full_board = board;
                full_board.resize(7);
                for(board_combination_iterator iter(2, board),end;iter!=end;++iter){
                        auto const& deal = *iter;

                        if( board.mask() & deal.mask() )
                                continue;
                        auto mask = board.mask() | deal.mask();

                        full_board[3] = deal[0];
                        full_board[4] = deal[1];

                        for(size_t idx=0;idx!=hv.size();++idx){
                                auto hd = hv.decl_at(idx);

                                if( mask & hd.mask())
                                        continue;

                                full_board[5] = hd.first();
                                full_board[6] = hd.second();

                                emit(hv[idx], full_board);
                        }
                }

                std::list<std::tuple<double, holdem_hand_vector > > avg_view;

                for(auto const& p : M ){
                        auto average = std::accumulate(p.second.begin(), p.second.end(), 0) * 1.0 / p.second.size();
                        //std::cout << p.first << "->" << detail::to_string(p.second) << "\n";
                        //std::cout << p.first << "->" << average << "\n";

                        avg_view.emplace_back(average, holdem_hand_vector{p.first});
                }
                avg_view.sort([](auto const& l, auto const& r){
                        return std::get<0>(l) < std::get<0>(r);
                });

                if( avg_view.size()){
                        auto head = avg_view.begin();
                        auto iter = head;
                        ++iter;
                        auto end = avg_view.end();
                        std::vector<decltype(iter)> to_erase;
                        for(;iter!=end;++iter){
                                constexpr double epsilon = 0.001;
                                bool merge_with_head = ( std::fabs(std::get<0>(*head) - std::get<0>(*iter)) < epsilon );
                                if( merge_with_head ){
                                        to_erase.push_back(iter);
                                        std::get<1>(*head).push_back(std::get<1>(*iter).back());
                                } else{
                                        head = iter;
                                }
                        }
                        for(auto const& iter : to_erase ){
                                avg_view.erase(iter);
                        }
                }

                if( Debug ){
                        for(auto const& _ : avg_view ){
                                std::cout << std::get<1>(_) << "->" << std::get<0>(_) << "\n";
                        }
                }

                using namespace Pretty;
                std::vector<LineItem> lines;
                lines.emplace_back(LineBreak);
                if( specific_hand ){
                        lines.emplace_back(std::vector<std::string>{"Hands", "Ranking", "P", "?"});
                } else {
                        lines.emplace_back(std::vector<std::string>{"Hands", "Ranking", "P"});
                }
                lines.emplace_back(LineBreak);
                size_t total_hands = M.size();
                size_t running_total = 0;
                for(auto const& _ : avg_view ){
                        running_total += std::get<1>(_).size();
                        double pct = running_total * 100.0 / total_hands;
                        std::vector<std::string> line{std::get<1>(_).to_string(),
                                boost::lexical_cast<std::string>(std::get<0>(_)),
                                boost::lexical_cast<std::string>(pct)};
                        if( specific_hand ){
                                std::string tag;
                                auto const& v = std::get<1>(_);
                                if( std::find(v.begin(),v.end(),specific_hand.get()) != v.end()){
                                        tag = "x";
                                }
                                line.push_back(tag);
                        }
                        lines.push_back(std::move(line));
                }
                lines.emplace_back(LineBreak);
                RenderTablePretty(std::cout, lines);

                return EXIT_SUCCESS;
        }
private:
        std::vector<std::string> args_;
};
static TrivialCommandDecl<HandRanking> HandRankingDecl{"hand-ranking"};

} // end namespace anon

ext: cpp


text:
// gridfs.cpp

/*    Copyright 2009 10gen
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

#include "mongo/platform/basic.h"

#include "mongo/client/gridfs.h"

#include <algorithm>
#include <boost/smart_ptr.hpp>
#include <fcntl.h>
#include <fstream>
#include <iostream>
#include <utility>

#if defined(_WIN32)
#include <io.h>
#endif

#include "mongo/client/dbclientcursor.h"

#ifndef MIN
#define MIN(a,b) ( (a) < (b) ? (a) : (b) )
#endif

namespace mongo {

    using std::min;
    using std::auto_ptr;
    using std::cout;
    using std::ios;
    using std::ofstream;
    using std::ostream;
    using std::string;

    const unsigned DEFAULT_CHUNK_SIZE = 255 * 1024;

    GridFSChunk::GridFSChunk( BSONObj o ) {
        _data = o;
    }

    GridFSChunk::GridFSChunk( BSONObj fileObject , int chunkNumber , const char * data , int len ) {
        BSONObjBuilder b;
        b.appendAs( fileObject["_id"] , "files_id" );
        b.append( "n" , chunkNumber );
        b.appendBinData( "data" , len, BinDataGeneral, data );
        _data = b.obj();
    }

    GridFS::GridFS( DBClientBase& client , const string& dbName , const string& prefix ) : _client( client ) , _dbName( dbName ) , _prefix( prefix ) {
        _filesNS = dbName + "." + prefix + ".files";
        _chunksNS = dbName + "." + prefix + ".chunks";
        _chunkSize = DEFAULT_CHUNK_SIZE;

        client.createIndex( _filesNS , BSON( "filename" << 1 ) );
        client.createIndex( _chunksNS , IndexSpec().addKeys(BSON( "files_id" << 1 << "n" << 1 )).unique() );
    }

    GridFS::~GridFS() {

    }

    void GridFS::setChunkSize(unsigned int size) {
        massert( 13296 , "invalid chunk size is specified", (size != 0 ));
        _chunkSize = size;
    }

    unsigned int GridFS::getChunkSize() const {
        return _chunkSize;
    }

    BSONObj GridFS::storeFile( const char* data , size_t length , const string& remoteName , const string& contentType) {
        char const * const end = data + length;

        OID id;
        id.init();
        BSONObj idObj = BSON("_id" << id);

        int chunkNumber = 0;
        while (data < end) {
            int chunkLen = MIN(_chunkSize, (unsigned)(end-data));
            GridFSChunk c(idObj, chunkNumber, data, chunkLen);
            _client.insert( _chunksNS.c_str() , c._data );

            chunkNumber++;
            data += chunkLen;
        }

        return insertFile(remoteName, id, length, contentType);
    }

    BSONObj GridFS::storeFile( const string& fileName , const string& remoteName , const string& contentType) {
        FILE* fd;
        if (fileName == "-")
            fd = stdin;
        else
            fd = fopen( fileName.c_str() , "rb" );
        uassert( 10013 , "error opening file", fd);

        OID id;
        id.init();
        BSONObj idObj = BSON("_id" << id);

        int chunkNumber = 0;
        gridfs_offset length = 0;
        while (!feof(fd)) {
            //boost::scoped_array<char>buf (new char[_chunkSize+1]);
            char * buf = new char[_chunkSize+1];
            char* bufPos = buf;//.get();
            unsigned int chunkLen = 0; // how much in the chunk now
            while(chunkLen != _chunkSize && !feof(fd)) {
                int readLen = fread(bufPos, 1, _chunkSize - chunkLen, fd);
                chunkLen += readLen;
                bufPos += readLen;

                verify(chunkLen <= _chunkSize);
            }

            GridFSChunk c(idObj, chunkNumber, buf, chunkLen);
            _client.insert( _chunksNS.c_str() , c._data );

            length += chunkLen;
            chunkNumber++;
            delete[] buf;
        }

        if (fd != stdin)
            fclose( fd );

        return insertFile((remoteName.empty() ? fileName : remoteName), id, length, contentType);
    }

    BSONObj GridFS::insertFile(const string& name, const OID& id, gridfs_offset length, const string& contentType) {
        // Wait for any pending writebacks to finish
        BSONObj errObj = _client.getLastErrorDetailed();
        uassert( 16428,
                 str::stream() << "Error storing GridFS chunk for file: " << name
                               << ", error: " << errObj,
                 DBClientWithCommands::getLastErrorString(errObj) == "" );

        BSONObj res;
        if ( ! _client.runCommand( _dbName.c_str() , BSON( "filemd5" << id << "root" << _prefix ) , res ) )
            throw UserException( 9008 , "filemd5 failed" );

        BSONObjBuilder file;
        file << "_id" << id
             << "filename" << name
             << "chunkSize" << _chunkSize
             << "uploadDate" << DATENOW
             << "md5" << res["md5"]
             ;

        if (length < 1024*1024*1024) { // 2^30
            file << "length" << (int) length;
        }
        else {
            file << "length" << (long long) length;
        }

        if (!contentType.empty())
            file << "contentType" << contentType;

        BSONObj ret = file.obj();
        _client.insert(_filesNS.c_str(), ret);

        return ret;
    }

    void GridFS::removeFile( const string& fileName ) {
        auto_ptr<DBClientCursor> files = _client.query( _filesNS , BSON( "filename" << fileName ) );
        if (files.get()) {
            while (files->more()) {
                BSONObj file = files->next();
                BSONElement id = file["_id"];
                _client.remove( _filesNS.c_str() , BSON( "_id" << id ) );
                _client.remove( _chunksNS.c_str() , BSON( "files_id" << id ) );
            }
        }
    }

    GridFile::GridFile(const GridFS * grid , BSONObj obj ) {
        _grid = grid;
        _obj = obj;
    }

    GridFile GridFS::findFileByName( const string& fileName ) const {
        return findFile( BSON( "filename" << fileName ) );
    };

    GridFile GridFS::findFile( Query query ) const {
        query.sort(BSON("uploadDate" << -1));
        return GridFile( this , _client.findOne( _filesNS.c_str() , query.obj ) );
    }

    auto_ptr<DBClientCursor> GridFS::list() const {
        return _client.query( _filesNS.c_str() , BSONObj() );
    }

    auto_ptr<DBClientCursor> GridFS::list( BSONObj o ) const {
        return _client.query( _filesNS.c_str() , o );
    }

    void GridFS::_insertChunk( const GridFSChunk& chunk ) {
        _client.insert( _chunksNS.c_str() , chunk._data );
    }

    BSONObj GridFile::getMetadata() const {
        BSONElement meta_element = _obj["metadata"];
        if( meta_element.eoo() ) {
            return BSONObj();
        }

        return meta_element.embeddedObject();
    }

    GridFSChunk GridFile::getChunk( int n ) const {
        _exists();
        BSONObjBuilder b;
        b.appendAs( _obj["_id"] , "files_id" );
        b.append( "n" , n );

        BSONObj o = _grid->_client.findOne( _grid->_chunksNS.c_str() , b.obj() );
        uassert( 10014 ,  "chunk is empty!" , ! o.isEmpty() );
        return GridFSChunk(o);
    }

    gridfs_offset GridFile::write( ostream & out ) const {
        _exists();

        const int num = getNumChunks();

        for ( int i=0; i<num; i++ ) {
            GridFSChunk c = getChunk( i );

            int len;
            const char * data = c.data( len );
            out.write( data , len );
        }

        return getContentLength();
    }

    gridfs_offset GridFile::write( const string& where ) const {
        if (where == "-") {
            return write( cout );
        }
        else {
            ofstream out(where.c_str() , ios::out | ios::binary );
            uassert(13325, "couldn't open file: " + where, out.is_open() );
            return write( out );
        }
    }

    void GridFile::_exists() const {
        uassert( 10015 ,  "doesn't exists" , exists() );
    }

    GridFileBuilder::GridFileBuilder( GridFS* const grid ) :
        _grid( grid ),
        _chunkSize( grid->getChunkSize() ),
        _currentChunk( 0 ),
        _pendingData( new char[_chunkSize] ),
        _pendingDataSize( 0 ),
        _fileLength( 0 ) {
        _fileId.init();
        _fileIdObj = BSON( "_id" << _fileId );
    }

    const char* GridFileBuilder::_appendChunk( const char* data,
                                               size_t length,
                                               bool forcePendingInsert ) {
        const char* const end = data + length;
        while (data < end) {
            size_t chunkLen = min( _chunkSize, static_cast<size_t>(end-data) );
            // the last chunk needs to be stored as pendingData, break while if
            // necessary
            if ((chunkLen < _chunkSize) && (!forcePendingInsert))
                break;
            GridFSChunk chunk( _fileIdObj, _currentChunk, data, chunkLen );
            _grid->_insertChunk( chunk );
            ++_currentChunk;
            data += chunkLen;
            _fileLength += chunkLen;
        }
        return data;
    }

    void GridFileBuilder::_appendPendingData() {
        if (_pendingDataSize > 0) {
            _appendChunk( _pendingData.get(), _pendingDataSize, true );
            _pendingDataSize = 0;
        }
    }

    void GridFileBuilder::appendChunk( const char* data, size_t length ) {
        if (length == 0)
            return;

        // check if there is pending data
        if (_pendingDataSize > 0) {
            size_t totalSize = _pendingDataSize + length;
            size_t size = min( _chunkSize, totalSize ) - _pendingDataSize;
            memcpy( _pendingData.get() + _pendingDataSize, data, size );
            _pendingDataSize += size;
            invariant( _pendingDataSize <= _chunkSize );
            if (_pendingDataSize == _chunkSize) {
                _appendPendingData();
                const char* const end = data + length;
                data = _appendChunk( data + size, length - size, false );
                if (data != end) {
                    invariant(data < end);
                    size_t nsize = static_cast<size_t>(end - data);
                    memcpy( _pendingData.get() + _pendingDataSize, data, nsize );
                    _pendingDataSize += nsize;
                }
            }
        }
        else {
            const char* const end = data + length;
            // split data in _chunkSize blocks, and store as pending the last block if
            // necessary
            data = _appendChunk( data, length, false );
            // process pending data if necessary
            if (data != end) {
                size_t size = static_cast<size_t>(end-data);
                memcpy( _pendingData.get() + _pendingDataSize, data, size );
                _pendingDataSize += size;
            }
        }
    }

    BSONObj GridFileBuilder::buildFile( const string& remoteName,
                                        const string& contentType ) {
        _appendPendingData();
        BSONObj ret = _grid->insertFile( remoteName, _fileId, _fileLength,
                                         contentType );
        // resets the object to allow more data append for a GridFile
        _currentChunk = 0;
        _pendingDataSize = 0;
        _fileLength = 0;
        _fileId.init();
        _fileIdObj = BSON( "_id" << _fileId );
        return ret;
    }

}

max_stars_repo_name: engineer-legion/mongo-cxx-driver

max_issues_repo_name: engineer-legion/mongo-cxx-driver

max_forks_repo_name: engineer-legion/mongo-cxx-driver


text:
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

#include <iostream>

#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/protocol/TDebugProtocol.h>
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TTransportUtils.h>

#include <boost/algorithm/string.hpp>
#include <boost/thread/thread.hpp>
#include "gen-cpp/NetworkTest_types.h"
#include "gen-cpp/NetworkTestService.h"

#include "common/init.h"
#include "common/logging.h"
#include "util/cpu-info.h"
#include "util/stopwatch.h"
#include "rpc/thrift-client.h"
#include "rpc/thrift-server.h"
#include "rpc/thrift-thread.h"

#include "common/names.h"

DEFINE_int32(port, 22222, "Port for NetworkTestService");
DEFINE_int64(send_batch_size, 0, "Batch size (in bytes).  Data is split up into batches");

// Simple client server network speed benchmark utility.  This compiles to
// a binary that runs as both the client and server.  The server can be started
// up by just running the binary.  After the server starts up, it will drop into
// the client 'shell' where benchmarks can be run.
// The supported benchmarks are:
//   'send <size in mb> <target ip>'
//   'broadcast <size in mb> <list of space separated target ips>
// The command can also be passed in via command line in the same format.  If
// run in this mode, the server does not start up.
// For broadcast, the data is sent in parallel to all nodes.
//
// The expected usage for measuring 'send' is to start up the server on one machine
// and issue the send from another.
// For 'broadcast', the server should be started on all the machines and then the
// broadcast is issued from one of them.

using boost::algorithm::is_any_of;
using boost::algorithm::token_compress_on;
using boost::algorithm::split;

using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;
using namespace apache::thrift::server;
using namespace apache::thrift::concurrency;
using namespace impala;
using namespace impalatest;

class TestServer : public NetworkTestServiceIf {
 public:
  TestServer() {
  }

  virtual ~TestServer() {
  }

  virtual void Send(ThriftDataResult& result, const ThriftDataParams& params) {
    result.__set_bytes_received(params.data.size());
  }

  void Server(ThriftServer* server) {
    ABORT_IF_ERROR(server->Start());
    server->Join();
  }
};

// Send bytes to client respecting the batch size
// Returns the rate in mb/s to send the data.
double Send(ThriftClient<NetworkTestServiceClient>* client, int64_t bytes) {
  int64_t batch_size = FLAGS_send_batch_size;
  if (batch_size == 0) batch_size = bytes;
  int64_t total_sent = 0;

  MonotonicStopWatch timer;
  timer.Start();
  while (total_sent < bytes) {
    int64_t send_size = min(bytes - total_sent, batch_size);
    total_sent += send_size;

    ThriftDataParams data;
    ThriftDataResult result;
    data.data.resize(send_size);
    client->iface()->Send(result, data);

    if (result.bytes_received != send_size) {
      return -1;
    }
  }
  timer.Stop();

  double mb = bytes / (1024. * 1024.);
  double sec = timer.ElapsedTime() / (1000.) / (1000.) / (1000.);
  return mb/sec;
}

// Send tokens[1] megabytes to tokens[2]
void HandleSend(const vector<string>& tokens) {
  if (tokens.size() != 3) {
    return;
  }

  int64_t mbs = atoi(tokens[1].c_str());
  int64_t bytes = mbs * (1024L * 1024L);
  cout << "Sending " << mbs << " megabytes..." << endl;
  const string& ip = tokens[2];

  ThriftClient<NetworkTestServiceClient> client(ip, FLAGS_port);
  Status status = client.Open();
  if (!status.ok()) {
    cerr << "Could not connect to server" << endl;
    return;
  }

  double rate = Send(&client, bytes);
  if (rate < 0) {
    cerr << "Send failed";
    return;
  }
  cout << "Send rate: (MB/s): " << rate << endl;
}

// Broadcast tokens[1] megabytes to tokens[2...n] nodes in parallel.
void HandleBroadcast(const vector<string>& tokens) {
  if (tokens.size() <= 2) {
    return;
  }
  int64_t mbs = atoi(tokens[1].c_str());
  int64_t bytes = mbs * (1024L * 1024L);
  cout << "Broadcasting " << mbs << " megabytes..." << endl;

  vector<ThriftClient<NetworkTestServiceClient>* > clients;
  for (int i = 2; i < tokens.size(); ++i) {
    ThriftClient<NetworkTestServiceClient>* client =
        new ThriftClient<NetworkTestServiceClient>(tokens[i], FLAGS_port);
    Status status = client->Open();
    if (!status.ok()) {
      cerr << "Could not connect to server: " << tokens[i] << endl;
      return;
    }
    clients.push_back(client);
  }

  MonotonicStopWatch timer;
  timer.Start();
  thread_group threads;
  for (int i = 0; i < clients.size(); ++i) {
    threads.add_thread(new thread(Send, clients[i], bytes));
  }
  threads.join_all();
  timer.Stop();

  double mb = bytes / (1024 * 1024.);
  double sec = timer.ElapsedTime() / (1000.) / (1000.) / (1000.);

  cout << "Send rate per node: (MB/s) " << (mb/sec) << endl;
  cout << "Send rate cluster: (MB/s) " << (mb * clients.size() / sec) << endl;
}

void ConvertToLowerCase(vector<string>* tokens) {
  for (int i = 0; i < tokens->size(); ++i) {
    transform(
        (*tokens)[i].begin(), (*tokens)[i].end(), (*tokens)[i].begin(), ::tolower);
  }
}

bool ProcessCommand(const vector<string>& tokens) {
  if (tokens.empty()) return false;

  if (tokens[0] == "quit") return true;;

  if (tokens[0] == "send") {
    HandleSend(tokens);
  } else if (tokens[0] == "broadcast") {
    HandleBroadcast(tokens);
  } else {
    cerr << "Invalid command" << endl;
    return false;
  }
  return false;
}

int main(int argc, char** argv) {
  google::ParseCommandLineFlags(&argc, &argv, true);
  impala::InitCommonRuntime(argc, argv, false, impala::TestInfo::BE_TEST);

  if (argc != 1) {
    // Just run client from command line args
    vector<string> tokens;
    for (int i = 1; i < argc; ++i) {
      tokens.push_back(argv[i]);
    }
    ConvertToLowerCase(&tokens);
    ProcessCommand(tokens);
    return 0;
  }

  // Start up server and client shell
  std::shared_ptr<TestServer> handler(new TestServer);
  std::shared_ptr<ThreadFactory> thread_factory(
      new ThriftThreadFactory("test", "test"));
  std::shared_ptr<TProcessor> processor(new NetworkTestServiceProcessor(handler));
  ThriftServer* server;
  ABORT_IF_ERROR(ThriftServerBuilder("Network Test Server", processor, FLAGS_port)
                     .max_concurrent_connections(100)
                     .Build(&server));
  thread* server_thread = new thread(&TestServer::Server, handler.get(), server);

  string input;
  while (1) {
    vector<string> tokens;
    cout << "> ";
    cout.flush();

    getline(cin, input);
    if (cin.eof()) break;

    split(tokens, input, is_any_of(" "), token_compress_on);

    ConvertToLowerCase(&tokens);
    if (ProcessCommand(tokens)) break;
  }

  server->StopForTesting();
  server_thread->join();

  return 0;
}

ext: cc

max_stars_repo_name: Keendata/impala

max_issues_repo_name: xwzbupt/impala

max_forks_repo_name: xwzbupt/impala


text:
/****
   Copyright 2005-2007, Moshe Looks

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
****/

#include "scoring.h"
#include "dtree_modeling.h"

#include <vector>
#include <map>
#include <boost/iterator/counting_iterator.hpp>

namespace alignment {
  static const score_t EPSILON=0.001;

  score_t Scorer::score(const match_pair& p) const {
    score_map::const_iterator it=_map.find(p);
    return (it==_map.end() ? _map.insert
	    (make_pair(p,compute_score(p.first,p.second)-
		       _noise*randfloat())).first :
	    it)->second;
  }
  score_t Scorer::score(const range_pair& p) const {
    if (p.first.first==p.first.second || p.second.first==p.second.second)
      return 0;
    range_score_map::const_iterator it=_rangeMap.find(p);
    return (it==_rangeMap.end() ? _rangeMap.insert
	    (make_pair(p,ordered_match(p)-_noise*randfloat())).first :
	    it)->second;
  }

  score_t Scorer::compute_score(sib_it l,sib_it r) const {
    static const score_t descent_penalty=1;

    //is_empty case taken out for now...
    score_t s=exact_match(l,r)+descent_penalty;
    if (go_down(*l))
      for (sib_it lc=l.begin();lc!=l.end();++lc)
	s=max(s,score(lc,r));
    if (go_down(*r))
      for (sib_it rc=r.begin();rc!=r.end();++rc)
	s=max(s,score(l,rc));
    return s-descent_penalty;
  }

  score_t Scorer::exact_match(sib_it l,sib_it r) const {
    return (matches(*l,*r) ?
	    ((l.begin()==l.end() && r.begin()==r.end()) ?
	     1 :
	     (is_commutative(*l) ?
	      unordered_match(l.begin(),l.end(),r.begin(),r.end()) :
	      (is_associative(*l) ?
	       score(l.begin(),l.end(),r.begin(),r.end()) :
	       exact_match(l.begin(),l.end(),r.begin(),r.end())))) :
	    0);
  }

  score_t Scorer::exact_match(sib_it l1,sib_it l2,
			      sib_it r1,sib_it r2) const {
    score_t res=0;
    for (;l1!=l2;++l1,++r1)
      res+=score(l1,r1);
    return res;
  }

  score_t Scorer::ordered_match(range_pair p) const {
    score_t s=score(p.first.first++,p.second.first++);
    s+=score(p);
    --p.first.first;
    s=max(s,score(p));
    ++p.first.first;
    --p.second.first;
    return max(s,score(p));
  }

  score_t Scorer::unordered_match(sib_it l1,sib_it l2,
				  sib_it r1,sib_it r2) const {
    std::vector<sib_it>
      lmatched(make_counting_iterator(l1),
	       make_counting_iterator(l2)),
      rmatched(make_counting_iterator(r1),
	       make_counting_iterator(r2));
    typedef std::multimap<score_t,pair<int,int>,std::greater<score_t> >
      ScoreMap;
    ScoreMap scores;
    for (int i=0;l1!=l2;++l1,++i) {
      sib_it r=r1;
      for (int j=0;r!=r2;++r,++j)
	scores.insert(make_pair(score(l1,r),make_pair(i,j)));
    }

    score_t s=0;
    int n=0,m=min(lmatched.size(),rmatched.size());
    for (ScoreMap::const_iterator it=scores.begin();
	 it!=scores.end();++it) {
      if (lmatched[it->second.first].node!=NULL &&
	  rmatched[it->second.second].node!=NULL) { //a valid match
	lmatched[it->second.first].node=NULL;
	rmatched[it->second.second].node=NULL;
	s+=it->first;
	if (++n==m)
	  return s;
      }
    }
    return s;
  }

  void merge_trees::unordered_merge(sib_it l1,sib_it l2,sib_it r1,sib_it r2) {
    std::vector<sib_it>
      lmatched(make_counting_iterator(l1),
	       make_counting_iterator(l2)),
      rmatched(make_counting_iterator(r1),
	       make_counting_iterator(r2));
    typedef std::multimap<score_t,pair<int,int>,std::greater<score_t> >
      ScoreMap;
    ScoreMap scores;
    sib_it l=l1;
    for (int i=0;l!=l2;++l,++i) {
      sib_it r=r1;
      for (int j=0;r!=r2;++r,++j)
	scores.insert(make_pair(_sc.score(l,r),make_pair(i,j)));
    }

    int n=0,m=min(lmatched.size(),rmatched.size());
    for (ScoreMap::const_iterator it=scores.begin();
	 it!=scores.end();++it) {
      if (it->first<=0)
	break;
      if (lmatched[it->second.first].node!=NULL &&
	  rmatched[it->second.second].node!=NULL) { //a valid match

	merge(lmatched[it->second.first],rmatched[it->second.second]);
	lmatched[it->second.first].node=NULL;
	rmatched[it->second.second].node=NULL;

	if (++n==m)
	  break;
      }
    }

    for (std::vector<sib_it>::const_iterator lsib=lmatched.begin();
	 lsib!=lmatched.end();++lsib)
      if (lsib->node!=NULL) //unmatched - add to end of right
	_dst.insert_subtree(r1,*lsib);
  }
  void merge_trees::ordered_merge(sib_it l,sib_it r) {
      score_t best=_sc.score(l,r)-1; //-1 for the alignment of *l with *r;

      sib_it lat=l.begin(),lnxt=++l.begin();
      sib_it rat=r.begin(),rnxt=++r.begin();
      while (lat!=l.end() && rat!=r.end()) {
	score_t s_im=_sc.score(lat,rat);
	score_t s0=s_im+_sc.score(lnxt,l.end(),rnxt,r.end());
	score_t s1=_sc.score(lat,l.end(),rnxt,r.end());
	score_t s2=_sc.score(lnxt,l.end(),rat,r.end());
	if (s_im>0 && s0>=s1 && s0>=s2) {
	  assert(s0>=best-EPSILON);
	  best-=s_im;
	  merge(lat,rat);
	  rat=rnxt++;
	  lat=lnxt++;
	} else if (s1>=s2) {
	  assert(ceil(s1)>=ceil(best)-EPSILON);
	  rat=rnxt++;
	} else {
	  assert(ceil(s2)>=ceil(best)-EPSILON);
	  _dst.move_before(rat,lat);
	  lat=lnxt++;
	}
      }
      _dst.append_children(r,lat,l.end());
  }

  void merge_trees::merge(sib_it l,sib_it r) {
    r->vlocs.splice(r->vlocs.begin(),l->vlocs);
    if (is_turn(*l)) {
      assert(is_turn(*r));
      r->v.insert(l->v.begin(),l->v.end()); //jumps too once we have jumps
      /*} else if (is_if_food(*l) || is_identity(*l) || is_near(*l) ||
	       is_pickup(*l) || is_holding(*l) || is_walktowards(*l)) {
      merge(l.begin(),r.begin());
      merge(++l.begin(),++r.begin());*/
    } else if (is_not(*l)) {
      assert(is_not(*r));
      merge(l.begin(),r.begin());
    } else if (is_or(*l) || is_and(*l)) {
      assert(*l==*r);
      unordered_merge(l.begin(),l.end(),r.begin(),r.end());
    } else if (is_progn(*l)) {
      assert(is_progn(*r));
      ordered_merge(l,r);
    } else {
      //if (*l!=*r
      //cout << *l << " " << *r << endl;
      if (*l!=*r)
	r->v.insert(l->v.begin(),l->v.end());
      //assert(*l==*r);
      cout << *l <<" " << *r << endl;
      assert(l.number_of_children()==r.number_of_children());
      for (sib_it sib1=l.begin(),sib2=r.begin();sib1!=l.end();++sib1,++sib2)
	merge(sib1,sib2);
    }
  }

} //~namespace alignment

max_stars_repo_name: moshelooks/moses

max_issues_repo_name: moshelooks/moses

max_forks_repo_name: moshelooks/moses


text:
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////

#ifndef BOOST_INTERPROCESS_DETAIL_NODE_POOL_HPP
#define BOOST_INTERPROCESS_DETAIL_NODE_POOL_HPP

#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#  pragma once
#endif

#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>

#include <boost/intrusive/slist.hpp>
#include <boost/math/common_factor_ct.hpp>
#include <boost/pointer_to_other.hpp>

#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/detail/math_functions.hpp>
#include <boost/interprocess/detail/type_traits.hpp>
#include <boost/interprocess/allocators/detail/node_tools.hpp>
#include <boost/interprocess/mem_algo/detail/mem_algo_common.hpp>
#include <boost/interprocess/allocators/detail/allocator_common.hpp>
#include <cstddef>
#include <functional>
#include <algorithm>
#include <cassert>

//!\file
//!Describes the real adaptive pool shared by many Interprocess adaptive pool allocators

namespace boost {
namespace interprocess {
namespace detail {

template<class SegmentManagerBase>
class private_node_pool_impl
{
   //Non-copyable
   private_node_pool_impl();
   private_node_pool_impl(const private_node_pool_impl &);
   private_node_pool_impl &operator=(const private_node_pool_impl &);

   //A node object will hold node_t when it's not allocated
   public:
   typedef typename SegmentManagerBase::void_pointer              void_pointer;
   typedef typename node_slist<void_pointer>::slist_hook_t        slist_hook_t;
   typedef typename node_slist<void_pointer>::node_t              node_t;
   typedef typename node_slist<void_pointer>::node_slist_t        free_nodes_t;
   typedef typename SegmentManagerBase::multiallocation_chain     multiallocation_chain;

   private:
   typedef typename bi::make_slist
      < node_t, bi::base_hook<slist_hook_t>
      , bi::linear<true>
      , bi::constant_time_size<false> >::type      blockslist_t;
   public:

   //!Segment manager typedef
   typedef SegmentManagerBase segment_manager_base_type;

   //!Constructor from a segment manager. Never throws
   private_node_pool_impl(segment_manager_base_type *segment_mngr_base, std::size_t node_size, std::size_t nodes_per_block)
   :  m_nodes_per_block(nodes_per_block)
   ,  m_real_node_size(detail::lcm(node_size, std::size_t(alignment_of<node_t>::value)))
      //General purpose allocator
   ,  mp_segment_mngr_base(segment_mngr_base)
   ,  m_blocklist()
   ,  m_freelist()
      //Debug node count
   ,  m_allocated(0)
   {}

   //!Destructor. Deallocates all allocated blocks. Never throws
   ~private_node_pool_impl()
   {  this->purge_blocks();  }

   std::size_t get_real_num_node() const
   {  return m_nodes_per_block; }

   //!Returns the segment manager. Never throws
   segment_manager_base_type* get_segment_manager_base()const
   {  return detail::get_pointer(mp_segment_mngr_base);  }

   //!Allocates array of count elements. Can throw boost::interprocess::bad_alloc
   void *allocate_node()
   {
      //If there are no free nodes we allocate a new block
      if (m_freelist.empty())
         priv_alloc_block();
      //We take the first free node
      node_t *n = &m_freelist.front();
      m_freelist.pop_front();
      ++m_allocated;
      return n;
   }

   //!Deallocates an array pointed by ptr. Never throws
   void deallocate_node(void *ptr)
   {
      //We put the node at the beginning of the free node list
      node_t * to_deallocate = static_cast<node_t*>(ptr);
      m_freelist.push_front(*to_deallocate);
      assert(m_allocated>0);
      --m_allocated;
   }

   //!Allocates a singly linked list of n nodes ending in null pointer
   //!can throw boost::interprocess::bad_alloc
   multiallocation_chain allocate_nodes(const std::size_t n)
   {
      multiallocation_chain nodes;
      std::size_t i = 0;
      try{
         for(; i < n; ++i){
            nodes.push_front(this->allocate_node());
         }
      }
      catch(...){
         this->deallocate_nodes(nodes, i);
         throw;
      }
      return boost::interprocess::move(nodes);
   }

   //!Deallocates the first n nodes of a linked list of nodes. Never throws
   void deallocate_nodes(multiallocation_chain &nodes, std::size_t n)
   {
      for(std::size_t i = 0; i < n; ++i){
         void *p = detail::get_pointer(nodes.front());
         assert(p);
         nodes.pop_front();
         this->deallocate_node(p);
      }
   }

   //!Deallocates the nodes pointed by the multiallocation iterator. Never throws
   void deallocate_nodes(multiallocation_chain chain)
   {
      while(!chain.empty()){
         void *addr = detail::get_pointer(chain.front());
         chain.pop_front();
         deallocate_node(addr);
      }
   }

   //!Deallocates all the free blocks of memory. Never throws
   void deallocate_free_blocks()
   {
      typedef typename free_nodes_t::iterator nodelist_iterator;
      typename blockslist_t::iterator bit(m_blocklist.before_begin()),
                                      it(m_blocklist.begin()),
                                      itend(m_blocklist.end());
      free_nodes_t backup_list;
      nodelist_iterator backup_list_last = backup_list.before_begin();

      //Execute the algorithm and get an iterator to the last value
      std::size_t blocksize = detail::get_rounded_size
         (m_real_node_size*m_nodes_per_block, alignment_of<node_t>::value);

      while(it != itend){
         //Collect all the nodes from the block pointed by it
         //and push them in the list
         free_nodes_t free_nodes;
         nodelist_iterator last_it = free_nodes.before_begin();
         const void *addr = get_block_from_hook(&*it, blocksize);

         m_freelist.remove_and_dispose_if
            (is_between(addr, blocksize), push_in_list(free_nodes, last_it));

         //If the number of nodes is equal to m_nodes_per_block
         //this means that the block can be deallocated
         if(free_nodes.size() == m_nodes_per_block){
            //Unlink the nodes
            free_nodes.clear();
            it = m_blocklist.erase_after(bit);
            mp_segment_mngr_base->deallocate((void*)addr);
         }
         //Otherwise, insert them in the backup list, since the
         //next "remove_if" does not need to check them again.
         else{
            //Assign the iterator to the last value if necessary
            if(backup_list.empty() && !m_freelist.empty()){
               backup_list_last = last_it;
            }
            //Transfer nodes. This is constant time.
            backup_list.splice_after
               ( backup_list.before_begin()
               , free_nodes
               , free_nodes.before_begin()
               , last_it
               , free_nodes.size());
            bit = it;
            ++it;
         }
      }
      //We should have removed all the nodes from the free list
      assert(m_freelist.empty());

      //Now pass all the node to the free list again
      m_freelist.splice_after
         ( m_freelist.before_begin()
         , backup_list
         , backup_list.before_begin()
         , backup_list_last
         , backup_list.size());
   }

   std::size_t num_free_nodes()
   {  return m_freelist.size();  }

   //!Deallocates all used memory. Precondition: all nodes allocated from this pool should
   //!already be deallocated. Otherwise, undefined behaviour. Never throws
   void purge_blocks()
   {
      //check for memory leaks
      assert(m_allocated==0);
      std::size_t blocksize = detail::get_rounded_size
         (m_real_node_size*m_nodes_per_block, alignment_of<node_t>::value);
      typename blockslist_t::iterator
         it(m_blocklist.begin()), itend(m_blocklist.end()), aux;

      //We iterate though the NodeBlock list to free the memory
      while(!m_blocklist.empty()){
         void *addr = get_block_from_hook(&m_blocklist.front(), blocksize);
         m_blocklist.pop_front();
         mp_segment_mngr_base->deallocate((void*)addr);
      }
      //Just clear free node list
      m_freelist.clear();
   }

   void swap(private_node_pool_impl &other)
   {
      std::swap(mp_segment_mngr_base, other.mp_segment_mngr_base);
      m_blocklist.swap(other.m_blocklist);
      m_freelist.swap(other.m_freelist);
      std::swap(m_allocated, other.m_allocated);
   }

   private:

   struct push_in_list
   {
      push_in_list(free_nodes_t &l, typename free_nodes_t::iterator &it)
         :  slist_(l), last_it_(it)
      {}

      void operator()(typename free_nodes_t::pointer p) const
      {
         slist_.push_front(*p);
         if(slist_.size() == 1){ //Cache last element
            ++last_it_ = slist_.begin();
         }
      }

      private:
      free_nodes_t &slist_;
      typename free_nodes_t::iterator &last_it_;
   };

   struct is_between
      :  std::unary_function<typename free_nodes_t::value_type, bool>
   {
      is_between(const void *addr, std::size_t size)
         :  beg_(static_cast<const char *>(addr)), end_(beg_+size)
      {}

      bool operator()(typename free_nodes_t::const_reference v) const
      {
         return (beg_ <= reinterpret_cast<const char *>(&v) &&
                 end_ >  reinterpret_cast<const char *>(&v));
      }
      private:
      const char *      beg_;
      const char *      end_;
   };

   //!Allocates a block of nodes. Can throw boost::interprocess::bad_alloc
   void priv_alloc_block()
   {
      //We allocate a new NodeBlock and put it as first
      //element in the free Node list
      std::size_t blocksize =
         detail::get_rounded_size(m_real_node_size*m_nodes_per_block, alignment_of<node_t>::value);
      char *pNode = reinterpret_cast<char*>
         (mp_segment_mngr_base->allocate(blocksize + sizeof(node_t)));
      if(!pNode)  throw bad_alloc();
      char *pBlock = pNode;
      m_blocklist.push_front(get_block_hook(pBlock, blocksize));

      //We initialize all Nodes in Node Block to insert
      //them in the free Node list
      for(std::size_t i = 0; i < m_nodes_per_block; ++i, pNode += m_real_node_size){
         m_freelist.push_front(*new (pNode) node_t);
      }
   }

   //!Deprecated, use deallocate_free_blocks
   void deallocate_free_chunks()
   {  this->deallocate_free_blocks(); }

   //!Deprecated, use purge_blocks
   void purge_chunks()
   {  this->purge_blocks(); }

   private:
   //!Returns a reference to the block hook placed in the end of the block
   static node_t & get_block_hook (void *block, std::size_t blocksize)
   {
      return *reinterpret_cast<node_t*>(reinterpret_cast<char*>(block) + blocksize);
   }

   //!Returns the starting address of the block reference to the block hook placed in the end of the block
   void *get_block_from_hook (node_t *hook, std::size_t blocksize)
   {
      return (reinterpret_cast<char*>(hook) - blocksize);
   }

   private:
   typedef typename boost::pointer_to_other
      <void_pointer, segment_manager_base_type>::type   segment_mngr_base_ptr_t;

   const std::size_t m_nodes_per_block;
   const std::size_t m_real_node_size;
   segment_mngr_base_ptr_t mp_segment_mngr_base;   //Segment manager
   blockslist_t      m_blocklist;      //Intrusive container of blocks
   free_nodes_t      m_freelist;       //Intrusive container of free nods
   std::size_t       m_allocated;      //Used nodes for debugging
};

//!Pooled shared memory allocator using single segregated storage. Includes
//!a reference count but the class does not delete itself, this is
//!responsibility of user classes. Node size (NodeSize) and the number of
//!nodes allocated per block (NodesPerBlock) are known at compile time
template< class SegmentManager, std::size_t NodeSize, std::size_t NodesPerBlock >
class private_node_pool
   //Inherit from the implementation to avoid template bloat
   :  public private_node_pool_impl<typename SegmentManager::segment_manager_base_type>
{
   typedef private_node_pool_impl<typename SegmentManager::segment_manager_base_type> base_t;
   //Non-copyable
   private_node_pool();
   private_node_pool(const private_node_pool &);
   private_node_pool &operator=(const private_node_pool &);

   public:
   typedef SegmentManager segment_manager;

   static const std::size_t nodes_per_block = NodesPerBlock;
   //Deprecated, use nodes_per_block
   static const std::size_t nodes_per_chunk = NodesPerBlock;

   //!Constructor from a segment manager. Never throws
   private_node_pool(segment_manager *segment_mngr)
      :  base_t(segment_mngr, NodeSize, NodesPerBlock)
   {}

   //!Returns the segment manager. Never throws
   segment_manager* get_segment_manager() const
   {  return static_cast<segment_manager*>(base_t::get_segment_manager_base()); }
};

//!Pooled shared memory allocator using single segregated storage. Includes
//!a reference count but the class does not delete itself, this is
//!responsibility of user classes. Node size (NodeSize) and the number of
//!nodes allocated per block (NodesPerBlock) are known at compile time
//!Pooled shared memory allocator using adaptive pool. Includes
//!a reference count but the class does not delete itself, this is
//!responsibility of user classes. Node size (NodeSize) and the number of
//!nodes allocated per block (NodesPerBlock) are known at compile time
template< class SegmentManager
        , std::size_t NodeSize
        , std::size_t NodesPerBlock
        >
class shared_node_pool
   :  public detail::shared_pool_impl
      < private_node_pool
         <SegmentManager, NodeSize, NodesPerBlock>
      >
{
   typedef detail::shared_pool_impl
      < private_node_pool
         <SegmentManager, NodeSize, NodesPerBlock>
      > base_t;
   public:
   shared_node_pool(SegmentManager *segment_mgnr)
      : base_t(segment_mgnr)
   {}
};

}  //namespace detail {
}  //namespace interprocess {
}  //namespace boost {

#include <boost/interprocess/detail/config_end.hpp>

#endif   //#ifndef BOOST_INTERPROCESS_DETAIL_NODE_POOL_HPP

ext: hpp

max_stars_repo_name: TE-tatuonagamatu/boost


text:
/*******************************************************************************
Copyright(c) 2015-2019 LORD Corporation. All rights reserved.

MIT Licensed. See the included LICENSE.txt for a copy of the full MIT License.
*******************************************************************************/
#include "mscl/MicroStrain/Wireless/Packets/ShmPacket.h"
#include "mscl/MicroStrain/Wireless/Packets/WirelessPacket.h"
#include "mscl/MicroStrain/Wireless/Packets/WirelessPacketCollector.h"
#include "mscl/MicroStrain/Wireless/Packets/WirelessDataPacket.h"
#include "mscl/Exceptions.h"

#include <boost/test/unit_test.hpp>

using namespace mscl;

BOOST_AUTO_TEST_SUITE(ShmPacket_Test)

BOOST_AUTO_TEST_CASE(ShmPacket_Constructor)
{
    ByteStream payloadBytes;
    payloadBytes.append_uint8(0xA0);    //app id
    payloadBytes.append_uint8(0);        //angle id
    payloadBytes.append_uint8(0);        //mode
    payloadBytes.append_uint16(5);        //bin size
    payloadBytes.append_uint16(10);        //bin lower bound
    payloadBytes.append_uint16(16);        //dataset id
    payloadBytes.append_uint32(25);        //uptime
    payloadBytes.append_float(0.622558944f);    //angle    (in radians)
    payloadBytes.append_float(20.6f);    //life

    //there are 21 bins in each packet
    for(int i = 0; i < 21; i++)
    {
        payloadBytes.append_uint32(13);    //bin data
    }

    //build a WirelessPacket
    WirelessPacket packet;
    packet.nodeAddress(345);
    packet.deliveryStopFlags(DeliveryStopFlags::fromInvertedByte(0));
    packet.type(WirelessPacket::packetType_SHM);
    packet.nodeRSSI(1);
    packet.baseRSSI(1);
    packet.payload(payloadBytes.data());    //give the packet the payload bytes we created

    //call the addDataPacket() function to parse the packet as an LDC Packet
    WirelessPacketCollector collector;
    collector.addDataPacket(packet);

    DataSweeps sweeps;
    collector.getDataSweeps(sweeps);
    BOOST_CHECK_EQUAL(sweeps.size(), 1);

    DataSweep sweep = sweeps.at(0);

    //check that the sweep data matches the packet we added
    BOOST_CHECK_EQUAL(sweep.nodeAddress(), 345);
    BOOST_CHECK_EQUAL(sweep.tick(), 16);
    BOOST_CHECK_EQUAL(sweep.data().size(), 1);    //1 point in the packet
    BOOST_CHECK_EQUAL(sweep.data().at(0).channelId(), WirelessChannel::channel_structuralHealth);
    BOOST_CHECK_EQUAL(sweep.data().at(0).channelNumber(), 0);
    BOOST_CHECK_EQUAL(sweep.data().at(0).channelName(), "structuralHealth_angle35.67");

    BOOST_CHECK_EQUAL(sweep.data().at(0).storedAs(), valueType_StructuralHealth);

    StructuralHealth sh = sweep.data().at(0).as_StructuralHealth();

    BOOST_CHECK_EQUAL(sh.uptime(), 25);
    BOOST_CHECK_CLOSE(sh.angle(), 35.67, 0.0001);
    BOOST_CHECK_CLOSE(sh.damage(), 20.6, 0.0001);

    mscl::Bins bins = sh.histogram().bins();
    mscl::Bin bin = bins.at(0);
    BOOST_CHECK_EQUAL(sh.histogram().binsStart().as_uint32(), 10);
    BOOST_CHECK_EQUAL(sh.histogram().binsSize().as_uint32(), 5);
    BOOST_CHECK_EQUAL(bins.size(), 21);
    BOOST_CHECK_EQUAL(bin.start().as_uint32(), 10);
    BOOST_CHECK_EQUAL(bin.end().as_uint32(), 15);
    BOOST_CHECK_EQUAL(bin.count().as_uint32(), 13);
    bin = bins.at(1);
    BOOST_CHECK_EQUAL(bin.start().as_uint32(), 15);
    BOOST_CHECK_EQUAL(bin.end().as_uint32(), 20);
}

BOOST_AUTO_TEST_CASE(ShmPacket2_Constructor)
{
    ByteStream payloadBytes;
    payloadBytes.append_uint8(0x00);    //app id (v2)
    payloadBytes.append_uint8(108);        //transmit rate
    payloadBytes.append_uint8(112);        //processing rate
    payloadBytes.append_uint32(4000000000);        //persistant tick
    payloadBytes.append_float(42.17663f);    //angle (in degrees)
    payloadBytes.append_float(20.36f);    //damage
    payloadBytes.append_uint16(10);        //bin start
    payloadBytes.append_uint16(5);        //bin size

    //there are 21 bins in each packet
    for(int i = 0; i < 21; i++)
    {
        payloadBytes.append_uint32(3000000000);    //bin data
    }

    //build a WirelessPacket
    WirelessPacket packet;
    packet.nodeAddress(345);
    packet.deliveryStopFlags(DeliveryStopFlags::fromInvertedByte(0));
    packet.type(WirelessPacket::packetType_SHM);
    packet.nodeRSSI(1);
    packet.baseRSSI(1);
    packet.payload(payloadBytes.data());    //give the packet the payload bytes we created

    //call the addDataPacket() function to parse the packet as an LDC Packet
    WirelessPacketCollector collector;
    collector.addDataPacket(packet);

    DataSweeps sweeps;
    collector.getDataSweeps(sweeps);
    BOOST_CHECK_EQUAL(sweeps.size(), 1);

    DataSweep sweep = sweeps.at(0);

    //check that the sweep data matches the packet we added
    BOOST_CHECK_EQUAL(sweep.nodeAddress(), 345);
    BOOST_CHECK_EQUAL(sweep.tick(), 4000000000);
    BOOST_CHECK_EQUAL(sweep.data().size(), 1);    //1 point in the packet
    BOOST_CHECK_EQUAL(sweep.data().at(0).channelId(), WirelessChannel::channel_structuralHealth);
    BOOST_CHECK_EQUAL(sweep.data().at(0).channelNumber(), 0);
    BOOST_CHECK_EQUAL(sweep.data().at(0).channelName(), "structuralHealth_angle42.18");

    BOOST_CHECK_EQUAL(sweep.data().at(0).storedAs(), valueType_StructuralHealth);

    StructuralHealth sh = sweep.data().at(0).as_StructuralHealth();

    BOOST_CHECK_EQUAL(sh.uptime(), 4000000000);
    BOOST_CHECK_CLOSE(sh.angle(), 42.17663, 0.0001);
    BOOST_CHECK_CLOSE(sh.damage(), 20.36, 0.0001);

    mscl::Bins bins = sh.histogram().bins();
    mscl::Bin bin = bins.at(0);
    BOOST_CHECK_EQUAL(sh.histogram().binsStart().as_uint32(), 10);
    BOOST_CHECK_EQUAL(sh.histogram().binsSize().as_uint32(), 5);
    BOOST_CHECK_EQUAL(bins.size(), 21);
    BOOST_CHECK_EQUAL(bin.start().as_uint32(), 10);
    BOOST_CHECK_EQUAL(bin.end().as_uint32(), 15);
    BOOST_CHECK_EQUAL(bin.count().as_uint32(), 3000000000);
    bin = bins.at(1);
    BOOST_CHECK_EQUAL(bin.start().as_uint32(), 15);
    BOOST_CHECK_EQUAL(bin.end().as_uint32(), 20);
}

BOOST_AUTO_TEST_CASE(ShmPacket_IntegrityCheck_SmallPayload)
{
    ByteStream payloadBytes;
    payloadBytes.append_uint8(0xA0);    //app id
    payloadBytes.append_uint8(0);        //angle id
    payloadBytes.append_uint8(0);        //mode
    payloadBytes.append_uint16(5);        //bin size
    payloadBytes.append_uint16(10);        //bin lower bound
    payloadBytes.append_uint16(16);        //dataset id
    payloadBytes.append_uint32(25);        //uptime
    payloadBytes.append_float(35.67f);    //angle
    payloadBytes.append_float(20.6f);    //life
                                        //no bins

    //build a WirelessPacket
    WirelessPacket packet;
    packet.nodeAddress(345);
    packet.deliveryStopFlags(DeliveryStopFlags::fromInvertedByte(0));
    packet.type(WirelessPacket::packetType_SHM);
    packet.nodeRSSI(1);
    packet.baseRSSI(1);
    packet.payload(payloadBytes.data());    //give the packet the payload bytes we created

    //check that the integrity check failed
    BOOST_CHECK_EQUAL(ShmPacket::integrityCheck(packet), false);
}

BOOST_AUTO_TEST_CASE(ShmPacket_IntegrityCheck_BadStopFlags)
{
    ByteStream payloadBytes;
    payloadBytes.append_uint8(0xA0);    //app id
    payloadBytes.append_uint8(0);        //angle id
    payloadBytes.append_uint8(0);        //mode
    payloadBytes.append_uint16(5);        //bin size
    payloadBytes.append_uint16(10);        //bin lower bound
    payloadBytes.append_uint16(16);        //dataset id
    payloadBytes.append_uint32(25);        //uptime
    payloadBytes.append_float(35.67f);    //angle
    payloadBytes.append_float(20.6f);    //life

    //there are 21 bins in each packet
    for(int i = 0; i < 21; i++)
    {
        payloadBytes.append_uint32(13);    //bin data
    }

    //build a WirelessPacket
    WirelessPacket packet;
    packet.nodeAddress(345);
    packet.deliveryStopFlags(DeliveryStopFlags::fromInvertedByte(15));    //INVALID DELIVERY STOP FLAGS
    packet.type(WirelessPacket::packetType_SHM);
    packet.nodeRSSI(1);
    packet.baseRSSI(1);
    packet.payload(payloadBytes.data());    //give the packet the payload bytes we created

    //check that the integrity check failed
    BOOST_CHECK_EQUAL(ShmPacket::integrityCheck(packet), false);
}

BOOST_AUTO_TEST_CASE(ShmPacket_IntegrityCheck_BadPacketType)
{
    ByteStream payloadBytes;
    payloadBytes.append_uint8(0xA0);    //app id
    payloadBytes.append_uint8(0);        //angle id
    payloadBytes.append_uint8(0);        //mode
    payloadBytes.append_uint16(5);        //bin size
    payloadBytes.append_uint16(10);        //bin lower bound
    payloadBytes.append_uint16(16);        //dataset id
    payloadBytes.append_uint32(25);        //uptime
    payloadBytes.append_float(35.67f);    //angle
    payloadBytes.append_float(20.6f);    //life

    //there are 21 bins in each packet
    for(int i = 0; i < 21; i++)
    {
        payloadBytes.append_uint32(13);    //bin data
    }

    //build a WirelessPacket
    WirelessPacket packet;
    packet.nodeAddress(345);
    packet.deliveryStopFlags(DeliveryStopFlags::fromInvertedByte(0));
    packet.type(WirelessPacket::packetType_SyncSampling);        //INVALID PACKET TYPE
    packet.nodeRSSI(1);
    packet.baseRSSI(1);
    packet.payload(payloadBytes.data());    //give the packet the payload bytes we created

    //check that the integrity check failed
    BOOST_CHECK_EQUAL(ShmPacket::integrityCheck(packet), false);
}

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: vibhoraggarwal/MSCL

max_stars_repo_licenses: BSL-1.0 OpenSSL MIT

max_issues_repo_name: vibhoraggarwal/MSCL

max_issues_repo_licenses: BSL-1.0 OpenSSL MIT

max_forks_repo_name: vibhoraggarwal/MSCL

max_forks_repo_licenses: BSL-1.0 OpenSSL MIT


text:
#ifndef SQL_PARSER_AST_SQL_STMT_HPP
#define SQL_PARSER_AST_SQL_STMT_HPP

#include "sql/ast/create_table_stmt.hpp"
#include "sql/ast/import_table_stmt.hpp"
#include "sql/ast/select_stmt.hpp"

#include <boost/spirit/home/x3/support/ast/position_tagged.hpp>

#include <vector>

namespace sql { namespace ast
{
    namespace x3 = boost::spirit::x3;

    struct explain_clause : x3::position_tagged {
        bool explain;
        bool query_plan;
    };

    struct sql_stmt_variant : x3::variant<
              select_stmt
            , create_table_stmt
            , import_table_stmt
    >
    {
        using base_type::base_type;
        using base_type::operator=;
    };

    struct sql_stmt : x3::position_tagged
    {
        explain_clause explain;
        sql_stmt_variant stmt;
    };

    typedef std::vector<sql_stmt> sql_stmt_list;
}}

#endif //SQL_PARSER_AST_SQL_STMT_HPP

max_stars_repo_name: cviebig/lib-sql

max_issues_repo_name: cviebig/lib-sql

max_forks_repo_name: cviebig/lib-sql


text:
#include "stdafx.h"
#include "RoundRobinThreadAffinedTaskScheduler.h"

//#include <boost/date_time.hpp>

#include "ArgumentOutOfRangeException.h"
#include "ThreadHelper.h"

namespace Disruptor
{

    void RoundRobinThreadAffinedTaskScheduler::start(std::int32_t numberOfThreads)
    {
        if (m_started)
            return;

        m_started = true;

        if (numberOfThreads < 1)
            DISRUPTOR_THROW_ARGUMENT_OUT_OF_RANGE_EXCEPTION(numberOfThreads);

        createThreads(numberOfThreads);
    }

    void RoundRobinThreadAffinedTaskScheduler::stop()
    {
        if (!m_started)
            return;

        m_started = false;

        for (auto&& thread : m_threads)
        {
            if (thread.joinable())
                //thread.timed_join(boost::posix_time::seconds(10));
                thread.join();
        }
    }

    std::future< void > RoundRobinThreadAffinedTaskScheduler::scheduleAndStart(std::packaged_task< void() >&& task)
    {
        auto future = task.get_future();
        m_tasks.push(std::move(task));

        return future;
    }

    void RoundRobinThreadAffinedTaskScheduler::createThreads(std::int32_t numberOfThreads)
    {
        for (auto i = 0; i < numberOfThreads; ++i)
            m_threads.emplace_back([this, i]() { workingLoop(i); });
    }

    void RoundRobinThreadAffinedTaskScheduler::workingLoop(std::int32_t threadId)
    {
        static const auto processorCount = std::thread::hardware_concurrency();

        const auto processorIndex = threadId % processorCount;

        const auto affinityMask = ThreadHelper::AffinityMask(1ull << processorIndex);

        ThreadHelper::setThreadAffinity(affinityMask);

        while (m_started)
        {
            std::packaged_task< void() > task;
            while (m_tasks.timedWaitAndPop(task, std::chrono::milliseconds(100)))
            {
                tryExecuteTask(task);
            }
        }
    }

    void RoundRobinThreadAffinedTaskScheduler::tryExecuteTask(std::packaged_task< void() >& task)
    {
        task();
    }

} // namespace Disruptor

max_stars_repo_name: monkcage/Disruptor-cpp

max_issues_repo_name: monkcage/Disruptor-cpp

max_forks_repo_name: monkcage/Disruptor-cpp


text:
/**
 * @file walletfetchtxs.cpp
 *
 * The fetch functions provide a sorted list of transaction hashes ordered by block,
 * position in block and position in wallet including STO receipts.
 */

#include <omnicore/walletfetchtxs.h>

#include <omnicore/dbstolist.h>
#include <omnicore/dbtxlist.h>
#include <omnicore/log.h>
#include <omnicore/omnicore.h>
#include <omnicore/pending.h>
#include <omnicore/utilsbitcoin.h>

#include <init.h>
#include <interfaces/wallet.h>
#include <validation.h>
#include <sync.h>
#include <tinyformat.h>
#include <index/txindex.h>
#ifdef ENABLE_WALLET
#include <wallet/wallet.h>
#endif

#include <boost/algorithm/string.hpp>

#include <stdint.h>
#include <list>
#include <map>
#include <set>
#include <string>
#include <utility>
#include <vector>

namespace mastercore
{
/**
 * Gets the byte offset of a transaction from the transaction index.
 */
static unsigned int GetTransactionByteOffset(const uint256& txid)
{
    LOCK(cs_main);

    if (g_txindex) {
        return g_txindex->ReadTxPos(txid);
    }

    return 0;
}

/**
 * Returns an ordered list of Omni transactions including STO receipts that are relevant to the wallet.
 *
 * Ignores order in the wallet (which can be skewed by watch addresses) and utilizes block height and position within block.
 */
std::map<std::string, uint256> FetchWalletOmniTransactions(interfaces::Wallet& iWallet, unsigned int count, int startBlock, int endBlock)
{
    std::map<std::string, uint256> mapResponse;
#ifdef ENABLE_WALLET
    if (!HasWallets()) {
        return mapResponse;
    }
    std::set<uint256> seenHashes;
    std::multimap<int64_t, const interfaces::WalletTx*> txOrdered;
    const std::vector<interfaces::WalletTx>& transactions = iWallet.getWalletTxs();
    for (const auto& transaction : transactions)
        txOrdered.insert(std::make_pair(transaction.order_pos, &transaction));

    // Iterate backwards through wallet transactions until we have count items to return:
    for (std::multimap<int64_t, const interfaces::WalletTx*>::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) {
        const interfaces::WalletTx* pwtx = it->second;
        const uint256& txHash = pwtx->tx->GetHash();
        {
            LOCK(cs_tally);
            if (!pDbTransactionList->exists(txHash)) continue;
        }
        const uint256& blockHash = pwtx->hash_block;
        if (blockHash.IsNull()) continue;
        const CBlockIndex* pBlockIndex = GetBlockIndex(blockHash);
        if (pBlockIndex == nullptr) continue;
        int blockHeight = pBlockIndex->nHeight;
        if (blockHeight < startBlock || blockHeight > endBlock) continue;
        int blockPosition = GetTransactionByteOffset(txHash);
        std::string sortKey = strprintf("%06d%010d", blockHeight, blockPosition);
        mapResponse.insert(std::make_pair(sortKey, txHash));
        seenHashes.insert(txHash);
        if (mapResponse.size() >= count) break;
    }

    // Insert STO receipts - receiving an STO has no inbound transaction to the wallet, so we will insert these manually into the response
    std::string mySTOReceipts;
    {
        LOCK(cs_tally);
        mySTOReceipts = pDbStoList->getMySTOReceipts("", iWallet);
    }
    std::vector<std::string> vecReceipts;
    if (!mySTOReceipts.empty()) {
        boost::split(vecReceipts, mySTOReceipts, boost::is_any_of(","), boost::token_compress_on);
    }
    for (size_t i = 0; i < vecReceipts.size(); i++) {
        std::vector<std::string> svstr;
        boost::split(svstr, vecReceipts[i], boost::is_any_of(":"), boost::token_compress_on);
        if (svstr.size() != 4) {
            PrintToLog("STODB Error - number of tokens is not as expected (%s)\n", vecReceipts[i]);
            continue;
        }
        int blockHeight = atoi(svstr[1]);
        if (blockHeight < startBlock || blockHeight > endBlock) continue;
        uint256 txHash = uint256S(svstr[0]);
        if (seenHashes.find(txHash) != seenHashes.end()) continue; // an STO may already be in the wallet if we sent it
        int blockPosition = GetTransactionByteOffset(txHash);
        std::string sortKey = strprintf("%06d%010d", blockHeight, blockPosition);
        mapResponse.insert(std::make_pair(sortKey, txHash));
    }

    // Insert pending transactions (sets block as 999999 and position as wallet position)
    // TODO: resolve potential deadlock caused by cs_wallet, cs_pending
    // LOCK(cs_pending);
    for (PendingMap::const_iterator it = my_pending.begin(); it != my_pending.end(); ++it) {
        const uint256& txHash = it->first;
        int blockHeight = 999999;
        if (blockHeight < startBlock || blockHeight > endBlock) continue;
        int blockPosition = 0;
        {
            for (const auto& transaction : transactions)
                if (transaction.tx->GetHash() == txHash)
                    blockPosition = transaction.order_pos;
        }
        std::string sortKey = strprintf("%06d%010d", blockHeight, blockPosition);
        mapResponse.insert(std::make_pair(sortKey, txHash));
    }
#endif
    return mapResponse;
}

} // namespace mastercore

max_stars_repo_name: lcgogo/omnicore

max_issues_repo_name: lcgogo/omnicore

max_forks_repo_name: lcgogo/omnicore