<commit_before>#ifndef VSMC_SMP_BACKEND_STD_HPP
#define VSMC_SMP_BACKEND_STD_HPP

#include <vsmc/smp/base.hpp>
#include <vsmc/utility/stdtbb.hpp>
#include <vsmc/utility/tbb_op.hpp>

namespace vsmc {

/// \brief Particle::weight_set_type subtype using C++11 concurrency
/// \ingroup SMP
template <typename BaseState>
class WeightSetSTD : public traits::WeightSetTypeTrait<BaseState>::type
{
    typedef typename traits::WeightSetTypeTrait<BaseState>::type base;

    public :

    typedef typename traits::SizeTypeTrait<base>::type size_type;

    explicit WeightSetSTD (size_type N) : base(N) {}

    private :

    void log_weight2weight ()
    {
        const size_type N = static_cast<size_type>(this->size());
        parallel_for(BlockedRange<size_type>(0, N), tbb_op::exp<double>(
                    this->log_weight_ptr(), this->weight_ptr()));
    }

    void weight2log_weight ()
    {
        const size_type N = static_cast<size_type>(this->size());
        parallel_for(BlockedRange<size_type>(0, N), tbb_op::log<double>(
                    this->weight_ptr(), this->log_weight_ptr()));
    }
}; // class WeightSetSTD

/// \brief Particle::value_type subtype using C++11 concurrency
/// \ingroup SMP
template <typename BaseState>
class StateSTD : public BaseState
{
    public :

    typedef typename traits::SizeTypeTrait<BaseState>::type size_type;

    explicit StateSTD (size_type N) : BaseState(N) {}

    template <typename IntType>
    void copy (size_type N, const IntType *copy_from)
    {
        VSMC_RUNTIME_ASSERT_STATE_COPY_SIZE_MISMATCH(STD);

        parallel_for(BlockedRange<size_type>(0, N),
                copy_work_<IntType>(this, copy_from));
    }

    private :

    template <typename IntType>
    class copy_work_
    {
        public :

        copy_work_ (StateSTD<BaseState> *state, const IntType *copy_from) :
            state_(state), copy_from_(copy_from) {}

        void operator() (const BlockedRange<size_type> &range) const
        {
            for (size_type to = range.begin(); to != range.end(); ++to)
                state_->copy_particle(copy_from_[to], to);
        }

        private :

        StateSTD<BaseState> *const state_;
        const IntType *const copy_from_;
    }; // class copy_work_
}; // class StateSTD

/// \brief Sampler<T>::init_type subtype using C++11 concurrency
/// \ingroup SMP
template <typename T, typename Derived>
class InitializeSTD : public InitializeBase<T, Derived>
{
    public :

    std::size_t operator() (Particle<T> &particle, void *param)
    {
        typedef typename Particle<T>::size_type size_type;
        const size_type N = static_cast<size_type>(particle.size());
        this->initialize_param(particle, param);
        this->pre_processor(particle);
        std::size_t accept = parallel_accumulate(BlockedRange<size_type>(0, N),
                work_(this, &particle), static_cast<std::size_t>(0));
        this->post_processor(particle);

        return accept;
    }

    protected :

    VSMC_DEFINE_SMP_IMPL_COPY_BASE(STD, Initialize)

    private :

    class work_
    {
        public :

        typedef typename Particle<T>::size_type size_type;

        work_ (InitializeSTD<T, Derived> *init,
                Particle<T> *particle) :
            init_(init), particle_(particle) {}

        void operator() (const BlockedRange<size_type> &range,
                std::size_t &accept) const
        {
            std::size_t acc = 0;
            for (size_type i = range.begin(); i != range.end(); ++i) {
                Particle<T> *const part = particle_;
                acc += init_->initialize_state(SingleParticle<T>(i, part));
            }
            accept = acc;
        }

        private :

        InitializeSTD<T, Derived> *const init_;
        Particle<T> *const particle_;
    }; // class work_
}; // class InitializeSTD

/// \brief Sampler<T>::move_type subtype using C++11 concurrency
/// \ingroup SMP
template <typename T, typename Derived>
class MoveSTD : public MoveBase<T, Derived>
{
    public :

    std::size_t operator() (std::size_t iter, Particle<T> &particle)
    {
        typedef typename Particle<T>::size_type size_type;
        const size_type N = static_cast<size_type>(particle.size());
        this->pre_processor(iter, particle);
        std::size_t accept = parallel_accumulate(BlockedRange<size_type>(0, N),
                work_(this, iter, &particle), static_cast<std::size_t>(0));
        this->post_processor(iter, particle);

        return accept;
    }

    protected :

    VSMC_DEFINE_SMP_IMPL_COPY_BASE(STD, Move)

    private :

    class work_
    {
        public :

        typedef typename Particle<T>::size_type size_type;

        work_ (MoveSTD<T, Derived> *move, std::size_t iter,
                Particle<T> *particle):
            move_(move), iter_(iter), particle_(particle) {}

        void operator() (const BlockedRange<size_type> &range,
                std::size_t &accept) const
        {
            std::size_t acc = 0;
            for (size_type i = range.begin(); i != range.end(); ++i) {
                Particle<T> *const part = particle_;
                acc += move_->move_state(iter_, SingleParticle<T>(i, part));
            }
            accept = acc;
        }

        private :

        MoveSTD<T, Derived> *const move_;
        const std::size_t iter_;
        Particle<T> *const particle_;
    }; // class work_
}; // class MoveSTD

/// \brief Monitor<T>::eval_type subtype using C++11 concurrency
/// \ingroup SMP
template <typename T, typename Derived>
class MonitorEvalSTD : public MonitorEvalBase<T, Derived>
{
    public :

    void operator() (std::size_t iter, std::size_t dim,
            const Particle<T> &particle, double *res)
    {
        typedef typename Particle<T>::size_type size_type;
        const size_type N = static_cast<size_type>(particle.size());
        this->pre_processor(iter, particle);
        parallel_for(BlockedRange<size_type>(0, N),
                work_(this, iter, dim, &particle, res));
        this->post_processor(iter, particle);
    }

    protected :

    VSMC_DEFINE_SMP_IMPL_COPY_BASE(STD, MonitorEval)

    private :

    class work_
    {
        public :

        typedef typename Particle<T>::size_type size_type;

        work_ (MonitorEvalSTD<T, Derived> *monitor,
                std::size_t iter, std::size_t dim,
                const Particle<T> *particle, double *res) :
            monitor_(monitor), iter_(iter), dim_(dim), particle_(particle),
            res_(res) {}

        void operator() (const BlockedRange<size_type> &range) const
        {
            for (size_type i = range.begin(); i != range.end(); ++i) {
                double *const r = res_ + i * dim_;
                const Particle<T> *const part = particle_;
                monitor_->monitor_state(iter_, dim_,
                        ConstSingleParticle<T>(i, part), r);
            }
        }

        private :

        MonitorEvalSTD<T, Derived> *const monitor_;
        const std::size_t iter_;
        const std::size_t dim_;
        const Particle<T> *const particle_;
        double *const res_;
    }; // class work_
}; // class MonitorEvalSTD

/// \brief Path<T>::eval_type subtype using C++11 concurrency
/// \ingroup SMP
template <typename T, typename Derived>
class PathEvalSTD : public PathEvalBase<T, Derived>
{
    public :

    double operator() (std::size_t iter, const Particle<T> &particle,
            double *res)
    {
        typedef typename Particle<T>::size_type size_type;
        const size_type N = static_cast<size_type>(particle.size());
        this->pre_processor(iter, particle);
        parallel_for(BlockedRange<size_type>(0, N),
                work_(this, iter, &particle, res));
        this->post_processor(iter, particle);

        return this->path_grid(iter, particle);
    }

    protected :

    VSMC_DEFINE_SMP_IMPL_COPY_BASE(STD, PathEval)

    private :

    class work_
    {
        public :

        typedef typename Particle<T>::size_type size_type;

        work_ (PathEvalSTD<T, Derived> *path, std::size_t iter,
                const Particle<T> *particle, double *res) :
            path_(path), iter_(iter), particle_(particle), res_(res) {}

        void operator() (const BlockedRange<size_type> &range) const
        {
            for (size_type i = range.begin(); i != range.end(); ++i) {
                const Particle<T> *const part = particle_;
                res_[i] = path_->path_state(iter_,
                        ConstSingleParticle<T>(i, part));
            }
        }

        private :

        PathEvalSTD<T, Derived> *const path_;
        const std::size_t iter_;
        const Particle<T> *const particle_;
        double *const res_;
    }; // class work_
}; // PathEvalSTD

} // namespace vsmc

#endif // VSMC_SMP_BACKEND_STD_HPP
<commit_msg>stdtbb backend normalize weights parallelized<commit_after>#ifndef VSMC_SMP_BACKEND_STD_HPP
#define VSMC_SMP_BACKEND_STD_HPP

#include <vsmc/smp/base.hpp>
#include <vsmc/utility/stdtbb.hpp>
#include <vsmc/utility/tbb_op.hpp>

namespace vsmc {

/// \brief Particle::weight_set_type subtype using C++11 concurrency
/// \ingroup SMP
template <typename BaseState>
class WeightSetSTD : public traits::WeightSetTypeTrait<BaseState>::type
{
    typedef typename traits::WeightSetTypeTrait<BaseState>::type base;

    public :

    typedef typename traits::SizeTypeTrait<base>::type size_type;

    explicit WeightSetSTD (size_type N) : base(N) {}

    private :

    void log_weight2weight ()
    {
        const size_type N = static_cast<size_type>(this->size());
        parallel_for(BlockedRange<size_type>(0, N), tbb_op::exp<double>(
                    this->log_weight_ptr(), this->weight_ptr()));
    }

    void weight2log_weight ()
    {
        const size_type N = static_cast<size_type>(this->size());
        parallel_for(BlockedRange<size_type>(0, N), tbb_op::log<double>(
                    this->weight_ptr(), this->log_weight_ptr()));
    }

    void normalize_log_weight ()
    {
        const size_type N = static_cast<size_type>(this->size());
        tbb_op::maximum<double> max_weight(this->log_weight_ptr());
        parallel_reduce(BlockedRange<size_type>(0, N), max_weight);
        parallel_for(BlockedRange<size_type>(0, N), tbb_op::minus<double>(
                    this->log_weight_ptr(), this->log_weight_ptr(),
                    max_weight.result()));
    }

    void normalize_weight ()
    {
        const size_type N = static_cast<size_type>(this->size());
        tbb_op::summation<double> coeff(this->weight_ptr());
        parallel_reduce(BlockedRange<size_type>(0, N), coeff);
        parallel_for(BlockedRange<size_type>(0, N),
                tbb_op::multiplies<double>(
                    this->weight_ptr(), this->weight_ptr(),
                    1 / coeff.result()));
        tbb_op::square_sum<double> ess(this->weight_ptr());
        parallel_reduce(BlockedRange<size_type>(0, this->size()), ess);
        this->set_ess(1 / ess.result());
    }
}; // class WeightSetSTD

/// \brief Particle::value_type subtype using C++11 concurrency
/// \ingroup SMP
template <typename BaseState>
class StateSTD : public BaseState
{
    public :

    typedef typename traits::SizeTypeTrait<BaseState>::type size_type;

    explicit StateSTD (size_type N) : BaseState(N) {}

    template <typename IntType>
    void copy (size_type N, const IntType *copy_from)
    {
        VSMC_RUNTIME_ASSERT_STATE_COPY_SIZE_MISMATCH(STD);

        parallel_for(BlockedRange<size_type>(0, N),
                copy_work_<IntType>(this, copy_from));
    }

    private :

    template <typename IntType>
    class copy_work_
    {
        public :

        copy_work_ (StateSTD<BaseState> *state, const IntType *copy_from) :
            state_(state), copy_from_(copy_from) {}

        void operator() (const BlockedRange<size_type> &range) const
        {
            for (size_type to = range.begin(); to != range.end(); ++to)
                state_->copy_particle(copy_from_[to], to);
        }

        private :

        StateSTD<BaseState> *const state_;
        const IntType *const copy_from_;
    }; // class copy_work_
}; // class StateSTD

/// \brief Sampler<T>::init_type subtype using C++11 concurrency
/// \ingroup SMP
template <typename T, typename Derived>
class InitializeSTD : public InitializeBase<T, Derived>
{
    public :

    std::size_t operator() (Particle<T> &particle, void *param)
    {
        typedef typename Particle<T>::size_type size_type;
        const size_type N = static_cast<size_type>(particle.size());
        this->initialize_param(particle, param);
        this->pre_processor(particle);
        std::size_t accept = parallel_accumulate(BlockedRange<size_type>(0, N),
                work_(this, &particle), static_cast<std::size_t>(0));
        this->post_processor(particle);

        return accept;
    }

    protected :

    VSMC_DEFINE_SMP_IMPL_COPY_BASE(STD, Initialize)

    private :

    class work_
    {
        public :

        typedef typename Particle<T>::size_type size_type;

        work_ (InitializeSTD<T, Derived> *init,
                Particle<T> *particle) :
            init_(init), particle_(particle) {}

        void operator() (const BlockedRange<size_type> &range,
                std::size_t &accept) const
        {
            std::size_t acc = 0;
            for (size_type i = range.begin(); i != range.end(); ++i) {
                Particle<T> *const part = particle_;
                acc += init_->initialize_state(SingleParticle<T>(i, part));
            }
            accept = acc;
        }

        private :

        InitializeSTD<T, Derived> *const init_;
        Particle<T> *const particle_;
    }; // class work_
}; // class InitializeSTD

/// \brief Sampler<T>::move_type subtype using C++11 concurrency
/// \ingroup SMP
template <typename T, typename Derived>
class MoveSTD : public MoveBase<T, Derived>
{
    public :

    std::size_t operator() (std::size_t iter, Particle<T> &particle)
    {
        typedef typename Particle<T>::size_type size_type;
        const size_type N = static_cast<size_type>(particle.size());
        this->pre_processor(iter, particle);
        std::size_t accept = parallel_accumulate(BlockedRange<size_type>(0, N),
                work_(this, iter, &particle), static_cast<std::size_t>(0));
        this->post_processor(iter, particle);

        return accept;
    }

    protected :

    VSMC_DEFINE_SMP_IMPL_COPY_BASE(STD, Move)

    private :

    class work_
    {
        public :

        typedef typename Particle<T>::size_type size_type;

        work_ (MoveSTD<T, Derived> *move, std::size_t iter,
                Particle<T> *particle):
            move_(move), iter_(iter), particle_(particle) {}

        void operator() (const BlockedRange<size_type> &range,
                std::size_t &accept) const
        {
            std::size_t acc = 0;
            for (size_type i = range.begin(); i != range.end(); ++i) {
                Particle<T> *const part = particle_;
                acc += move_->move_state(iter_, SingleParticle<T>(i, part));
            }
            accept = acc;
        }

        private :

        MoveSTD<T, Derived> *const move_;
        const std::size_t iter_;
        Particle<T> *const particle_;
    }; // class work_
}; // class MoveSTD

/// \brief Monitor<T>::eval_type subtype using C++11 concurrency
/// \ingroup SMP
template <typename T, typename Derived>
class MonitorEvalSTD : public MonitorEvalBase<T, Derived>
{
    public :

    void operator() (std::size_t iter, std::size_t dim,
            const Particle<T> &particle, double *res)
    {
        typedef typename Particle<T>::size_type size_type;
        const size_type N = static_cast<size_type>(particle.size());
        this->pre_processor(iter, particle);
        parallel_for(BlockedRange<size_type>(0, N),
                work_(this, iter, dim, &particle, res));
        this->post_processor(iter, particle);
    }

    protected :

    VSMC_DEFINE_SMP_IMPL_COPY_BASE(STD, MonitorEval)

    private :

    class work_
    {
        public :

        typedef typename Particle<T>::size_type size_type;

        work_ (MonitorEvalSTD<T, Derived> *monitor,
                std::size_t iter, std::size_t dim,
                const Particle<T> *particle, double *res) :
            monitor_(monitor), iter_(iter), dim_(dim), particle_(particle),
            res_(res) {}

        void operator() (const BlockedRange<size_type> &range) const
        {
            for (size_type i = range.begin(); i != range.end(); ++i) {
                double *const r = res_ + i * dim_;
                const Particle<T> *const part = particle_;
                monitor_->monitor_state(iter_, dim_,
                        ConstSingleParticle<T>(i, part), r);
            }
        }

        private :

        MonitorEvalSTD<T, Derived> *const monitor_;
        const std::size_t iter_;
        const std::size_t dim_;
        const Particle<T> *const particle_;
        double *const res_;
    }; // class work_
}; // class MonitorEvalSTD

/// \brief Path<T>::eval_type subtype using C++11 concurrency
/// \ingroup SMP
template <typename T, typename Derived>
class PathEvalSTD : public PathEvalBase<T, Derived>
{
    public :

    double operator() (std::size_t iter, const Particle<T> &particle,
            double *res)
    {
        typedef typename Particle<T>::size_type size_type;
        const size_type N = static_cast<size_type>(particle.size());
        this->pre_processor(iter, particle);
        parallel_for(BlockedRange<size_type>(0, N),
                work_(this, iter, &particle, res));
        this->post_processor(iter, particle);

        return this->path_grid(iter, particle);
    }

    protected :

    VSMC_DEFINE_SMP_IMPL_COPY_BASE(STD, PathEval)

    private :

    class work_
    {
        public :

        typedef typename Particle<T>::size_type size_type;

        work_ (PathEvalSTD<T, Derived> *path, std::size_t iter,
                const Particle<T> *particle, double *res) :
            path_(path), iter_(iter), particle_(particle), res_(res) {}

        void operator() (const BlockedRange<size_type> &range) const
        {
            for (size_type i = range.begin(); i != range.end(); ++i) {
                const Particle<T> *const part = particle_;
                res_[i] = path_->path_state(iter_,
                        ConstSingleParticle<T>(i, part));
            }
        }

        private :

        PathEvalSTD<T, Derived> *const path_;
        const std::size_t iter_;
        const Particle<T> *const particle_;
        double *const res_;
    }; // class work_
}; // PathEvalSTD

} // namespace vsmc

#endif // VSMC_SMP_BACKEND_STD_HPP
<|endoftext|>


<commit_before>#ifndef VSMC_SMP_STATE_TUPLE_HPP
#define VSMC_SMP_STATE_TUPLE_HPP

#include <vsmc/smp/base.hpp>
#include <vsmc/core/single_particle.hpp>
#include <vsmc/utility/tuple_manip.hpp>

namespace vsmc {

/// \brief Base type of StateTuple
/// \ingroup SMP
template <MatrixOrder Order, typename T, typename... Types>
class StateTupleBase
{
    public :

    typedef std::size_t size_type;
    typedef std::tuple<T, Types...> state_tuple_type;

    template <std::size_t Pos> struct state_type
    {typedef typename std::tuple_element<Pos, state_tuple_type>::type type;};

    class state_pack_type
    {
        public :

        state_pack_type () {}

        state_pack_type (const state_tuple_type &data) : data_(data) {}

        operator state_tuple_type () {return data_;}

        template <std::size_t Pos>
        typename state_type<Pos>::type &get ()
        {return std::get<Pos>(data_);}

        template <std::size_t Pos>
        const typename state_type<Pos>::type &get () const
        {return std::get<Pos>(data_);}

        template <typename Archive>
        void serialize (Archive &ar, const unsigned)
        {serialize(ar, Position<0>());}

        template <typename Archive>
        void serialize (Archive &ar, const unsigned) const
        {serialize(ar, Position<0>());}

        private :

        state_tuple_type data_;
        static const std::size_t dim_ = sizeof...(Types) + 1;

        template <typename Archive, std::size_t Pos>
        void serialize (Archive &ar, Position<Pos>)
        {
            ar & std::get<Pos>(data_);
            serialize(ar, Position<Pos + 1>());
        }

        template <typename Archive>
        void serialize (Archive &ar, Position<dim_>) {}

        template <typename Archive, std::size_t Pos>
        void serialize (Archive &ar, Position<Pos>) const
        {
            ar & std::get<Pos>(data_);
            serialize(ar, Position<Pos + 1>());
        }

        template <typename Archive>
        void serialize (Archive &ar, Position<dim_>) const {}
    };

    template <typename S>
    struct single_particle_type : public SingleParticleBase<S>
    {
        single_particle_type (typename Particle<S>::size_type id,
                Particle<S> *particle_ptr) :
            SingleParticleBase<S>(id, particle_ptr) {}

        static VSMC_CONSTEXPR std::size_t dim () {return S::dim();}

        template <std::size_t Pos>
        typename state_type<Pos>::type &state (Position<Pos>) const
        {
            return this->mutable_particle_ptr()->value().
                state(this->id(), Position<Pos>());
        }

        template <std::size_t Pos>
        typename state_type<Pos>::type &state () const
        {return this->state(Position<Pos>());}
    };

    template <typename S>
    struct const_single_particle_type : public ConstSingleParticleBase<S>
    {
        const_single_particle_type (typename Particle<S>::size_type id,
                const Particle<S> *particle_ptr) :
            ConstSingleParticleBase<S>(id, particle_ptr) {}

        static VSMC_CONSTEXPR std::size_t dim () {return S::dim();}

        template <std::size_t Pos>
        const typename state_type<Pos>::type &state (Position<Pos>) const
        {
            return this->particle_ptr()->value().
                state(this->id(), Position<Pos>());
        }

        template <std::size_t Pos>
        const typename state_type<Pos>::type &state () const
        {return this->state(Position<Pos>());}
    };

    size_type size () const {return size_;}

    static VSMC_CONSTEXPR std::size_t dim () {return dim_;}

    state_pack_type state_pack (size_type id) const
    {
        state_pack_type pack;
        pack_particle(id, pack, Position<0>());

        return pack;
    }

    void state_unpack (size_type id, const state_pack_type &pack)
    {unpack_particle(id, pack, Position<0>());}

    template <typename IntType>
    void copy (size_type N, const IntType *copy_from)
    {
        VSMC_RUNTIME_ASSERT_STATE_COPY_SIZE_MISMATCH(Tuple);

        for (size_type to = 0; to != N; ++to)
            copy_particle(copy_from[to], to);
    }

    template <std::size_t Pos, typename OutputIter>
    OutputIter read_state (Position<Pos>, OutputIter first) const
    {
        const StateTuple<Order, T, Types...> *sptr =
            static_cast<const StateTuple<Order, T, Types...> *>(this);
        for (size_type i = 0; i != size_; ++i, ++first)
                *first = sptr->state(i, Position<Pos>());

        return first;
    }

    template <std::size_t Pos, typename OutputIter>
    OutputIter read_state (OutputIter first) const
    {return read_state(Position<Pos>(), first);}

    template <typename OutputStream>
    OutputStream &print (OutputStream &os, std::size_t iter = 0,
            char sepchar = ' ', char eolchar = '\n') const
    {
        for (size_type i = 0; i != size_; ++i) {
            os << iter << sepchar;
            print_particle(os, i, sepchar, eolchar, Position<0>());
        }

        return os;
    }

    protected :

    explicit StateTupleBase (size_type N) : size_(N) {}

    void copy_particle (size_type from, size_type to)
    {
        if (from != to)
            copy_particle(from, to, Position<0>());
    }

    private :

    size_type size_;
    static const std::size_t dim_ = sizeof...(Types) + 1;

    template <std::size_t Pos>
    void pack_particle (size_type id, state_pack_type &pack,
            Position<Pos>) const
    {
        const StateTuple<Order, T, Types...> *sptr =
            static_cast<const StateTuple<Order, T, Types...> *>(this);
        pack.template get<Pos>() = sptr->state(id, Position<Pos>());
        pack_particle(id, pack, Position<Pos + 1>());
    }

    void pack_particle (size_type id, state_pack_type &pack,
            Position<dim_>) const {}

    template <std::size_t Pos>
    void unpack_particle (size_type id, const state_pack_type &pack,
            Position<Pos>)
    {
        StateTuple<Order, T, Types...> *sptr =
            static_cast<StateTuple<Order, T, Types...> *>(this);
        sptr->state(id, Position<Pos>()) = pack.template get<Pos>();
        unpack_particle(id, pack, Position<Pos + 1>());
    }

    void unpack_particle (size_type id, const state_pack_type &pack,
            Position<dim_>) {}

    template <std::size_t Pos>
    void copy_particle (size_type from, size_type to, Position<Pos>)
    {
        StateTuple<Order, T, Types...> *sptr =
            static_cast<StateTuple<Order, T, Types...> *>(this);
        sptr->state(to, Position<Pos>()) = sptr->state(from, Position<Pos>());
        copy_particle(from, to, Position<Pos + 1>());
    }

    void copy_particle (size_type from, size_type to, Position<dim_>) {}

    template <typename OutputStream, std::size_t Pos>
    void print_particle (OutputStream &os, size_type id,
            char sepchar, char eolchar, Position<Pos>) const
    {
        const StateTuple<Order, T, Types...> *sptr =
            static_cast<const StateTuple<Order, T, Types...> *>(this);
        os << sptr->state(id, Position<Pos>()) << sepchar;
        print_particle(os, id, sepchar, eolchar, Position<Pos + 1>());
    }

    template <typename OutputStream>
    void print_particle (OutputStream &os, size_type id,
            char sepchar, char eolchar, Position<dim_ - 1>) const
    {
        const StateTuple<Order, T, Types...> *sptr =
            static_cast<const StateTuple<Order, T, Types...> *>(this);
        os << sptr->state(id, Position<dim_ - 1>()) << eolchar;
    }
}; // class StateTupleBase

/// \brief Particle::value_type subtype
/// \ingroup SMP
template <typename T, typename... Types>
class StateTuple<RowMajor, T, Types...> :
    public StateTupleBase<RowMajor, T, Types...>
{
    public :

    typedef StateTupleBase<RowMajor, T, Types...>
        state_tuple_base_type;
    typedef typename state_tuple_base_type::size_type size_type;

    explicit StateTuple (size_type N) : state_tuple_base_type(N), state_(N) {}

    template <std::size_t Pos>
    typename state_tuple_base_type::template state_type<Pos>::type
    &state (size_type id, Position<Pos>)
    {return std::get<Pos>(state_[id]);}

    template <std::size_t Pos>
    const typename state_tuple_base_type::template state_type<Pos>::type
    &state (size_type id, Position<Pos>) const
    {return std::get<Pos>(state_[id]);}

    template <std::size_t Pos>
    typename state_tuple_base_type::template state_type<Pos>::type
    &state (size_type id)
    {return state(id, Position<Pos>());}

    template <std::size_t Pos>
    const typename state_tuple_base_type::template state_type<Pos>::type
    &state (size_type id) const
    {return state(id, Position<Pos>());}

    private :

    std::vector<std::tuple<T, Types...> > state_;
}; // StateTuple

/// \brief Particle::value_type subtype
/// \ingroup SMP
template <typename T, typename... Types>
class StateTuple<ColMajor, T, Types...> :
    public StateTupleBase<ColMajor, T, Types...>
{
    public :

    typedef StateTupleBase<ColMajor, T, Types...>
        state_tuple_base_type;
    typedef typename state_tuple_base_type::size_type size_type;

    explicit StateTuple (size_type N) : state_tuple_base_type(N)
    {init_state(N, Position<0>());}

    template <std::size_t Pos>
    typename state_tuple_base_type::template state_type<Pos>::type
    &state (size_type id, Position<Pos>)
    {return std::get<Pos>(state_)[id];}

    template <std::size_t Pos>
    const typename state_tuple_base_type::template state_type<Pos>::type
    &state (size_type id, Position<Pos>) const
    {return std::get<Pos>(state_)[id];}

    template <std::size_t Pos>
    typename state_tuple_base_type::template state_type<Pos>::type
    &state (size_type id)
    {return state(id, Position<Pos>());}

    template <std::size_t Pos>
    const typename state_tuple_base_type::template state_type<Pos>::type
    &state (size_type id) const
    {return state(id, Position<Pos>());}

    private :

    typename tuple::TupleApplyVector<std::tuple<T, Types...> >::type state_;

    template <std::size_t Pos>
    void init_state (size_type N, Position<Pos>)
    {
        std::get<Pos>(state_).resize(N);
        init_state(N, Position<Pos + 1>());
    }

    void init_state (size_type N, Position<sizeof...(Types)>)
    {std::get<sizeof...(Types)>(state_).resize(N);}
}; // class StateTuple

} // namespace vsmc

#endif // VSMC_SMP_STATE_TUPLE_HPP
<commit_msg>add move for StateTuple::state_pack_type<commit_after>#ifndef VSMC_SMP_STATE_TUPLE_HPP
#define VSMC_SMP_STATE_TUPLE_HPP

#include <vsmc/smp/base.hpp>
#include <vsmc/core/single_particle.hpp>
#include <vsmc/utility/tuple_manip.hpp>

namespace vsmc {

/// \brief Base type of StateTuple
/// \ingroup SMP
template <MatrixOrder Order, typename T, typename... Types>
class StateTupleBase
{
    public :

    typedef std::size_t size_type;
    typedef std::tuple<T, Types...> state_tuple_type;

    template <std::size_t Pos> struct state_type
    {typedef typename std::tuple_element<Pos, state_tuple_type>::type type;};

    class state_pack_type
    {
        public :

        state_pack_type () {}

        state_pack_type (const state_pack_type &other) : data_(other.data_) {}

        state_pack_type &operator= (const state_pack_type &other)
        {
            if (this != &other)
                data_ = other.data_;

            return *this;
        }

#if VSMC_HAS_CXX11_RVALUE_REFERENCES
        state_pack_type (state_pack_type &&other) :
            data_(cxx11::move(other.data_)) {}

        state_pack_type &operator= (state_pack_type &&other)
        {
            if (this != &other)
                data_ = cxx11::move(other.data_);

            return *this;
        }
#endif

        state_pack_type (const state_tuple_type &data) : data_(data) {}

        operator state_tuple_type () {return data_;}

        template <std::size_t Pos>
        typename state_type<Pos>::type &get ()
        {return std::get<Pos>(data_);}

        template <std::size_t Pos>
        const typename state_type<Pos>::type &get () const
        {return std::get<Pos>(data_);}

        template <typename Archive>
        void serialize (Archive &ar, const unsigned)
        {serialize(ar, Position<0>());}

        template <typename Archive>
        void serialize (Archive &ar, const unsigned) const
        {serialize(ar, Position<0>());}

        private :

        state_tuple_type data_;
        static const std::size_t dim_ = sizeof...(Types) + 1;

        template <typename Archive, std::size_t Pos>
        void serialize (Archive &ar, Position<Pos>)
        {
            ar & std::get<Pos>(data_);
            serialize(ar, Position<Pos + 1>());
        }

        template <typename Archive>
        void serialize (Archive &ar, Position<dim_>) {}

        template <typename Archive, std::size_t Pos>
        void serialize (Archive &ar, Position<Pos>) const
        {
            ar & std::get<Pos>(data_);
            serialize(ar, Position<Pos + 1>());
        }

        template <typename Archive>
        void serialize (Archive &ar, Position<dim_>) const {}
    };

    template <typename S>
    struct single_particle_type : public SingleParticleBase<S>
    {
        single_particle_type (typename Particle<S>::size_type id,
                Particle<S> *particle_ptr) :
            SingleParticleBase<S>(id, particle_ptr) {}

        static VSMC_CONSTEXPR std::size_t dim () {return S::dim();}

        template <std::size_t Pos>
        typename state_type<Pos>::type &state (Position<Pos>) const
        {
            return this->mutable_particle_ptr()->value().
                state(this->id(), Position<Pos>());
        }

        template <std::size_t Pos>
        typename state_type<Pos>::type &state () const
        {return this->state(Position<Pos>());}
    };

    template <typename S>
    struct const_single_particle_type : public ConstSingleParticleBase<S>
    {
        const_single_particle_type (typename Particle<S>::size_type id,
                const Particle<S> *particle_ptr) :
            ConstSingleParticleBase<S>(id, particle_ptr) {}

        static VSMC_CONSTEXPR std::size_t dim () {return S::dim();}

        template <std::size_t Pos>
        const typename state_type<Pos>::type &state (Position<Pos>) const
        {
            return this->particle_ptr()->value().
                state(this->id(), Position<Pos>());
        }

        template <std::size_t Pos>
        const typename state_type<Pos>::type &state () const
        {return this->state(Position<Pos>());}
    };

    size_type size () const {return size_;}

    static VSMC_CONSTEXPR std::size_t dim () {return dim_;}

    state_pack_type state_pack (size_type id) const
    {
        state_pack_type pack;
        pack_particle(id, pack, Position<0>());

        return pack;
    }

    void state_unpack (size_type id, const state_pack_type &pack)
    {unpack_particle(id, pack, Position<0>());}

    template <typename IntType>
    void copy (size_type N, const IntType *copy_from)
    {
        VSMC_RUNTIME_ASSERT_STATE_COPY_SIZE_MISMATCH(Tuple);

        for (size_type to = 0; to != N; ++to)
            copy_particle(copy_from[to], to);
    }

    template <std::size_t Pos, typename OutputIter>
    OutputIter read_state (Position<Pos>, OutputIter first) const
    {
        const StateTuple<Order, T, Types...> *sptr =
            static_cast<const StateTuple<Order, T, Types...> *>(this);
        for (size_type i = 0; i != size_; ++i, ++first)
                *first = sptr->state(i, Position<Pos>());

        return first;
    }

    template <std::size_t Pos, typename OutputIter>
    OutputIter read_state (OutputIter first) const
    {return read_state(Position<Pos>(), first);}

    template <typename OutputStream>
    OutputStream &print (OutputStream &os, std::size_t iter = 0,
            char sepchar = ' ', char eolchar = '\n') const
    {
        for (size_type i = 0; i != size_; ++i) {
            os << iter << sepchar;
            print_particle(os, i, sepchar, eolchar, Position<0>());
        }

        return os;
    }

    protected :

    explicit StateTupleBase (size_type N) : size_(N) {}

    void copy_particle (size_type from, size_type to)
    {
        if (from != to)
            copy_particle(from, to, Position<0>());
    }

    private :

    size_type size_;
    static const std::size_t dim_ = sizeof...(Types) + 1;

    template <std::size_t Pos>
    void pack_particle (size_type id, state_pack_type &pack,
            Position<Pos>) const
    {
        const StateTuple<Order, T, Types...> *sptr =
            static_cast<const StateTuple<Order, T, Types...> *>(this);
        pack.template get<Pos>() = sptr->state(id, Position<Pos>());
        pack_particle(id, pack, Position<Pos + 1>());
    }

    void pack_particle (size_type id, state_pack_type &pack,
            Position<dim_>) const {}

    template <std::size_t Pos>
    void unpack_particle (size_type id, const state_pack_type &pack,
            Position<Pos>)
    {
        StateTuple<Order, T, Types...> *sptr =
            static_cast<StateTuple<Order, T, Types...> *>(this);
        sptr->state(id, Position<Pos>()) = pack.template get<Pos>();
        unpack_particle(id, pack, Position<Pos + 1>());
    }

    void unpack_particle (size_type id, const state_pack_type &pack,
            Position<dim_>) {}

    template <std::size_t Pos>
    void copy_particle (size_type from, size_type to, Position<Pos>)
    {
        StateTuple<Order, T, Types...> *sptr =
            static_cast<StateTuple<Order, T, Types...> *>(this);
        sptr->state(to, Position<Pos>()) = sptr->state(from, Position<Pos>());
        copy_particle(from, to, Position<Pos + 1>());
    }

    void copy_particle (size_type from, size_type to, Position<dim_>) {}

    template <typename OutputStream, std::size_t Pos>
    void print_particle (OutputStream &os, size_type id,
            char sepchar, char eolchar, Position<Pos>) const
    {
        const StateTuple<Order, T, Types...> *sptr =
            static_cast<const StateTuple<Order, T, Types...> *>(this);
        os << sptr->state(id, Position<Pos>()) << sepchar;
        print_particle(os, id, sepchar, eolchar, Position<Pos + 1>());
    }

    template <typename OutputStream>
    void print_particle (OutputStream &os, size_type id,
            char sepchar, char eolchar, Position<dim_ - 1>) const
    {
        const StateTuple<Order, T, Types...> *sptr =
            static_cast<const StateTuple<Order, T, Types...> *>(this);
        os << sptr->state(id, Position<dim_ - 1>()) << eolchar;
    }
}; // class StateTupleBase

/// \brief Particle::value_type subtype
/// \ingroup SMP
template <typename T, typename... Types>
class StateTuple<RowMajor, T, Types...> :
    public StateTupleBase<RowMajor, T, Types...>
{
    public :

    typedef StateTupleBase<RowMajor, T, Types...>
        state_tuple_base_type;
    typedef typename state_tuple_base_type::size_type size_type;

    explicit StateTuple (size_type N) : state_tuple_base_type(N), state_(N) {}

    template <std::size_t Pos>
    typename state_tuple_base_type::template state_type<Pos>::type
    &state (size_type id, Position<Pos>)
    {return std::get<Pos>(state_[id]);}

    template <std::size_t Pos>
    const typename state_tuple_base_type::template state_type<Pos>::type
    &state (size_type id, Position<Pos>) const
    {return std::get<Pos>(state_[id]);}

    template <std::size_t Pos>
    typename state_tuple_base_type::template state_type<Pos>::type
    &state (size_type id)
    {return state(id, Position<Pos>());}

    template <std::size_t Pos>
    const typename state_tuple_base_type::template state_type<Pos>::type
    &state (size_type id) const
    {return state(id, Position<Pos>());}

    private :

    std::vector<std::tuple<T, Types...> > state_;
}; // StateTuple

/// \brief Particle::value_type subtype
/// \ingroup SMP
template <typename T, typename... Types>
class StateTuple<ColMajor, T, Types...> :
    public StateTupleBase<ColMajor, T, Types...>
{
    public :

    typedef StateTupleBase<ColMajor, T, Types...>
        state_tuple_base_type;
    typedef typename state_tuple_base_type::size_type size_type;

    explicit StateTuple (size_type N) : state_tuple_base_type(N)
    {init_state(N, Position<0>());}

    template <std::size_t Pos>
    typename state_tuple_base_type::template state_type<Pos>::type
    &state (size_type id, Position<Pos>)
    {return std::get<Pos>(state_)[id];}

    template <std::size_t Pos>
    const typename state_tuple_base_type::template state_type<Pos>::type
    &state (size_type id, Position<Pos>) const
    {return std::get<Pos>(state_)[id];}

    template <std::size_t Pos>
    typename state_tuple_base_type::template state_type<Pos>::type
    &state (size_type id)
    {return state(id, Position<Pos>());}

    template <std::size_t Pos>
    const typename state_tuple_base_type::template state_type<Pos>::type
    &state (size_type id) const
    {return state(id, Position<Pos>());}

    private :

    typename tuple::TupleApplyVector<std::tuple<T, Types...> >::type state_;

    template <std::size_t Pos>
    void init_state (size_type N, Position<Pos>)
    {
        std::get<Pos>(state_).resize(N);
        init_state(N, Position<Pos + 1>());
    }

    void init_state (size_type N, Position<sizeof...(Types)>)
    {std::get<sizeof...(Types)>(state_).resize(N);}
}; // class StateTuple

} // namespace vsmc

#endif // VSMC_SMP_STATE_TUPLE_HPP
<|endoftext|>


<commit_before>#pragma once

#include "zmsg_cmm.hpp"

namespace zmsg {

template<>
struct zmsg<mid_t::motor_test_start> {
public:
	UINT32 FSPattern;
	UINT32 FibreType;
	UINT32 FibreAlignment;
	BOOL XImageFocus;
	BOOL YImageFocus;
	UINT32 FibreShift;
	BOOL DischargeStrengthAdjustment;
	BOOL TensionSet;
	FLOAT CutAngleLimit;
	FLOAT LossLimit;
	FLOAT FibreAngleLimit;
	ULONG CleanDischargeTime;
	ULONG FibreIntervalSetup;
	LONG  FSPosSetup;
	UINT16 FibrePreFSStrength;
	ULONG FibrePreFSTime;
	ULONG FibreOverlapSetup;
	UINT16 Discharge1Strength;
	ULONG Discharge1Time;
	UINT16 Discharge2Strength;
	ULONG Discharge2LastTime;
	ULONG Discharge2StartTime;
	ULONG Discharge2StopTime;
	ULONG ExtraManualDischargeTime;

	BOOL ConeFS;
	ULONG ConeFSWaitTime;
	ULONG ConeFSSpeed;
	ULONG ConeFSStretchLength;
	UINT32 LossEstimationMode;
	FLOAT LeftFibreMFD;
	FLOAT RightFibreMFD;
	FLOAT LeastLoss;
	FLOAT RateOfSyntropyBending;
	FLOAT RateOfReverseBending;
	FLOAT RateOfMFDDeviation;

	BOOL AutoStart;
	BOOL Stop1;
	BOOL Stop2;
	/*data dispaly*/
	BOOL CutAngle;
	BOOL OffsetData;
	/*omitted choice*/
	BOOL Cut;
	BOOL Loss;
	BOOL FibreCoreAngle;
	BOOL Bubble;
	BOOL Thick;
	BOOL Thin;
	/*dischargesupplement*/
	BOOL AirPressure;
	BOOL Temperature;
	/*fiber_image_display*/
	UINT32 ImgGap;
	UINT32 ImgStop1;
	UINT32 ImgAlign;
	UINT32 ImgStop2;
	UINT32 ImgDischarge;
	UINT32 ImgLossEstimation;
	/*else*/
	BOOL FibreAutoFeed;
	BOOL BadCutSurface;
	BOOL AutoAlignAfterStop;
	ULONG ManualDischargeTimes;

	/* motor test para */
	UINT32 MotorTestTimes;
	UINT32 ElectricArcTestTimes;
	UINT32 CleanArcRate;
public:
	ZMSG_PU(
		FSPattern,
		FibreType,
		FibreAlignment,
		XImageFocus,
		YImageFocus,
		FibreShift,
		DischargeStrengthAdjustment,
		TensionSet,
		CutAngleLimit,
		LossLimit,
		FibreAngleLimit,
		CleanDischargeTime,
		FibreIntervalSetup,
		FSPosSetup,
		FibrePreFSStrength,
		FibrePreFSTime,
		FibreOverlapSetup,
		Discharge1Strength,
		Discharge1Time,
		Discharge2Strength,
		Discharge2LastTime,
		Discharge2StartTime,
		Discharge2StopTime,
		ExtraManualDischargeTime,

		ConeFS,
		ConeFSWaitTime,
		ConeFSSpeed,
		ConeFSStretchLength,
		LossEstimationMode,
		LeftFibreMFD,
		RightFibreMFD,
		LeastLoss,
		RateOfSyntropyBending,
		RateOfReverseBending,
		RateOfMFDDeviation,

		AutoStart,
		Stop1,
		Stop2,
		CutAngle,
		OffsetData,
		Cut,
		Loss,
		FibreCoreAngle,
		Bubble,
		Thick,
		Thin,
		AirPressure,
		Temperature,
		ImgGap,
		ImgStop1,
		ImgAlign,
		ImgStop2,
		ImgDischarge,
		ImgLossEstimation,
		FibreAutoFeed,
		BadCutSurface,
		AutoAlignAfterStop,

		ManualDischargeTimes,
		MotorTestTimes,
		ElectricArcTestTimes,
		CleanArcRate)
};

template<>
struct zmsg<mid_t::motor_test_result> {
	motor_test_err_t code;
	/// \note following are error times
	UINT32 reset;
	UINT32 push;
	UINT32 ele_arc;
	UINT32 img;
public:
	ZMSG_PU(code, reset, push, ele_arc, img);
};

} /* namespace zmsg */

<commit_msg>zmsg: motor_test_result : add test times<commit_after>#pragma once

#include "zmsg_cmm.hpp"

namespace zmsg {

template<>
struct zmsg<mid_t::motor_test_start> {
public:
	UINT32 FSPattern;
	UINT32 FibreType;
	UINT32 FibreAlignment;
	BOOL XImageFocus;
	BOOL YImageFocus;
	UINT32 FibreShift;
	BOOL DischargeStrengthAdjustment;
	BOOL TensionSet;
	FLOAT CutAngleLimit;
	FLOAT LossLimit;
	FLOAT FibreAngleLimit;
	ULONG CleanDischargeTime;
	ULONG FibreIntervalSetup;
	LONG  FSPosSetup;
	UINT16 FibrePreFSStrength;
	ULONG FibrePreFSTime;
	ULONG FibreOverlapSetup;
	UINT16 Discharge1Strength;
	ULONG Discharge1Time;
	UINT16 Discharge2Strength;
	ULONG Discharge2LastTime;
	ULONG Discharge2StartTime;
	ULONG Discharge2StopTime;
	ULONG ExtraManualDischargeTime;

	BOOL ConeFS;
	ULONG ConeFSWaitTime;
	ULONG ConeFSSpeed;
	ULONG ConeFSStretchLength;
	UINT32 LossEstimationMode;
	FLOAT LeftFibreMFD;
	FLOAT RightFibreMFD;
	FLOAT LeastLoss;
	FLOAT RateOfSyntropyBending;
	FLOAT RateOfReverseBending;
	FLOAT RateOfMFDDeviation;

	BOOL AutoStart;
	BOOL Stop1;
	BOOL Stop2;
	/*data dispaly*/
	BOOL CutAngle;
	BOOL OffsetData;
	/*omitted choice*/
	BOOL Cut;
	BOOL Loss;
	BOOL FibreCoreAngle;
	BOOL Bubble;
	BOOL Thick;
	BOOL Thin;
	/*dischargesupplement*/
	BOOL AirPressure;
	BOOL Temperature;
	/*fiber_image_display*/
	UINT32 ImgGap;
	UINT32 ImgStop1;
	UINT32 ImgAlign;
	UINT32 ImgStop2;
	UINT32 ImgDischarge;
	UINT32 ImgLossEstimation;
	/*else*/
	BOOL FibreAutoFeed;
	BOOL BadCutSurface;
	BOOL AutoAlignAfterStop;
	ULONG ManualDischargeTimes;

	/* motor test para */
	UINT32 MotorTestTimes;
	UINT32 ElectricArcTestTimes;
	UINT32 CleanArcRate;
public:
	ZMSG_PU(
		FSPattern,
		FibreType,
		FibreAlignment,
		XImageFocus,
		YImageFocus,
		FibreShift,
		DischargeStrengthAdjustment,
		TensionSet,
		CutAngleLimit,
		LossLimit,
		FibreAngleLimit,
		CleanDischargeTime,
		FibreIntervalSetup,
		FSPosSetup,
		FibrePreFSStrength,
		FibrePreFSTime,
		FibreOverlapSetup,
		Discharge1Strength,
		Discharge1Time,
		Discharge2Strength,
		Discharge2LastTime,
		Discharge2StartTime,
		Discharge2StopTime,
		ExtraManualDischargeTime,

		ConeFS,
		ConeFSWaitTime,
		ConeFSSpeed,
		ConeFSStretchLength,
		LossEstimationMode,
		LeftFibreMFD,
		RightFibreMFD,
		LeastLoss,
		RateOfSyntropyBending,
		RateOfReverseBending,
		RateOfMFDDeviation,

		AutoStart,
		Stop1,
		Stop2,
		CutAngle,
		OffsetData,
		Cut,
		Loss,
		FibreCoreAngle,
		Bubble,
		Thick,
		Thin,
		AirPressure,
		Temperature,
		ImgGap,
		ImgStop1,
		ImgAlign,
		ImgStop2,
		ImgDischarge,
		ImgLossEstimation,
		FibreAutoFeed,
		BadCutSurface,
		AutoAlignAfterStop,

		ManualDischargeTimes,

		MotorTestTimes,
		ElectricArcTestTimes,
		CleanArcRate)
};

template<>
struct zmsg<mid_t::motor_test_result> {
	motor_test_err_t code;

	UINT32 motor_test_times;
	UINT32 ele_arc_test_times;

	/// \note following are error times
	UINT32 reset;
	UINT32 push;
	UINT32 ele_arc;
	UINT32 img;
public:
	ZMSG_PU(code, reset, push, ele_arc, img);
};

} /* namespace zmsg */

<|endoftext|>


<commit_before>#pragma once

#include "../std/string.hpp"

namespace classificator
{
  void ReadVisibility(string const & fPath);

  void Load();
}
<commit_msg>Remove obsolete declaration.<commit_after>#pragma once

#include "../std/string.hpp"

namespace classificator
{
  void Load();
}
<|endoftext|>


<commit_before>
// Note - python_bindings_common.h must be included before condor_common to avoid
// re-definition warnings.
#include "python_bindings_common.h"

#include "condor_adtypes.h"
#include "dc_collector.h"
#include "condor_version.h"

#include <memory>

#include "old_boost.h"
#include "classad_wrapper.h"
#include "module_lock.h"
#include "htcondor.h"
#include "daemon_location.h"

using namespace boost::python;

static boost::python::list
toList(const boost::shared_ptr<classad::ClassAd> ad, const std::vector<std::string> &attrs)
{
    int idx = 1;
    bool hasattr = true;
    boost::python::list result;
    while (hasattr)
    {
        hasattr = false;
        boost::shared_ptr<ClassAdWrapper> nextAd(new ClassAdWrapper());
        for (std::vector<std::string>::const_iterator it = attrs.begin(); it != attrs.end(); it++)
        {
            std::stringstream attr; attr << *it << idx;
            classad::ExprTree *expr = NULL;
            if ((expr = ad->Lookup(attr.str())))
            {
                classad::ExprTree *copy = expr->Copy();
                if (!copy) { THROW_EX(HTCondorInternalError, "Unable to create copy of ClassAd expression"); }
                if (!nextAd->Insert(*it, copy)) { THROW_EX(HTCondorInternalError, "Unable to copy attribute into destination ClassAd"); }
                hasattr = true;
            }
        }
        if (hasattr)
        {
            result.append(nextAd);
        }
        idx++;
    }
    return result;
}

struct Negotiator {

    void use_local_negotiator()
    {
        Daemon neg( DT_NEGOTIATOR, 0, 0 );
        bool result;
        {
        condor::ModuleLock ml;
        result = neg.locate();
        }

        if (result)
        {
            if (neg.addr())
            {
                m_addr = neg.addr();
            }
            else
            {
                THROW_EX(HTCondorLocateError, "Unable to locate negotiator address.");
            }
            m_version = neg.version() ? neg.version() : "";
        }
        else
        {
            THROW_EX(HTCondorLocateError, "Unable to locate local daemon");
        }
    }

    Negotiator() {
        use_local_negotiator();
    }

    Negotiator(boost::python::object loc)
      : m_addr(), m_version("")
    {
		int rv = construct_for_location(loc, DT_NEGOTIATOR, m_addr, m_version);
		if (rv == 0) {
			use_local_negotiator();
		} else if (rv < 0) {
			if (rv == -2) { boost::python::throw_error_already_set(); }
			THROW_EX(HTCondorValueError, "Unknown type");
		}
	}

    ~Negotiator()
    {
    }

    boost::python::object location() const {
        return make_daemon_location(DT_NEGOTIATOR, m_addr, m_version);
    }

    void setPriority(const std::string &user, float prio)
    {
        if (prio < 0) THROW_EX(HTCondorValueError, "User priority must be non-negative");
        sendUserValue(SET_PRIORITY, user, prio);
    }

    void setFactor(const std::string &user, float factor)
    {
        if (factor<1) THROW_EX(HTCondorValueError, "Priority factors must be >= 1");
        sendUserValue(SET_PRIORITYFACTOR, user, factor);
    }

    void setUsage(const std::string &user, float usage)
    {
        if (usage < 0) THROW_EX(HTCondorValueError, "Usage must be non-negative.");
        sendUserValue(SET_ACCUMUSAGE, user, usage);
    }

    void setBeginUsage(const std::string &user, time_t time)
    {
        sendUserValue(SET_BEGINTIME, user, time);
    }

    void setLastUsage(const std::string &user, time_t time)
    {
        sendUserValue(SET_LASTTIME, user, time);
    }

	void setCeiling(const std::string &user, float ceiling)
	{
        if (ceiling < -1) THROW_EX(HTCondorValueError, "Ceiling must be greater than -1.");
        sendUserValue(SET_CEILING, user, ceiling);
	}

    void resetUsage(const std::string &user)
    {
        sendUserCmd(RESET_USAGE, user);
    }

    void deleteUser(const std::string &user)
    {
        sendUserCmd(DELETE_USER, user);
    }

    void resetAllUsage()
    {
        Daemon negotiator(DT_NEGOTIATOR, m_addr.c_str());
        bool result;
        {
        condor::ModuleLock ml;
        result = negotiator.sendCommand(RESET_ALL_USAGE, Stream::reli_sock, 0);
        }
        if (!result)
        {
                THROW_EX(HTCondorIOError, "Failed to send RESET_ALL_USAGE command");
        }
    }

    boost::python::list
    getResourceUsage(const std::string &user)
    {
        checkUser(user);

        boost::shared_ptr<Sock> sock = getSocket(GET_RESLIST);
        if (!sock->put(user.c_str()) ||
            !sock->end_of_message())
        {
            sock->close();
            THROW_EX(HTCondorIOError, "Failed to send GET_RESLIST command to negotiator" );
        }
        sock->decode();
        boost::shared_ptr<ClassAdWrapper> ad(new ClassAdWrapper());
        bool result;
        {
        condor::ModuleLock ml;
        result = !getClassAdNoTypes(sock.get(), *ad.get()) || !sock->end_of_message();
        }
        if (result)
        {
            sock->close();
            THROW_EX(HTCondorIOError, "Failed to get classad from negotiator");
        }
        sock->close();

        std::vector<std::string> attrs;
        attrs.push_back("Name");
        attrs.push_back("StartTime");
        return toList(ad, attrs);
    }

    boost::python::list
    getPriorities(bool rollup=false)
    {
        boost::shared_ptr<Sock> sock = getSocket(rollup ? GET_PRIORITY_ROLLUP : GET_PRIORITY);

        sock->decode();
        boost::shared_ptr<ClassAdWrapper> ad(new ClassAdWrapper());
        bool result;
        {
        condor::ModuleLock ml;
        result = !getClassAdNoTypes(sock.get(), *ad.get()) || !sock->end_of_message();
        }
        if (result)
        {
            sock->close();
            THROW_EX(HTCondorIOError, "Failed to get classad from negotiator");
        }
        sock->close();

        std::vector<std::string> attrs;
        attrs.push_back("Name");
        attrs.push_back("Priority");
        attrs.push_back("ResourcesUsed");
        attrs.push_back("Requested");
        attrs.push_back("WeightedResourcesUsed");
        attrs.push_back("PriorityFactor");
        attrs.push_back("BeginUsageTime");
        attrs.push_back("LastUsageTime");
        attrs.push_back("WeightedAccumulatedUsage");
        attrs.push_back("AccountingGroup");
        attrs.push_back("IsAccountingGroup");
        attrs.push_back("AccumulatedUsage");
        return toList(ad, attrs);
    }

private:

    void checkUser(const std::string &user)
    {
        if( user.find('@') == std::string::npos )
        {
            THROW_EX(HTCondorValueError, "You must specify the full name of the submittor you wish (user@uid.domain)");
        }
    }

    boost::shared_ptr<Sock> getSocket(int cmd)
    {
        Daemon negotiator(DT_NEGOTIATOR, m_addr.c_str());
        Sock *raw_sock;
        {
        condor::ModuleLock ml;
        raw_sock = negotiator.startCommand(cmd, Stream::reli_sock, 0);
        }
        boost::shared_ptr<Sock> sock(raw_sock);
        if (!sock.get()) { THROW_EX(HTCondorIOError, "Unable to connect to the negotiator"); }
        return sock;
    }

    void sendUserValue(int cmd, const std::string &user, float val)
    {
        checkUser(user);
        boost::shared_ptr<Sock> sock = getSocket(cmd);

        bool retval;
        {
        condor::ModuleLock ml;
        retval = !sock->put(user.c_str()) || !sock->put(val) || !sock->end_of_message();
        }
        if (retval)
        {
            sock->close();
            THROW_EX(HTCondorIOError, "Failed to send command to negotiator\n" );
        }
        sock->close();
    }

    void sendUserValue(int cmd, const std::string &user, time_t val)
    {
        checkUser(user);
        boost::shared_ptr<Sock> sock = getSocket(cmd);

        bool retval;
        {
        condor::ModuleLock ml;
        retval = !sock->put(user.c_str()) || !sock->put(val) || !sock->end_of_message();
        }
        if (retval)
        {
            sock->close();
            THROW_EX(HTCondorIOError, "Failed to send command to negotiator\n" );
        }
        sock->close();
    }

    void sendUserCmd(int cmd, const std::string &user)
    {
        checkUser(user);
        boost::shared_ptr<Sock> sock = getSocket(cmd);

        bool retval;
        {
        condor::ModuleLock ml;
        retval = !sock->put(user.c_str()) || !sock->end_of_message();
        }
        if (retval)
        {
            sock->close();
            THROW_EX(HTCondorIOError, "Failed to send command to negotiator\n" );
        }
        sock->close();
    }

    std::string m_addr;
    std::string m_version;

};

BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(priority_overloads, getPriorities, 0, 1);

void export_negotiator()
{
    class_<Negotiator>("Negotiator",
            R"C0ND0R(
            This class provides a query interface to the *condor_negotiator*.
            It primarily allows one to query and set various parameters in the fair-share accounting.
            )C0ND0R",
        init<boost::python::object>(
            R"C0ND0R(
            :param location_ad: A ClassAd or DaemonLocation describing the *condor_negotiator*
                location and version.  If omitted, the default pool negotiator is assumed.
            :type location_ad: :class:`~classad.ClassAd` or :class:`DaemonLocation`
            )C0ND0R",
            boost::python::args("self", "ad")))
        .def(boost::python::init<>(boost::python::args("self")))
        .add_property("location", &Negotiator::location,
            R"C0ND0R(
            The negotiator to query or send commands to
            :rtype: location :class:`DaemonLocation`
            )C0ND0R")
        .def("setPriority", &Negotiator::setPriority,
            R"C0ND0R(
            Set the real priority of a specified user.

            :param str user: A fully-qualified user name (``USER@DOMAIN``).
            :param float prio: The priority to be set for the user; must be greater-than 0.0.
            )C0ND0R",
            boost::python::args("self", "user", "prio"))
        .def("setFactor", &Negotiator::setFactor,
            R"C0ND0R(
            Set the priority factor of a specified user.

            :param str user: A fully-qualified user name (``USER@DOMAIN``).
            :param float factor: The priority factor to be set for the user; must be greater-than or equal-to 1.0.
            )C0ND0R",
            boost::python::args("self", "user", "factor"))
        .def("setCeiling", &Negotiator::setCeiling,
            R"C0ND0R(
            Set the submitter ceiling of a specified user.

            :param str user: A fully-qualified user name (``USER@DOMAIN``).
            :param float ceiling: The ceiling t be set for the submitter; must be greater-than or equal-to -1.0.
            )C0ND0R",
            boost::python::args("self", "user", "ceiling"))
        .def("setUsage", &Negotiator::setUsage,
            R"C0ND0R(
            Set the accumulated usage of a specified user.

            :param str user: A fully-qualified user name (``USER@DOMAIN``).
            :param float usage: The usage, in hours, to be set for the user.
            )C0ND0R",
            boost::python::args("self", "user", "usage"))
        .def("setBeginUsage", &Negotiator::setBeginUsage,
            R"C0ND0R(
            Manually set the time that a user begins using the pool.

            :param str user: A fully-qualified user name (``USER@DOMAIN``).
            :param int value: The Unix timestamp of initial usage.
            )C0ND0R",
            boost::python::args("self", "user", "value"))
        .def("setLastUsage", &Negotiator::setLastUsage,
            R"C0ND0R(
            Manually set the time that a user last used the pool.

            :param str user: A fully-qualified user name (``USER@DOMAIN``).
            :param int value: The Unix timestamp of last usage.
            )C0ND0R",
            boost::python::args("self", "user", "value"))
        .def("resetUsage", &Negotiator::resetUsage,
            R"C0ND0R(
            Reset all usage accounting of the specified user.

            :param str user: A fully-qualified user name (``USER@DOMAIN``).
            )C0ND0R",
            boost::python::args("self", "user"))
        .def("deleteUser", &Negotiator::deleteUser,
            R"C0ND0R(
            Delete all records of a user from the Negotiator's fair-share accounting.

            :param str user: A fully-qualified user name (``USER@DOMAIN``).
            )C0ND0R",
            boost::python::args("self", "user"))
        .def("resetAllUsage", &Negotiator::resetAllUsage,
            R"C0ND0R(
            Reset all usage accounting.  All known user records in the negotiator are deleted.
            )C0ND0R",
            boost::python::args("self"))
        .def("getResourceUsage", &Negotiator::getResourceUsage,
            R"C0ND0R(
            Get the resources (slots) used by a specified user.

            :param str user: A fully-qualified user name (``USER@DOMAIN``).
            :return: List of ads describing the resources (slots) in use.
            :rtype: list[:class:`~classad.ClassAd`]
            )C0ND0R",
            boost::python::args("self", "user"))
        .def("getPriorities", &Negotiator::getPriorities, priority_overloads(
            R"C0ND0R(
            Retrieve the pool accounting information, one per entry.
            Returns a list of accounting ClassAds.

            :param bool rollup: Set to ``True`` if accounting information, as applied to
                hierarchical group quotas, should be summed for groups and subgroups.
            :return: A list of accounting ads, one per entity.
            :rtype: list[:class:`~classad.ClassAd`]
            )C0ND0R",
            boost::python::args("self", "rollup")))
        ;
}
<commit_msg>Updated negotiator.getPriorites python binding to include ceiling (HTCONDOR-560)<commit_after>
// Note - python_bindings_common.h must be included before condor_common to avoid
// re-definition warnings.
#include "python_bindings_common.h"

#include "condor_adtypes.h"
#include "dc_collector.h"
#include "condor_version.h"

#include <memory>

#include "old_boost.h"
#include "classad_wrapper.h"
#include "module_lock.h"
#include "htcondor.h"
#include "daemon_location.h"

using namespace boost::python;

static boost::python::list
toList(const boost::shared_ptr<classad::ClassAd> ad, const std::vector<std::string> &attrs)
{
    int idx = 1;
    bool hasattr = true;
    boost::python::list result;
    while (hasattr)
    {
        hasattr = false;
        boost::shared_ptr<ClassAdWrapper> nextAd(new ClassAdWrapper());
        for (std::vector<std::string>::const_iterator it = attrs.begin(); it != attrs.end(); it++)
        {
            std::stringstream attr; attr << *it << idx;
            classad::ExprTree *expr = NULL;
            if ((expr = ad->Lookup(attr.str())))
            {
                classad::ExprTree *copy = expr->Copy();
                if (!copy) { THROW_EX(HTCondorInternalError, "Unable to create copy of ClassAd expression"); }
                if (!nextAd->Insert(*it, copy)) { THROW_EX(HTCondorInternalError, "Unable to copy attribute into destination ClassAd"); }
                hasattr = true;
            }
        }
        if (hasattr)
        {
            result.append(nextAd);
        }
        idx++;
    }
    return result;
}

struct Negotiator {

    void use_local_negotiator()
    {
        Daemon neg( DT_NEGOTIATOR, 0, 0 );
        bool result;
        {
        condor::ModuleLock ml;
        result = neg.locate();
        }

        if (result)
        {
            if (neg.addr())
            {
                m_addr = neg.addr();
            }
            else
            {
                THROW_EX(HTCondorLocateError, "Unable to locate negotiator address.");
            }
            m_version = neg.version() ? neg.version() : "";
        }
        else
        {
            THROW_EX(HTCondorLocateError, "Unable to locate local daemon");
        }
    }

    Negotiator() {
        use_local_negotiator();
    }

    Negotiator(boost::python::object loc)
      : m_addr(), m_version("")
    {
		int rv = construct_for_location(loc, DT_NEGOTIATOR, m_addr, m_version);
		if (rv == 0) {
			use_local_negotiator();
		} else if (rv < 0) {
			if (rv == -2) { boost::python::throw_error_already_set(); }
			THROW_EX(HTCondorValueError, "Unknown type");
		}
	}

    ~Negotiator()
    {
    }

    boost::python::object location() const {
        return make_daemon_location(DT_NEGOTIATOR, m_addr, m_version);
    }

    void setPriority(const std::string &user, float prio)
    {
        if (prio < 0) THROW_EX(HTCondorValueError, "User priority must be non-negative");
        sendUserValue(SET_PRIORITY, user, prio);
    }

    void setFactor(const std::string &user, float factor)
    {
        if (factor<1) THROW_EX(HTCondorValueError, "Priority factors must be >= 1");
        sendUserValue(SET_PRIORITYFACTOR, user, factor);
    }

    void setUsage(const std::string &user, float usage)
    {
        if (usage < 0) THROW_EX(HTCondorValueError, "Usage must be non-negative.");
        sendUserValue(SET_ACCUMUSAGE, user, usage);
    }

    void setBeginUsage(const std::string &user, time_t time)
    {
        sendUserValue(SET_BEGINTIME, user, time);
    }

    void setLastUsage(const std::string &user, time_t time)
    {
        sendUserValue(SET_LASTTIME, user, time);
    }

	void setCeiling(const std::string &user, float ceiling)
	{
        if (ceiling < -1) THROW_EX(HTCondorValueError, "Ceiling must be greater than -1.");
        sendUserValue(SET_CEILING, user, ceiling);
	}

    void resetUsage(const std::string &user)
    {
        sendUserCmd(RESET_USAGE, user);
    }

    void deleteUser(const std::string &user)
    {
        sendUserCmd(DELETE_USER, user);
    }

    void resetAllUsage()
    {
        Daemon negotiator(DT_NEGOTIATOR, m_addr.c_str());
        bool result;
        {
        condor::ModuleLock ml;
        result = negotiator.sendCommand(RESET_ALL_USAGE, Stream::reli_sock, 0);
        }
        if (!result)
        {
                THROW_EX(HTCondorIOError, "Failed to send RESET_ALL_USAGE command");
        }
    }

    boost::python::list
    getResourceUsage(const std::string &user)
    {
        checkUser(user);

        boost::shared_ptr<Sock> sock = getSocket(GET_RESLIST);
        if (!sock->put(user.c_str()) ||
            !sock->end_of_message())
        {
            sock->close();
            THROW_EX(HTCondorIOError, "Failed to send GET_RESLIST command to negotiator" );
        }
        sock->decode();
        boost::shared_ptr<ClassAdWrapper> ad(new ClassAdWrapper());
        bool result;
        {
        condor::ModuleLock ml;
        result = !getClassAdNoTypes(sock.get(), *ad.get()) || !sock->end_of_message();
        }
        if (result)
        {
            sock->close();
            THROW_EX(HTCondorIOError, "Failed to get classad from negotiator");
        }
        sock->close();

        std::vector<std::string> attrs;
        attrs.push_back("Name");
        attrs.push_back("StartTime");
        return toList(ad, attrs);
    }

    boost::python::list
    getPriorities(bool rollup=false)
    {
        boost::shared_ptr<Sock> sock = getSocket(rollup ? GET_PRIORITY_ROLLUP : GET_PRIORITY);

        sock->decode();
        boost::shared_ptr<ClassAdWrapper> ad(new ClassAdWrapper());
        bool result;
        {
        condor::ModuleLock ml;
        result = !getClassAdNoTypes(sock.get(), *ad.get()) || !sock->end_of_message();
        }
        if (result)
        {
            sock->close();
            THROW_EX(HTCondorIOError, "Failed to get classad from negotiator");
        }
        sock->close();

        std::vector<std::string> attrs;
        attrs.push_back("Name");
        attrs.push_back("Priority");
        attrs.push_back("ResourcesUsed");
        attrs.push_back("Requested");
        attrs.push_back("WeightedResourcesUsed");
        attrs.push_back("PriorityFactor");
        attrs.push_back("BeginUsageTime");
        attrs.push_back("LastUsageTime");
        attrs.push_back("WeightedAccumulatedUsage");
        attrs.push_back("AccountingGroup");
        attrs.push_back("IsAccountingGroup");
        attrs.push_back("AccumulatedUsage");
        attrs.push_back("Ceiling");
        return toList(ad, attrs);
    }

private:

    void checkUser(const std::string &user)
    {
        if( user.find('@') == std::string::npos )
        {
            THROW_EX(HTCondorValueError, "You must specify the full name of the submittor you wish (user@uid.domain)");
        }
    }

    boost::shared_ptr<Sock> getSocket(int cmd)
    {
        Daemon negotiator(DT_NEGOTIATOR, m_addr.c_str());
        Sock *raw_sock;
        {
        condor::ModuleLock ml;
        raw_sock = negotiator.startCommand(cmd, Stream::reli_sock, 0);
        }
        boost::shared_ptr<Sock> sock(raw_sock);
        if (!sock.get()) { THROW_EX(HTCondorIOError, "Unable to connect to the negotiator"); }
        return sock;
    }

    void sendUserValue(int cmd, const std::string &user, float val)
    {
        checkUser(user);
        boost::shared_ptr<Sock> sock = getSocket(cmd);

        bool retval;
        {
        condor::ModuleLock ml;
        retval = !sock->put(user.c_str()) || !sock->put(val) || !sock->end_of_message();
        }
        if (retval)
        {
            sock->close();
            THROW_EX(HTCondorIOError, "Failed to send command to negotiator\n" );
        }
        sock->close();
    }

    void sendUserValue(int cmd, const std::string &user, time_t val)
    {
        checkUser(user);
        boost::shared_ptr<Sock> sock = getSocket(cmd);

        bool retval;
        {
        condor::ModuleLock ml;
        retval = !sock->put(user.c_str()) || !sock->put(val) || !sock->end_of_message();
        }
        if (retval)
        {
            sock->close();
            THROW_EX(HTCondorIOError, "Failed to send command to negotiator\n" );
        }
        sock->close();
    }

    void sendUserCmd(int cmd, const std::string &user)
    {
        checkUser(user);
        boost::shared_ptr<Sock> sock = getSocket(cmd);

        bool retval;
        {
        condor::ModuleLock ml;
        retval = !sock->put(user.c_str()) || !sock->end_of_message();
        }
        if (retval)
        {
            sock->close();
            THROW_EX(HTCondorIOError, "Failed to send command to negotiator\n" );
        }
        sock->close();
    }

    std::string m_addr;
    std::string m_version;

};

BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(priority_overloads, getPriorities, 0, 1);

void export_negotiator()
{
    class_<Negotiator>("Negotiator",
            R"C0ND0R(
            This class provides a query interface to the *condor_negotiator*.
            It primarily allows one to query and set various parameters in the fair-share accounting.
            )C0ND0R",
        init<boost::python::object>(
            R"C0ND0R(
            :param location_ad: A ClassAd or DaemonLocation describing the *condor_negotiator*
                location and version.  If omitted, the default pool negotiator is assumed.
            :type location_ad: :class:`~classad.ClassAd` or :class:`DaemonLocation`
            )C0ND0R",
            boost::python::args("self", "ad")))
        .def(boost::python::init<>(boost::python::args("self")))
        .add_property("location", &Negotiator::location,
            R"C0ND0R(
            The negotiator to query or send commands to
            :rtype: location :class:`DaemonLocation`
            )C0ND0R")
        .def("setPriority", &Negotiator::setPriority,
            R"C0ND0R(
            Set the real priority of a specified user.

            :param str user: A fully-qualified user name (``USER@DOMAIN``).
            :param float prio: The priority to be set for the user; must be greater-than 0.0.
            )C0ND0R",
            boost::python::args("self", "user", "prio"))
        .def("setFactor", &Negotiator::setFactor,
            R"C0ND0R(
            Set the priority factor of a specified user.

            :param str user: A fully-qualified user name (``USER@DOMAIN``).
            :param float factor: The priority factor to be set for the user; must be greater-than or equal-to 1.0.
            )C0ND0R",
            boost::python::args("self", "user", "factor"))
        .def("setCeiling", &Negotiator::setCeiling,
            R"C0ND0R(
            Set the submitter ceiling of a specified user.

            :param str user: A fully-qualified user name (``USER@DOMAIN``).
            :param float ceiling: The ceiling t be set for the submitter; must be greater-than or equal-to -1.0.
            )C0ND0R",
            boost::python::args("self", "user", "ceiling"))
        .def("setUsage", &Negotiator::setUsage,
            R"C0ND0R(
            Set the accumulated usage of a specified user.

            :param str user: A fully-qualified user name (``USER@DOMAIN``).
            :param float usage: The usage, in hours, to be set for the user.
            )C0ND0R",
            boost::python::args("self", "user", "usage"))
        .def("setBeginUsage", &Negotiator::setBeginUsage,
            R"C0ND0R(
            Manually set the time that a user begins using the pool.

            :param str user: A fully-qualified user name (``USER@DOMAIN``).
            :param int value: The Unix timestamp of initial usage.
            )C0ND0R",
            boost::python::args("self", "user", "value"))
        .def("setLastUsage", &Negotiator::setLastUsage,
            R"C0ND0R(
            Manually set the time that a user last used the pool.

            :param str user: A fully-qualified user name (``USER@DOMAIN``).
            :param int value: The Unix timestamp of last usage.
            )C0ND0R",
            boost::python::args("self", "user", "value"))
        .def("resetUsage", &Negotiator::resetUsage,
            R"C0ND0R(
            Reset all usage accounting of the specified user.

            :param str user: A fully-qualified user name (``USER@DOMAIN``).
            )C0ND0R",
            boost::python::args("self", "user"))
        .def("deleteUser", &Negotiator::deleteUser,
            R"C0ND0R(
            Delete all records of a user from the Negotiator's fair-share accounting.

            :param str user: A fully-qualified user name (``USER@DOMAIN``).
            )C0ND0R",
            boost::python::args("self", "user"))
        .def("resetAllUsage", &Negotiator::resetAllUsage,
            R"C0ND0R(
            Reset all usage accounting.  All known user records in the negotiator are deleted.
            )C0ND0R",
            boost::python::args("self"))
        .def("getResourceUsage", &Negotiator::getResourceUsage,
            R"C0ND0R(
            Get the resources (slots) used by a specified user.

            :param str user: A fully-qualified user name (``USER@DOMAIN``).
            :return: List of ads describing the resources (slots) in use.
            :rtype: list[:class:`~classad.ClassAd`]
            )C0ND0R",
            boost::python::args("self", "user"))
        .def("getPriorities", &Negotiator::getPriorities, priority_overloads(
            R"C0ND0R(
            Retrieve the pool accounting information, one per entry.
            Returns a list of accounting ClassAds.

            :param bool rollup: Set to ``True`` if accounting information, as applied to
                hierarchical group quotas, should be summed for groups and subgroups.
            :return: A list of accounting ads, one per entity.
            :rtype: list[:class:`~classad.ClassAd`]
            )C0ND0R",
            boost::python::args("self", "rollup")))
        ;
}
<|endoftext|>


<commit_before>// Copyright 2010-2013 RethinkDB, all rights reserved.
#include "rdb_protocol/terms/terms.hpp"

#include <string>

#include "rdb_protocol/op.hpp"
#include "rdb_protocol/error.hpp"
#include "rdb_protocol/pb_utils.hpp"
#include "rdb_protocol/minidriver.hpp"

namespace ql {

// This file implements terms that are rewritten into other terms.

class rewrite_term_t : public term_t {
public:
    rewrite_term_t(compile_env_t *env, protob_t<const Term> term, argspec_t argspec,
                   r::reql_t (*rewrite)(protob_t<const Term> in,
                                        const pb_rcheckable_t *bt_src,
                                        protob_t<const Term> optargs_in))
        : term_t(term), in(term), out(make_counted_term()) {
        int args_size = in->args_size();
        rcheck(argspec.contains(args_size),
               base_exc_t::GENERIC,
               strprintf("Expected %s but found %d.",
                         argspec.print().c_str(), args_size));
        out->Swap(&rewrite(in, this, in).get());
        propagate(out.get()); // duplicates `in` backtrace (see `pb_rcheckable_t`)
        real = compile_term(env, out);
    }

private:
    virtual void accumulate_captures(var_captures_t *captures) const {
        return real->accumulate_captures(captures);
    }
    virtual bool is_deterministic() const {
        return real->is_deterministic();
    }

    virtual counted_t<val_t> term_eval(scope_env_t *env, eval_flags_t) const {
        return real->eval(env);
    }

    protob_t<const Term> in;
    protob_t<Term> out;

    counted_t<const term_t> real;
};

class inner_join_term_t : public rewrite_term_t {
public:
    inner_join_term_t(compile_env_t *env, const protob_t<const Term> &term)
        : rewrite_term_t(env, term, argspec_t(3), rewrite) { }

    static r::reql_t rewrite(protob_t<const Term> in,
                             UNUSED const pb_rcheckable_t *bt_src,
                             protob_t<const Term> optargs_in) {
        const Term &left = in->args(0);
        const Term &right = in->args(1);
        const Term &func = in->args(2);
        auto n = pb::dummy_var_t::INNERJOIN_N;
        auto m = pb::dummy_var_t::INNERJOIN_M;

        r::reql_t term =
            r::expr(left).concat_map(
                r::fun(n,
                    r::expr(right).concat_map(
                        r::fun(m,
                            r::branch(
                                r::expr(func)(r::var(n), r::var(m)),
                                r::array(r::object(
                                        r::optarg("left", n), r::optarg("right", m))),
                                r::array())))));

        term.copy_optargs_from_term(*optargs_in);
        return term;
    }

    virtual const char *name() const { return "inner_join"; }
};

class outer_join_term_t : public rewrite_term_t {
public:
    outer_join_term_t(compile_env_t *env, const protob_t<const Term> &term) :
        rewrite_term_t(env, term, argspec_t(3), rewrite) { }

    static r::reql_t rewrite(protob_t<const Term> in,
                             UNUSED const pb_rcheckable_t *bt_src,
                             protob_t<const Term> optargs_in) {
        const Term &left = in->args(0);
        const Term &right = in->args(1);
        const Term &func = in->args(2);
        auto n = pb::dummy_var_t::OUTERJOIN_N;
        auto m = pb::dummy_var_t::OUTERJOIN_M;
        auto lst = pb::dummy_var_t::OUTERJOIN_LST;

        r::reql_t inner_concat_map =
            r::expr(right).concat_map(
                r::fun(m,
                    r::branch(
                        r::expr(func)(n, m),
                        r::array(r::object(r::optarg("left", n), r::optarg("right", m))),
                        r::array())));

        r::reql_t term =
            r::expr(left).concat_map(
                r::fun(n,
                    std::move(inner_concat_map).coerce_to("ARRAY").do_(lst,
                        r::branch(
                            r::expr(lst).count() > 0,
                            lst,
                            r::array(r::object(r::optarg("left", n)))))));

        term.copy_optargs_from_term(*optargs_in);
        return term;
    }

    virtual const char *name() const { return "outer_join"; }
};

class eq_join_term_t : public rewrite_term_t {
public:
    eq_join_term_t(compile_env_t *env, const protob_t<const Term> &term) :
        rewrite_term_t(env, term, argspec_t(3), rewrite) { }
private:

    static r::reql_t rewrite(protob_t<const Term> in,
                             UNUSED const pb_rcheckable_t *bt_src,
                             protob_t<const Term> optargs_in) {
        const Term &left = in->args(0);
        const Term &left_attr = in->args(1);
        const Term &right = in->args(2);

        auto row = pb::dummy_var_t::EQJOIN_ROW;
        auto v = pb::dummy_var_t::EQJOIN_V;

        r::reql_t get_all =
            r::expr(right).get_all(
                r::expr(left_attr)(row, r::optarg("_SHORTCUT_", GET_FIELD_SHORTCUT)));
        get_all.copy_optargs_from_term(*optargs_in);
        return r::expr(left).concat_map(
            r::fun(row,
                   r::branch(
                       r::null() == row,
                       r::array(),
                       std::move(get_all).default_(r::array()).map(
                           r::fun(v, r::object(r::optarg("left", row),
                                               r::optarg("right", v)))))));

    }
    virtual const char *name() const { return "inner_join"; }
};

class delete_term_t : public rewrite_term_t {
public:
    delete_term_t(compile_env_t *env, const protob_t<const Term> &term)
        : rewrite_term_t(env, term, argspec_t(1), rewrite) { }
private:

    static r::reql_t rewrite(protob_t<const Term> in,
                             UNUSED const pb_rcheckable_t *bt_src,
                             protob_t<const Term> optargs_in) {
        auto x = pb::dummy_var_t::IGNORED;

        r::reql_t term = r::expr(in->args(0)).replace(r::fun(x, r::null()));

        term.copy_optargs_from_term(*optargs_in);
        return term;
     }
     virtual const char *name() const { return "delete"; }
};

class update_term_t : public rewrite_term_t {
public:
    update_term_t(compile_env_t *env, const protob_t<const Term> &term)
        : rewrite_term_t(env, term, argspec_t(2), rewrite) { }
private:
    static r::reql_t rewrite(protob_t<const Term> in,
                             UNUSED const pb_rcheckable_t *bt_src,
                             protob_t<const Term> optargs_in) {
        auto old_row = pb::dummy_var_t::UPDATE_OLDROW;
        auto new_row = pb::dummy_var_t::UPDATE_NEWROW;

        r::reql_t term =
            r::expr(in->args(0)).replace(
                r::fun(old_row,
                    r::branch(
                        r::null() == old_row,
                        r::null(),
                        r::fun(new_row,
                            r::branch(
                                r::null() == new_row,
                                old_row,
                                r::expr(old_row).merge(new_row)))(
                                    r::expr(in->args(1))(old_row,
                                        r::optarg("_EVAL_FLAGS_", LITERAL_OK)),
                                    r::optarg("_EVAL_FLAGS_", LITERAL_OK)))));

        term.copy_optargs_from_term(*optargs_in);
        return term;
    }
    virtual const char *name() const { return "update"; }
};

class skip_term_t : public rewrite_term_t {
public:
    skip_term_t(compile_env_t *env, const protob_t<const Term> &term)
        : rewrite_term_t(env, term, argspec_t(2), rewrite) { }
private:
    static r::reql_t rewrite(protob_t<const Term> in,
                             UNUSED const pb_rcheckable_t *bt_src,
                             protob_t<const Term> optargs_in) {
        r::reql_t term =
            r::expr(in->args(0)).slice(in->args(1), -1,
                r::optarg("right_bound", "closed"));

        term.copy_optargs_from_term(*optargs_in);
        return term;
     }
     virtual const char *name() const { return "skip"; }
};

class difference_term_t : public rewrite_term_t {
public:
    difference_term_t(compile_env_t *env, const protob_t<const Term> &term)
        : rewrite_term_t(env, term, argspec_t(2), rewrite) { }
private:
    static r::reql_t rewrite(protob_t<const Term> in,
                             UNUSED const pb_rcheckable_t *bt_src,
                             protob_t<const Term> optargs_in) {
        auto row = pb::dummy_var_t::DIFFERENCE_ROW;

        r::reql_t term =
            r::expr(in->args(0)).filter(
                r::fun(row,
                    !r::expr(in->args(1)).contains(row)));

        term.copy_optargs_from_term(*optargs_in);
        return term;
    }

     virtual const char *name() const { return "difference"; }
};

class with_fields_term_t : public rewrite_term_t {
public:
    with_fields_term_t(compile_env_t *env, const protob_t<const Term> &term)
        : rewrite_term_t(env, term, argspec_t(1, -1), rewrite) { }
private:
    static r::reql_t rewrite(protob_t<const Term> in,
                             UNUSED const pb_rcheckable_t *bt_src,
                             protob_t<const Term> optargs_in) {

        r::reql_t has_fields = r::expr(in->args(0)).has_fields();
        has_fields.copy_args_from_term(*in, 1);
        has_fields.copy_optargs_from_term(*optargs_in);
        r::reql_t pluck = std::move(has_fields).pluck();
        pluck.copy_args_from_term(*in, 1);

        return pluck;
    }
     virtual const char *name() const { return "with_fields"; }
};

counted_t<term_t> make_skip_term(
    compile_env_t *env, const protob_t<const Term> &term) {
    return make_counted<skip_term_t>(env, term);
}
counted_t<term_t> make_inner_join_term(
    compile_env_t *env, const protob_t<const Term> &term) {
    return make_counted<inner_join_term_t>(env, term);
}
counted_t<term_t> make_outer_join_term(
    compile_env_t *env, const protob_t<const Term> &term) {
    return make_counted<outer_join_term_t>(env, term);
}
counted_t<term_t> make_eq_join_term(
    compile_env_t *env, const protob_t<const Term> &term) {
    return make_counted<eq_join_term_t>(env, term);
}
counted_t<term_t> make_update_term(
    compile_env_t *env, const protob_t<const Term> &term) {
    return make_counted<update_term_t>(env, term);
}
counted_t<term_t> make_delete_term(
    compile_env_t *env, const protob_t<const Term> &term) {
    return make_counted<delete_term_t>(env, term);
}
counted_t<term_t> make_difference_term(
    compile_env_t *env, const protob_t<const Term> &term) {
    return make_counted<difference_term_t>(env, term);
}
counted_t<term_t> make_with_fields_term(
    compile_env_t *env, const protob_t<const Term> &term) {
    return make_counted<with_fields_term_t>(env, term);
}

} // namespace ql
<commit_msg>Use actual name for `eq_join`<commit_after>// Copyright 2010-2013 RethinkDB, all rights reserved.
#include "rdb_protocol/terms/terms.hpp"

#include <string>

#include "rdb_protocol/op.hpp"
#include "rdb_protocol/error.hpp"
#include "rdb_protocol/pb_utils.hpp"
#include "rdb_protocol/minidriver.hpp"

namespace ql {

// This file implements terms that are rewritten into other terms.

class rewrite_term_t : public term_t {
public:
    rewrite_term_t(compile_env_t *env, protob_t<const Term> term, argspec_t argspec,
                   r::reql_t (*rewrite)(protob_t<const Term> in,
                                        const pb_rcheckable_t *bt_src,
                                        protob_t<const Term> optargs_in))
        : term_t(term), in(term), out(make_counted_term()) {
        int args_size = in->args_size();
        rcheck(argspec.contains(args_size),
               base_exc_t::GENERIC,
               strprintf("Expected %s but found %d.",
                         argspec.print().c_str(), args_size));
        out->Swap(&rewrite(in, this, in).get());
        propagate(out.get()); // duplicates `in` backtrace (see `pb_rcheckable_t`)
        real = compile_term(env, out);
    }

private:
    virtual void accumulate_captures(var_captures_t *captures) const {
        return real->accumulate_captures(captures);
    }
    virtual bool is_deterministic() const {
        return real->is_deterministic();
    }

    virtual counted_t<val_t> term_eval(scope_env_t *env, eval_flags_t) const {
        return real->eval(env);
    }

    protob_t<const Term> in;
    protob_t<Term> out;

    counted_t<const term_t> real;
};

class inner_join_term_t : public rewrite_term_t {
public:
    inner_join_term_t(compile_env_t *env, const protob_t<const Term> &term)
        : rewrite_term_t(env, term, argspec_t(3), rewrite) { }

    static r::reql_t rewrite(protob_t<const Term> in,
                             UNUSED const pb_rcheckable_t *bt_src,
                             protob_t<const Term> optargs_in) {
        const Term &left = in->args(0);
        const Term &right = in->args(1);
        const Term &func = in->args(2);
        auto n = pb::dummy_var_t::INNERJOIN_N;
        auto m = pb::dummy_var_t::INNERJOIN_M;

        r::reql_t term =
            r::expr(left).concat_map(
                r::fun(n,
                    r::expr(right).concat_map(
                        r::fun(m,
                            r::branch(
                                r::expr(func)(r::var(n), r::var(m)),
                                r::array(r::object(
                                        r::optarg("left", n), r::optarg("right", m))),
                                r::array())))));

        term.copy_optargs_from_term(*optargs_in);
        return term;
    }

    virtual const char *name() const { return "inner_join"; }
};

class outer_join_term_t : public rewrite_term_t {
public:
    outer_join_term_t(compile_env_t *env, const protob_t<const Term> &term) :
        rewrite_term_t(env, term, argspec_t(3), rewrite) { }

    static r::reql_t rewrite(protob_t<const Term> in,
                             UNUSED const pb_rcheckable_t *bt_src,
                             protob_t<const Term> optargs_in) {
        const Term &left = in->args(0);
        const Term &right = in->args(1);
        const Term &func = in->args(2);
        auto n = pb::dummy_var_t::OUTERJOIN_N;
        auto m = pb::dummy_var_t::OUTERJOIN_M;
        auto lst = pb::dummy_var_t::OUTERJOIN_LST;

        r::reql_t inner_concat_map =
            r::expr(right).concat_map(
                r::fun(m,
                    r::branch(
                        r::expr(func)(n, m),
                        r::array(r::object(r::optarg("left", n), r::optarg("right", m))),
                        r::array())));

        r::reql_t term =
            r::expr(left).concat_map(
                r::fun(n,
                    std::move(inner_concat_map).coerce_to("ARRAY").do_(lst,
                        r::branch(
                            r::expr(lst).count() > 0,
                            lst,
                            r::array(r::object(r::optarg("left", n)))))));

        term.copy_optargs_from_term(*optargs_in);
        return term;
    }

    virtual const char *name() const { return "outer_join"; }
};

class eq_join_term_t : public rewrite_term_t {
public:
    eq_join_term_t(compile_env_t *env, const protob_t<const Term> &term) :
        rewrite_term_t(env, term, argspec_t(3), rewrite) { }
private:

    static r::reql_t rewrite(protob_t<const Term> in,
                             UNUSED const pb_rcheckable_t *bt_src,
                             protob_t<const Term> optargs_in) {
        const Term &left = in->args(0);
        const Term &left_attr = in->args(1);
        const Term &right = in->args(2);

        auto row = pb::dummy_var_t::EQJOIN_ROW;
        auto v = pb::dummy_var_t::EQJOIN_V;

        r::reql_t get_all =
            r::expr(right).get_all(
                r::expr(left_attr)(row, r::optarg("_SHORTCUT_", GET_FIELD_SHORTCUT)));
        get_all.copy_optargs_from_term(*optargs_in);
        return r::expr(left).concat_map(
            r::fun(row,
                   r::branch(
                       r::null() == row,
                       r::array(),
                       std::move(get_all).default_(r::array()).map(
                           r::fun(v, r::object(r::optarg("left", row),
                                               r::optarg("right", v)))))));

    }
    virtual const char *name() const { return "eq_join"; }
};

class delete_term_t : public rewrite_term_t {
public:
    delete_term_t(compile_env_t *env, const protob_t<const Term> &term)
        : rewrite_term_t(env, term, argspec_t(1), rewrite) { }
private:

    static r::reql_t rewrite(protob_t<const Term> in,
                             UNUSED const pb_rcheckable_t *bt_src,
                             protob_t<const Term> optargs_in) {
        auto x = pb::dummy_var_t::IGNORED;

        r::reql_t term = r::expr(in->args(0)).replace(r::fun(x, r::null()));

        term.copy_optargs_from_term(*optargs_in);
        return term;
     }
     virtual const char *name() const { return "delete"; }
};

class update_term_t : public rewrite_term_t {
public:
    update_term_t(compile_env_t *env, const protob_t<const Term> &term)
        : rewrite_term_t(env, term, argspec_t(2), rewrite) { }
private:
    static r::reql_t rewrite(protob_t<const Term> in,
                             UNUSED const pb_rcheckable_t *bt_src,
                             protob_t<const Term> optargs_in) {
        auto old_row = pb::dummy_var_t::UPDATE_OLDROW;
        auto new_row = pb::dummy_var_t::UPDATE_NEWROW;

        r::reql_t term =
            r::expr(in->args(0)).replace(
                r::fun(old_row,
                    r::branch(
                        r::null() == old_row,
                        r::null(),
                        r::fun(new_row,
                            r::branch(
                                r::null() == new_row,
                                old_row,
                                r::expr(old_row).merge(new_row)))(
                                    r::expr(in->args(1))(old_row,
                                        r::optarg("_EVAL_FLAGS_", LITERAL_OK)),
                                    r::optarg("_EVAL_FLAGS_", LITERAL_OK)))));

        term.copy_optargs_from_term(*optargs_in);
        return term;
    }
    virtual const char *name() const { return "update"; }
};

class skip_term_t : public rewrite_term_t {
public:
    skip_term_t(compile_env_t *env, const protob_t<const Term> &term)
        : rewrite_term_t(env, term, argspec_t(2), rewrite) { }
private:
    static r::reql_t rewrite(protob_t<const Term> in,
                             UNUSED const pb_rcheckable_t *bt_src,
                             protob_t<const Term> optargs_in) {
        r::reql_t term =
            r::expr(in->args(0)).slice(in->args(1), -1,
                r::optarg("right_bound", "closed"));

        term.copy_optargs_from_term(*optargs_in);
        return term;
     }
     virtual const char *name() const { return "skip"; }
};

class difference_term_t : public rewrite_term_t {
public:
    difference_term_t(compile_env_t *env, const protob_t<const Term> &term)
        : rewrite_term_t(env, term, argspec_t(2), rewrite) { }
private:
    static r::reql_t rewrite(protob_t<const Term> in,
                             UNUSED const pb_rcheckable_t *bt_src,
                             protob_t<const Term> optargs_in) {
        auto row = pb::dummy_var_t::DIFFERENCE_ROW;

        r::reql_t term =
            r::expr(in->args(0)).filter(
                r::fun(row,
                    !r::expr(in->args(1)).contains(row)));

        term.copy_optargs_from_term(*optargs_in);
        return term;
    }

     virtual const char *name() const { return "difference"; }
};

class with_fields_term_t : public rewrite_term_t {
public:
    with_fields_term_t(compile_env_t *env, const protob_t<const Term> &term)
        : rewrite_term_t(env, term, argspec_t(1, -1), rewrite) { }
private:
    static r::reql_t rewrite(protob_t<const Term> in,
                             UNUSED const pb_rcheckable_t *bt_src,
                             protob_t<const Term> optargs_in) {

        r::reql_t has_fields = r::expr(in->args(0)).has_fields();
        has_fields.copy_args_from_term(*in, 1);
        has_fields.copy_optargs_from_term(*optargs_in);
        r::reql_t pluck = std::move(has_fields).pluck();
        pluck.copy_args_from_term(*in, 1);

        return pluck;
    }
     virtual const char *name() const { return "with_fields"; }
};

counted_t<term_t> make_skip_term(
    compile_env_t *env, const protob_t<const Term> &term) {
    return make_counted<skip_term_t>(env, term);
}
counted_t<term_t> make_inner_join_term(
    compile_env_t *env, const protob_t<const Term> &term) {
    return make_counted<inner_join_term_t>(env, term);
}
counted_t<term_t> make_outer_join_term(
    compile_env_t *env, const protob_t<const Term> &term) {
    return make_counted<outer_join_term_t>(env, term);
}
counted_t<term_t> make_eq_join_term(
    compile_env_t *env, const protob_t<const Term> &term) {
    return make_counted<eq_join_term_t>(env, term);
}
counted_t<term_t> make_update_term(
    compile_env_t *env, const protob_t<const Term> &term) {
    return make_counted<update_term_t>(env, term);
}
counted_t<term_t> make_delete_term(
    compile_env_t *env, const protob_t<const Term> &term) {
    return make_counted<delete_term_t>(env, term);
}
counted_t<term_t> make_difference_term(
    compile_env_t *env, const protob_t<const Term> &term) {
    return make_counted<difference_term_t>(env, term);
}
counted_t<term_t> make_with_fields_term(
    compile_env_t *env, const protob_t<const Term> &term) {
    return make_counted<with_fields_term_t>(env, term);
}

} // namespace ql
<|endoftext|>