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

#include "btree/keys.hpp"
#include "rdb_protocol/ql2.hpp"
#include "rdb_protocol/transform_visitors.hpp"

namespace query_language {

boost::shared_ptr<json_stream_t> json_stream_t::add_transformation(const rdb_protocol_details::transform_variant_t &t, ql::env_t *ql_env, const backtrace_t &backtrace) {
    rdb_protocol_details::transform_t transform;
    transform.push_back(rdb_protocol_details::transform_atom_t(t, backtrace));
    return boost::make_shared<transform_stream_t>(shared_from_this(), ql_env, transform);
}

result_t json_stream_t::apply_terminal(
    const rdb_protocol_details::terminal_variant_t &_t,
    ql::env_t *ql_env,
    const backtrace_t &backtrace) {
    rdb_protocol_details::terminal_variant_t t = _t;
    result_t res;

    terminal_initialize(ql_env, backtrace, &t, &res);

    boost::shared_ptr<scoped_cJSON_t> json;
    while ((json = next())) {
        terminal_apply(ql_env, backtrace, json, &t, &res);
    }
    return res;
}

in_memory_stream_t::in_memory_stream_t(json_array_iterator_t it) {
    while (cJSON *json = it.next()) {
        data.push_back(boost::shared_ptr<scoped_cJSON_t>(new scoped_cJSON_t(cJSON_DeepCopy(json))));
    }
}

in_memory_stream_t::in_memory_stream_t(boost::shared_ptr<json_stream_t> stream) {
    while (boost::shared_ptr<scoped_cJSON_t> json = stream->next()) {
        data.push_back(json);
    }
}

boost::shared_ptr<scoped_cJSON_t> in_memory_stream_t::next() {
    if (data.empty()) {
        return boost::shared_ptr<scoped_cJSON_t>();
    } else {
        boost::shared_ptr<scoped_cJSON_t> ret = data.front();
        data.pop_front();
        return ret;
    }
}

transform_stream_t::transform_stream_t(boost::shared_ptr<json_stream_t> _stream,
                                       ql::env_t *_ql_env,
                                       const rdb_protocol_details::transform_t &tr) :
    stream(_stream),
    ql_env(_ql_env),
    transform(tr) { }

boost::shared_ptr<scoped_cJSON_t> transform_stream_t::next() {
    while (data.empty()) {
        boost::shared_ptr<scoped_cJSON_t> input = stream->next();
        if (!input) {
            // End of stream reached.
            return boost::shared_ptr<scoped_cJSON_t>();
        }

        json_list_t accumulator;
        accumulator.push_back(input);

        //Apply transforms to the data
        typedef rdb_protocol_details::transform_t::iterator tit_t;
        for (tit_t it  = transform.begin();
                   it != transform.end();
                   ++it) {
            json_list_t tmp;
            for (json_list_t::iterator jt  = accumulator.begin();
                                       jt != accumulator.end();
                                       ++jt) {
                transform_apply(ql_env, it->backtrace, *jt, &it->variant, &tmp);
            }

            accumulator.swap(tmp);
        }

        data.swap(accumulator);
    }

    boost::shared_ptr<scoped_cJSON_t> datum = data.front();
    data.pop_front();
    return datum;
}

boost::shared_ptr<json_stream_t> transform_stream_t::add_transformation(const rdb_protocol_details::transform_variant_t &t, UNUSED ql::env_t *ql_env2, const backtrace_t &backtrace) {
    transform.push_back(rdb_protocol_details::transform_atom_t(t, backtrace));
    return shared_from_this();
}

batched_rget_stream_t::batched_rget_stream_t(
    const namespace_repo_t<rdb_protocol_t>::access_t &_ns_access,
    signal_t *_interruptor,
    counted_t<const ql::datum_t> left_bound,
    counted_t<const ql::datum_t> right_bound,
    const std::map<std::string, ql::wire_func_t> &_optargs,
    bool _use_outdated, sorting_t _sorting)
    : ns_access(_ns_access), interruptor(_interruptor),
      finished(false), started(false), optargs(_optargs), use_outdated(_use_outdated),
      range(key_range_t::closed,
            left_bound.has()
              ? store_key_t(left_bound->print_primary())
              : store_key_t::min(),
            key_range_t::closed,
            right_bound.has()
              ? store_key_t(right_bound->print_primary())
              : store_key_t::max()),
      table_scan_backtrace(),
      sorting(_sorting)
{ }

batched_rget_stream_t::batched_rget_stream_t(
    const namespace_repo_t<rdb_protocol_t>::access_t &_ns_access,
    signal_t *_interruptor, const std::string &_sindex_id,
    const std::map<std::string, ql::wire_func_t> &_optargs,
    bool _use_outdated,
    counted_t<const ql::datum_t> _sindex_start_value,
    counted_t<const ql::datum_t> _sindex_end_value,
    sorting_t _sorting)
    : ns_access(_ns_access),
      interruptor(_interruptor),
      sindex_id(_sindex_id),
      finished(false),
      started(false),
      optargs(_optargs),
      use_outdated(_use_outdated),
      sindex_start_value(_sindex_start_value),
      sindex_end_value(_sindex_end_value),
      range(rdb_protocol_t::sindex_key_range(
                _sindex_start_value != NULL
                  ? _sindex_start_value->truncated_secondary()
                  : store_key_t::min(),
                _sindex_end_value != NULL
                  ? _sindex_end_value->truncated_secondary()
                  : store_key_t::max())),
      table_scan_backtrace(),
      sorting(_sorting)
{ }

boost::optional<rget_item_t> batched_rget_stream_t::head() {
    started = true;
    if (data.empty()) {
        if (finished) {
            return boost::optional<rget_item_t>();
        }
        read_more();
        if (data.empty()) {
            finished = true;
            return boost::optional<rget_item_t>();
        }
    }

    return data.front();
}

void batched_rget_stream_t::pop() {
    guarantee(!data.empty());
    data.pop_front();
}

bool rget_item_sindex_key_less(const rget_item_t &left, const rget_item_t &right) {
    return json_cmp(left.sindex_key->get(), right.sindex_key->get()) < 0;
}

boost::shared_ptr<scoped_cJSON_t> batched_rget_stream_t::next() {
    if (!sorting_buffer.empty()) {
        boost::shared_ptr<scoped_cJSON_t> datum = sorting_buffer.front().data;
        sorting_buffer.pop_front();
        return datum;
    } else {
        for (;;) {
            boost::optional<rget_item_t> item = head();
            if (!item) {
                break;
            } else if (!ql::datum_t::key_is_truncated(item->key)) {
                if (sorting_buffer.empty()) {
                    pop();
                    return item->data;
                } else {
                    break;
                }
            } else {
                pop();
                sorting_buffer.push_back(*item);
            }
        }
    }

    /* The sorting buffer should now have unsorted data in it. Time to sort it. */
    if (sorting_buffer.empty()) {
        /* Nothing in the sorting buffer, this means we don't have any data to
         * return so we return nothing. */
        return boost::shared_ptr<scoped_cJSON_t>();
    } else {
        /* There's data in the sorting_buffer time to sort it. */
        debugf("Doing some sorting of %zd values.\n", sorting_buffer.size());
        std::sort(sorting_buffer.begin(), sorting_buffer.end(),
                  &rget_item_sindex_key_less);
        boost::shared_ptr<scoped_cJSON_t> datum = sorting_buffer.front().data;
        sorting_buffer.pop_front();
        return datum;
    }
}

boost::shared_ptr<json_stream_t> batched_rget_stream_t::add_transformation(const rdb_protocol_details::transform_variant_t &t, UNUSED ql::env_t *ql_env2, const backtrace_t &per_op_backtrace) {
    guarantee(!started);
    transform.push_back(rdb_protocol_details::transform_atom_t(t, per_op_backtrace));
    return shared_from_this();
}

result_t batched_rget_stream_t::apply_terminal(
    const rdb_protocol_details::terminal_variant_t &t,
    UNUSED ql::env_t *ql_env,
    const backtrace_t &per_op_backtrace) {
    rdb_protocol_t::rget_read_t rget_read = get_rget();
    rget_read.terminal = rdb_protocol_details::terminal_t(t, per_op_backtrace);
    rdb_protocol_t::read_t read(rget_read);
    try {
        rdb_protocol_t::read_response_t res;
        if (use_outdated) {
            ns_access.get_namespace_if()->read_outdated(read, &res, interruptor);
        } else {
            ns_access.get_namespace_if()->read(read, &res, order_token_t::ignore, interruptor);
        }
        rdb_protocol_t::rget_read_response_t *p_res = boost::get<rdb_protocol_t::rget_read_response_t>(&res.response);
        guarantee(p_res);

        /* Re throw an exception if we got one. */
        if (runtime_exc_t *e = boost::get<runtime_exc_t>(&p_res->result)) {
            throw *e;
        } else if (ql::exc_t *e2 = boost::get<ql::exc_t>(&p_res->result)) {
            throw *e2;
        } else if (ql::datum_exc_t *e3 = boost::get<ql::datum_exc_t>(&p_res->result)) {
            throw *e3;
        }

        return p_res->result;
    } catch (const cannot_perform_query_exc_t &e) {
        if (table_scan_backtrace) {
            throw runtime_exc_t("cannot perform read: " + std::string(e.what()), *table_scan_backtrace);
        } else {
            // No backtrace for these.
            rfail_toplevel(ql::base_exc_t::GENERIC,
                           "cannot perform read: %s", e.what());
        }
    }
}

rdb_protocol_t::rget_read_t batched_rget_stream_t::get_rget() {
    if (!sindex_id) {
        return rdb_protocol_t::rget_read_t(rdb_protocol_t::region_t(range),
                                           transform,
                                           optargs,
                                           sorting);
    } else {
        return rdb_protocol_t::rget_read_t(rdb_protocol_t::region_t(range),
                                           *sindex_id,
                                           sindex_start_value,
                                           sindex_end_value,
                                           transform,
                                           optargs,
                                           sorting);
    }
}

void batched_rget_stream_t::read_more() {
    rdb_protocol_t::read_t read(get_rget());
    try {
        guarantee(ns_access.get_namespace_if());
        rdb_protocol_t::read_response_t res;
        if (use_outdated) {
            ns_access.get_namespace_if()->read_outdated(read, &res, interruptor);
        } else {
            ns_access.get_namespace_if()->read(read, &res, order_token_t::ignore, interruptor);
        }
        rdb_protocol_t::rget_read_response_t *p_res = boost::get<rdb_protocol_t::rget_read_response_t>(&res.response);
        guarantee(p_res);

        /* Re throw an exception if we got one. */
        if (auto e = boost::get<runtime_exc_t>(&p_res->result)) {
            throw *e;
        } else if (auto e2 = boost::get<ql::exc_t>(&p_res->result)) {
            throw *e2;
        } else if (auto e3 = boost::get<ql::datum_exc_t>(&p_res->result)) {
            throw *e3;
        }

        // todo: just do a straight copy?
        typedef rdb_protocol_t::rget_read_response_t::stream_t stream_t;
        stream_t *stream = boost::get<stream_t>(&p_res->result);
        guarantee(stream);

        for (stream_t::iterator i = stream->begin(); i != stream->end(); ++i) {
            guarantee(i->data);
            data.push_back(*i);
        }

        if (forward(sorting)) {
            range.left = p_res->last_considered_key;
        } else {
            range.right = key_range_t::right_bound_t(p_res->last_considered_key);
        }

        if (forward(sorting) &&
            (!range.left.increment() ||
            (!range.right.unbounded && (range.right.key < range.left)))) {
            finished = true;
        } else if (backward(sorting)) {
            guarantee(!range.right.unbounded);
            if (!range.right.key.decrement() ||
                range.right.key < range.left) {
                finished = true;
            }
        }
    } catch (const cannot_perform_query_exc_t &e) {
        if (table_scan_backtrace) {
            throw runtime_exc_t("cannot perform read: " + std::string(e.what()), *table_scan_backtrace);
        } else {
            // No backtrace.
            rfail_toplevel(ql::base_exc_t::GENERIC,
                           "cannot perform read: %s", e.what());
        }
    }
}

} //namespace query_language
<commit_msg>Remove an unneeded debugf.<commit_after>// Copyright 2010-2012 RethinkDB, all rights reserved.
#include "rdb_protocol/stream.hpp"

#include "btree/keys.hpp"
#include "rdb_protocol/ql2.hpp"
#include "rdb_protocol/transform_visitors.hpp"

namespace query_language {

boost::shared_ptr<json_stream_t> json_stream_t::add_transformation(const rdb_protocol_details::transform_variant_t &t, ql::env_t *ql_env, const backtrace_t &backtrace) {
    rdb_protocol_details::transform_t transform;
    transform.push_back(rdb_protocol_details::transform_atom_t(t, backtrace));
    return boost::make_shared<transform_stream_t>(shared_from_this(), ql_env, transform);
}

result_t json_stream_t::apply_terminal(
    const rdb_protocol_details::terminal_variant_t &_t,
    ql::env_t *ql_env,
    const backtrace_t &backtrace) {
    rdb_protocol_details::terminal_variant_t t = _t;
    result_t res;

    terminal_initialize(ql_env, backtrace, &t, &res);

    boost::shared_ptr<scoped_cJSON_t> json;
    while ((json = next())) {
        terminal_apply(ql_env, backtrace, json, &t, &res);
    }
    return res;
}

in_memory_stream_t::in_memory_stream_t(json_array_iterator_t it) {
    while (cJSON *json = it.next()) {
        data.push_back(boost::shared_ptr<scoped_cJSON_t>(new scoped_cJSON_t(cJSON_DeepCopy(json))));
    }
}

in_memory_stream_t::in_memory_stream_t(boost::shared_ptr<json_stream_t> stream) {
    while (boost::shared_ptr<scoped_cJSON_t> json = stream->next()) {
        data.push_back(json);
    }
}

boost::shared_ptr<scoped_cJSON_t> in_memory_stream_t::next() {
    if (data.empty()) {
        return boost::shared_ptr<scoped_cJSON_t>();
    } else {
        boost::shared_ptr<scoped_cJSON_t> ret = data.front();
        data.pop_front();
        return ret;
    }
}

transform_stream_t::transform_stream_t(boost::shared_ptr<json_stream_t> _stream,
                                       ql::env_t *_ql_env,
                                       const rdb_protocol_details::transform_t &tr) :
    stream(_stream),
    ql_env(_ql_env),
    transform(tr) { }

boost::shared_ptr<scoped_cJSON_t> transform_stream_t::next() {
    while (data.empty()) {
        boost::shared_ptr<scoped_cJSON_t> input = stream->next();
        if (!input) {
            // End of stream reached.
            return boost::shared_ptr<scoped_cJSON_t>();
        }

        json_list_t accumulator;
        accumulator.push_back(input);

        //Apply transforms to the data
        typedef rdb_protocol_details::transform_t::iterator tit_t;
        for (tit_t it  = transform.begin();
                   it != transform.end();
                   ++it) {
            json_list_t tmp;
            for (json_list_t::iterator jt  = accumulator.begin();
                                       jt != accumulator.end();
                                       ++jt) {
                transform_apply(ql_env, it->backtrace, *jt, &it->variant, &tmp);
            }

            accumulator.swap(tmp);
        }

        data.swap(accumulator);
    }

    boost::shared_ptr<scoped_cJSON_t> datum = data.front();
    data.pop_front();
    return datum;
}

boost::shared_ptr<json_stream_t> transform_stream_t::add_transformation(const rdb_protocol_details::transform_variant_t &t, UNUSED ql::env_t *ql_env2, const backtrace_t &backtrace) {
    transform.push_back(rdb_protocol_details::transform_atom_t(t, backtrace));
    return shared_from_this();
}

batched_rget_stream_t::batched_rget_stream_t(
    const namespace_repo_t<rdb_protocol_t>::access_t &_ns_access,
    signal_t *_interruptor,
    counted_t<const ql::datum_t> left_bound,
    counted_t<const ql::datum_t> right_bound,
    const std::map<std::string, ql::wire_func_t> &_optargs,
    bool _use_outdated, sorting_t _sorting)
    : ns_access(_ns_access), interruptor(_interruptor),
      finished(false), started(false), optargs(_optargs), use_outdated(_use_outdated),
      range(key_range_t::closed,
            left_bound.has()
              ? store_key_t(left_bound->print_primary())
              : store_key_t::min(),
            key_range_t::closed,
            right_bound.has()
              ? store_key_t(right_bound->print_primary())
              : store_key_t::max()),
      table_scan_backtrace(),
      sorting(_sorting)
{ }

batched_rget_stream_t::batched_rget_stream_t(
    const namespace_repo_t<rdb_protocol_t>::access_t &_ns_access,
    signal_t *_interruptor, const std::string &_sindex_id,
    const std::map<std::string, ql::wire_func_t> &_optargs,
    bool _use_outdated,
    counted_t<const ql::datum_t> _sindex_start_value,
    counted_t<const ql::datum_t> _sindex_end_value,
    sorting_t _sorting)
    : ns_access(_ns_access),
      interruptor(_interruptor),
      sindex_id(_sindex_id),
      finished(false),
      started(false),
      optargs(_optargs),
      use_outdated(_use_outdated),
      sindex_start_value(_sindex_start_value),
      sindex_end_value(_sindex_end_value),
      range(rdb_protocol_t::sindex_key_range(
                _sindex_start_value != NULL
                  ? _sindex_start_value->truncated_secondary()
                  : store_key_t::min(),
                _sindex_end_value != NULL
                  ? _sindex_end_value->truncated_secondary()
                  : store_key_t::max())),
      table_scan_backtrace(),
      sorting(_sorting)
{ }

boost::optional<rget_item_t> batched_rget_stream_t::head() {
    started = true;
    if (data.empty()) {
        if (finished) {
            return boost::optional<rget_item_t>();
        }
        read_more();
        if (data.empty()) {
            finished = true;
            return boost::optional<rget_item_t>();
        }
    }

    return data.front();
}

void batched_rget_stream_t::pop() {
    guarantee(!data.empty());
    data.pop_front();
}

bool rget_item_sindex_key_less(const rget_item_t &left, const rget_item_t &right) {
    return json_cmp(left.sindex_key->get(), right.sindex_key->get()) < 0;
}

boost::shared_ptr<scoped_cJSON_t> batched_rget_stream_t::next() {
    if (!sorting_buffer.empty()) {
        boost::shared_ptr<scoped_cJSON_t> datum = sorting_buffer.front().data;
        sorting_buffer.pop_front();
        return datum;
    } else {
        for (;;) {
            boost::optional<rget_item_t> item = head();
            if (!item) {
                break;
            } else if (!ql::datum_t::key_is_truncated(item->key)) {
                if (sorting_buffer.empty()) {
                    pop();
                    return item->data;
                } else {
                    break;
                }
            } else {
                pop();
                sorting_buffer.push_back(*item);
            }
        }
    }

    /* The sorting buffer should now have unsorted data in it. Time to sort it. */
    if (sorting_buffer.empty()) {
        /* Nothing in the sorting buffer, this means we don't have any data to
         * return so we return nothing. */
        return boost::shared_ptr<scoped_cJSON_t>();
    } else {
        /* There's data in the sorting_buffer time to sort it. */
        std::sort(sorting_buffer.begin(), sorting_buffer.end(),
                  &rget_item_sindex_key_less);
        boost::shared_ptr<scoped_cJSON_t> datum = sorting_buffer.front().data;
        sorting_buffer.pop_front();
        return datum;
    }
}

boost::shared_ptr<json_stream_t> batched_rget_stream_t::add_transformation(const rdb_protocol_details::transform_variant_t &t, UNUSED ql::env_t *ql_env2, const backtrace_t &per_op_backtrace) {
    guarantee(!started);
    transform.push_back(rdb_protocol_details::transform_atom_t(t, per_op_backtrace));
    return shared_from_this();
}

result_t batched_rget_stream_t::apply_terminal(
    const rdb_protocol_details::terminal_variant_t &t,
    UNUSED ql::env_t *ql_env,
    const backtrace_t &per_op_backtrace) {
    rdb_protocol_t::rget_read_t rget_read = get_rget();
    rget_read.terminal = rdb_protocol_details::terminal_t(t, per_op_backtrace);
    rdb_protocol_t::read_t read(rget_read);
    try {
        rdb_protocol_t::read_response_t res;
        if (use_outdated) {
            ns_access.get_namespace_if()->read_outdated(read, &res, interruptor);
        } else {
            ns_access.get_namespace_if()->read(read, &res, order_token_t::ignore, interruptor);
        }
        rdb_protocol_t::rget_read_response_t *p_res = boost::get<rdb_protocol_t::rget_read_response_t>(&res.response);
        guarantee(p_res);

        /* Re throw an exception if we got one. */
        if (runtime_exc_t *e = boost::get<runtime_exc_t>(&p_res->result)) {
            throw *e;
        } else if (ql::exc_t *e2 = boost::get<ql::exc_t>(&p_res->result)) {
            throw *e2;
        } else if (ql::datum_exc_t *e3 = boost::get<ql::datum_exc_t>(&p_res->result)) {
            throw *e3;
        }

        return p_res->result;
    } catch (const cannot_perform_query_exc_t &e) {
        if (table_scan_backtrace) {
            throw runtime_exc_t("cannot perform read: " + std::string(e.what()), *table_scan_backtrace);
        } else {
            // No backtrace for these.
            rfail_toplevel(ql::base_exc_t::GENERIC,
                           "cannot perform read: %s", e.what());
        }
    }
}

rdb_protocol_t::rget_read_t batched_rget_stream_t::get_rget() {
    if (!sindex_id) {
        return rdb_protocol_t::rget_read_t(rdb_protocol_t::region_t(range),
                                           transform,
                                           optargs,
                                           sorting);
    } else {
        return rdb_protocol_t::rget_read_t(rdb_protocol_t::region_t(range),
                                           *sindex_id,
                                           sindex_start_value,
                                           sindex_end_value,
                                           transform,
                                           optargs,
                                           sorting);
    }
}

void batched_rget_stream_t::read_more() {
    rdb_protocol_t::read_t read(get_rget());
    try {
        guarantee(ns_access.get_namespace_if());
        rdb_protocol_t::read_response_t res;
        if (use_outdated) {
            ns_access.get_namespace_if()->read_outdated(read, &res, interruptor);
        } else {
            ns_access.get_namespace_if()->read(read, &res, order_token_t::ignore, interruptor);
        }
        rdb_protocol_t::rget_read_response_t *p_res = boost::get<rdb_protocol_t::rget_read_response_t>(&res.response);
        guarantee(p_res);

        /* Re throw an exception if we got one. */
        if (auto e = boost::get<runtime_exc_t>(&p_res->result)) {
            throw *e;
        } else if (auto e2 = boost::get<ql::exc_t>(&p_res->result)) {
            throw *e2;
        } else if (auto e3 = boost::get<ql::datum_exc_t>(&p_res->result)) {
            throw *e3;
        }

        // todo: just do a straight copy?
        typedef rdb_protocol_t::rget_read_response_t::stream_t stream_t;
        stream_t *stream = boost::get<stream_t>(&p_res->result);
        guarantee(stream);

        for (stream_t::iterator i = stream->begin(); i != stream->end(); ++i) {
            guarantee(i->data);
            data.push_back(*i);
        }

        if (forward(sorting)) {
            range.left = p_res->last_considered_key;
        } else {
            range.right = key_range_t::right_bound_t(p_res->last_considered_key);
        }

        if (forward(sorting) &&
            (!range.left.increment() ||
            (!range.right.unbounded && (range.right.key < range.left)))) {
            finished = true;
        } else if (backward(sorting)) {
            guarantee(!range.right.unbounded);
            if (!range.right.key.decrement() ||
                range.right.key < range.left) {
                finished = true;
            }
        }
    } catch (const cannot_perform_query_exc_t &e) {
        if (table_scan_backtrace) {
            throw runtime_exc_t("cannot perform read: " + std::string(e.what()), *table_scan_backtrace);
        } else {
            // No backtrace.
            rfail_toplevel(ql::base_exc_t::GENERIC,
                           "cannot perform read: %s", e.what());
        }
    }
}

} //namespace query_language
<|endoftext|>


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

#include "paddle/fluid/operators/detail/safe_ref.h"
#include "paddle/fluid/operators/reader/reader_op_registry.h"

namespace paddle {
namespace operators {
namespace reader {

class MultiPassReader : public framework::DecoratedReader {
 public:
  MultiPassReader(ReaderBase* reader, int pass_num)
      : DecoratedReader(reader), pass_num_(pass_num), pass_count_(0) {}

  void ReadNext(std::vector<framework::LoDTensor>* out) override {
    if (!HasNext()) {
      PADDLE_THROW("There is no next data!");
    }
    reader_->ReadNext(out);
  }

  bool HasNext() const override {
    if (reader_->HasNext()) {
      return true;
    } else {
      ++pass_count_;
      if (pass_count_ >= pass_num_) {
        return false;
      } else {
        reader_->ReInit();
        return true;
      }
    }
  }

  void ReInit() override {
    pass_count_ = 0;
    reader_->ReInit();
  }

 private:
  int pass_num_;
  mutable int pass_count_;
};

class CreateMultiPassReaderOp : public framework::OperatorBase {
 public:
  using framework::OperatorBase::OperatorBase;

 private:
  void RunImpl(const framework::Scope& scope,
               const platform::Place& dev_place) const override {
    const auto& underlying_reader = scope.FindVar(Input("UnderlyingReader"))
                                        ->Get<framework::ReaderHolder>();
    auto& out = detail::Ref(scope.FindVar(Output("Out")));
    int pass_num = Attr<int>("pass_num");
    out.GetMutable<framework::ReaderHolder>()->Reset(
        new MultiPassReader(underlying_reader.Get(), pass_num));
  }
};

class CreateMultiPassReaderOpMaker : public DecoratedReaderMakerBase {
 public:
  CreateMultiPassReaderOpMaker(OpProto* op_proto, OpAttrChecker* op_checker)
      : DecoratedReaderMakerBase(op_proto, op_checker) {
    AddAttr<int>("pass_num", "The number of pass to run.").GreaterThan(0);
    AddComment(R"DOC(
      CreateMultiPassReader Operator

      This operator creates a multi-pass reader. A multi-pass reader
      is used to yield data for several pass training continuously.
      It takes the the number of pass to run as one of its attributes
      ('pass_num'), and maintains a pass counter to record how many
      passes it has completed. When the underlying reader reach the EOF,
      the multi-pass reader checks whether it has completed training
      of the given number of pass. If not, the underlying reader will
      be re-initialized and starts a new pass automatically.
    )DOC");
  }
};

}  // namespace reader
}  // namespace operators
}  // namespace paddle

namespace ops = paddle::operators::reader;
REGISTER_DECORATED_READER_OPERATOR(create_multi_pass_reader,
                                   ops::CreateMultiPassReaderOp,
                                   ops::CreateMultiPassReaderOpMaker);
<commit_msg>refine MultiPassReader's doc string<commit_after>//   Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "paddle/fluid/operators/detail/safe_ref.h"
#include "paddle/fluid/operators/reader/reader_op_registry.h"

namespace paddle {
namespace operators {
namespace reader {

class MultiPassReader : public framework::DecoratedReader {
 public:
  MultiPassReader(ReaderBase* reader, int pass_num)
      : DecoratedReader(reader), pass_num_(pass_num), pass_count_(0) {}

  void ReadNext(std::vector<framework::LoDTensor>* out) override {
    if (!HasNext()) {
      PADDLE_THROW("There is no next data!");
    }
    reader_->ReadNext(out);
  }

  bool HasNext() const override {
    if (reader_->HasNext()) {
      return true;
    } else {
      ++pass_count_;
      if (pass_count_ >= pass_num_) {
        return false;
      } else {
        reader_->ReInit();
        return true;
      }
    }
  }

  void ReInit() override {
    pass_count_ = 0;
    reader_->ReInit();
  }

 private:
  int pass_num_;
  mutable int pass_count_;
};

class CreateMultiPassReaderOp : public framework::OperatorBase {
 public:
  using framework::OperatorBase::OperatorBase;

 private:
  void RunImpl(const framework::Scope& scope,
               const platform::Place& dev_place) const override {
    const auto& underlying_reader = scope.FindVar(Input("UnderlyingReader"))
                                        ->Get<framework::ReaderHolder>();
    auto& out = detail::Ref(scope.FindVar(Output("Out")));
    int pass_num = Attr<int>("pass_num");
    out.GetMutable<framework::ReaderHolder>()->Reset(
        new MultiPassReader(underlying_reader.Get(), pass_num));
  }
};

class CreateMultiPassReaderOpMaker : public DecoratedReaderMakerBase {
 public:
  CreateMultiPassReaderOpMaker(OpProto* op_proto, OpAttrChecker* op_checker)
      : DecoratedReaderMakerBase(op_proto, op_checker) {
    AddAttr<int>("pass_num", "The number of pass to run.").GreaterThan(0);
    AddComment(R"DOC(
      CreateMultiPassReader Operator

      This operator creates a multi-pass reader. A multi-pass reader
      is used to yield data for several pass training continuously.
      It takes the number of passes to run as one of its attributes
      ('pass_num'), and maintains a pass counter to record how many
      passes it has completed. When the underlying reader reaches the
      EOF, the multi-pass reader checks whether it has completed training
      of the given number of pass. If not, the underlying reader will
      be re-initialized and starts a new pass automatically.
    )DOC");
  }
};

}  // namespace reader
}  // namespace operators
}  // namespace paddle

namespace ops = paddle::operators::reader;
REGISTER_DECORATED_READER_OPERATOR(create_multi_pass_reader,
                                   ops::CreateMultiPassReaderOp,
                                   ops::CreateMultiPassReaderOpMaker);
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include "alloc_impl.hxx"
#include "rtl/alloc.h"
#include <sal/macros.h>

#include <cassert>
#include <string.h>
#include <stdio.h>

#include "internal/rtllifecycle.h"

AllocMode alloc_mode = AMode_UNSET;

#if !defined(FORCE_SYSALLOC)
static void determine_alloc_mode()
{
    assert(alloc_mode == AMode_UNSET);
    alloc_mode = (getenv("G_SLICE") == NULL ? AMode_CUSTOM : AMode_SYSTEM);
}

/* ================================================================= *
 *
 * custom allocator includes.
 *
 * ================================================================= */

#include "sal/macros.h"

/* ================================================================= *
 *
 * custom allocator internals.
 *
 * ================================================================= */

static const sal_Size g_alloc_sizes[] =
{
    /* powers of 2**(1/4) */
    4 *    4,           6 *    4,
    4 *    8, 5 *    8, 6 *    8, 7 *    8,
    4 *   16, 5 *   16, 6 *   16, 7 *   16,
    4 *   32, 5 *   32, 6 *   32, 7 *   32,
    4 *   64, 5 *   64, 6 *   64, 7 *   64,
    4 *  128, 5 *  128, 6 *  128, 7 *  128,
    4 *  256, 5 *  256, 6 *  256, 7 *  256,
    4 *  512, 5 *  512, 6 *  512, 7 *  512,
    4 * 1024, 5 * 1024, 6 * 1024, 7 * 1024,
    4 * 2048, 5 * 2048, 6 * 2048, 7 * 2048,
    4 * 4096
};

#define RTL_MEMORY_CACHED_LIMIT 4 * 4096
#define RTL_MEMORY_CACHED_SIZES (SAL_N_ELEMENTS(g_alloc_sizes))

static rtl_cache_type * g_alloc_caches[RTL_MEMORY_CACHED_SIZES] =
{
    0,
};

#define RTL_MEMALIGN       8
#define RTL_MEMALIGN_SHIFT 3

static rtl_cache_type * g_alloc_table[RTL_MEMORY_CACHED_LIMIT >> RTL_MEMALIGN_SHIFT] =
{
    0,
};

static rtl_arena_type * gp_alloc_arena = 0;

/* ================================================================= *
 *
 * custom allocator implemenation.
 *
 * ================================================================= */

void *
SAL_CALL rtl_allocateMemory_CUSTOM (sal_Size n) SAL_THROW_EXTERN_C()
{
    void * p = 0;
    if (n > 0)
    {
        char *     addr;
        sal_Size   size = RTL_MEMORY_ALIGN(n + RTL_MEMALIGN, RTL_MEMALIGN);

        assert(RTL_MEMALIGN >= sizeof(sal_Size));
        if (n >= SAL_MAX_SIZE - (RTL_MEMALIGN + RTL_MEMALIGN - 1))
        {
            /* requested size too large for roundup alignment */
            return 0;
        }

try_alloc:
        if (size <= RTL_MEMORY_CACHED_LIMIT)
            addr = (char*)rtl_cache_alloc(g_alloc_table[(size - 1) >> RTL_MEMALIGN_SHIFT]);
        else
            addr = (char*)rtl_arena_alloc (gp_alloc_arena, &size);

        if (addr != 0)
        {
            ((sal_Size*)(addr))[0] = size;
            p = addr + RTL_MEMALIGN;
        }
        else if (gp_alloc_arena == 0)
        {
            ensureMemorySingleton();
            if (gp_alloc_arena)
            {
                /* try again */
                goto try_alloc;
            }
        }
    }
    return (p);
}

/* ================================================================= */

void SAL_CALL rtl_freeMemory_CUSTOM (void * p) SAL_THROW_EXTERN_C()
{
    if (p != 0)
    {
        char *   addr = (char*)(p) - RTL_MEMALIGN;
        sal_Size size = ((sal_Size*)(addr))[0];

        if (size <= RTL_MEMORY_CACHED_LIMIT)
            rtl_cache_free(g_alloc_table[(size - 1) >> RTL_MEMALIGN_SHIFT], addr);
        else
            rtl_arena_free (gp_alloc_arena, addr, size);
    }
}

/* ================================================================= */

void * SAL_CALL rtl_reallocateMemory_CUSTOM (void * p, sal_Size n) SAL_THROW_EXTERN_C()
{
    if (n > 0)
    {
        if (p != 0)
        {
            void *   p_old = p;
            sal_Size n_old = ((sal_Size*)( (char*)(p) - RTL_MEMALIGN  ))[0] - RTL_MEMALIGN;

            p = rtl_allocateMemory (n);
            if (p != 0)
            {
                memcpy (p, p_old, SAL_MIN(n, n_old));
                rtl_freeMemory (p_old);
            }
        }
        else
        {
            p = rtl_allocateMemory (n);
        }
    }
    else if (p != 0)
    {
        rtl_freeMemory (p), p = 0;
    }
    return (p);
}

#endif

/* ================================================================= *
 *
 * custom allocator initialization / finalization.
 *
 * ================================================================= */

void rtl_memory_init()
{
#if !defined(FORCE_SYSALLOC)
    {
        /* global memory arena */
        assert(gp_alloc_arena == 0);

        gp_alloc_arena = rtl_arena_create (
            "rtl_alloc_arena",
            2048,     /* quantum */
            0,        /* w/o quantum caching */
            0,        /* default source */
            rtl_arena_alloc,
            rtl_arena_free,
            0         /* flags */
        );
        assert(gp_alloc_arena != 0);
    }
    {
        sal_Size size;
        int i, n = RTL_MEMORY_CACHED_SIZES;

        for (i = 0; i < n; i++)
        {
            char name[RTL_CACHE_NAME_LENGTH + 1];
            (void) snprintf (name, sizeof(name), "rtl_alloc_%lu", g_alloc_sizes[i]);
            g_alloc_caches[i] = rtl_cache_create (name, g_alloc_sizes[i], 0, NULL, NULL, NULL, NULL, NULL, 0);
        }

        size = RTL_MEMALIGN;
        for (i = 0; i < n; i++)
        {
            while (size <= g_alloc_sizes[i])
            {
                g_alloc_table[(size - 1) >> RTL_MEMALIGN_SHIFT] = g_alloc_caches[i];
                size += RTL_MEMALIGN;
            }
        }
    }
#endif
    // SAL_INFO("sal", "rtl_memory_init completed");
}

/* ================================================================= */

void rtl_memory_fini()
{
#if !defined(FORCE_SYSALLOC)
    int i, n;

    /* clear g_alloc_table */
    memset (g_alloc_table, 0, sizeof(g_alloc_table));

    /* cleanup g_alloc_caches */
    for (i = 0, n = RTL_MEMORY_CACHED_SIZES; i < n; i++)
    {
        if (g_alloc_caches[i] != 0)
        {
            rtl_cache_destroy (g_alloc_caches[i]);
            g_alloc_caches[i] = 0;
        }
    }

    /* cleanup gp_alloc_arena */
    if (gp_alloc_arena != 0)
    {
        rtl_arena_destroy (gp_alloc_arena);
        gp_alloc_arena = 0;
    }
#endif
    // SAL_INFO("sal", "rtl_memory_fini completed");
}

/* ================================================================= *
 *
 * system allocator implemenation.
 *
 * ================================================================= */

void * SAL_CALL rtl_allocateMemory_SYSTEM (sal_Size n)
{
    return malloc (n);
}

/* ================================================================= */

void SAL_CALL rtl_freeMemory_SYSTEM (void * p)
{
    free (p);
}

/* ================================================================= */

void * SAL_CALL rtl_reallocateMemory_SYSTEM (void * p, sal_Size n)
{
    return realloc (p, n);
}

/* ================================================================= */

void* SAL_CALL rtl_allocateMemory (sal_Size n) SAL_THROW_EXTERN_C()
{
#if !defined(FORCE_SYSALLOC)
    while (1)
    {
        if (alloc_mode == AMode_CUSTOM)
        {
            return rtl_allocateMemory_CUSTOM(n);
        }
        if (alloc_mode == AMode_SYSTEM)
        {
            return rtl_allocateMemory_SYSTEM(n);
        }
        determine_alloc_mode();
    }
#else
    return rtl_allocateMemory_SYSTEM(n);
#endif
}

void* SAL_CALL rtl_reallocateMemory (void * p, sal_Size n) SAL_THROW_EXTERN_C()
{
#if !defined(FORCE_SYSALLOC)
    while (1)
    {
        if (alloc_mode == AMode_CUSTOM)
        {
            return rtl_reallocateMemory_CUSTOM(p,n);
        }
        if (alloc_mode == AMode_SYSTEM)
        {
            return rtl_reallocateMemory_SYSTEM(p,n);
        }
        determine_alloc_mode();
    }
#else
    return rtl_reallocateMemory_SYSTEM(p,n);
#endif
}

void SAL_CALL rtl_freeMemory (void * p) SAL_THROW_EXTERN_C()
{
#if !defined(FORCE_SYSALLOC)
    while (1)
    {
        if (alloc_mode == AMode_CUSTOM)
        {
            rtl_freeMemory_CUSTOM(p);
            return;
        }
        if (alloc_mode == AMode_SYSTEM)
        {
            rtl_freeMemory_SYSTEM(p);
            return;
        }
        determine_alloc_mode();
    }
#else
    rtl_freeMemory_SYSTEM(p);
#endif
}

/* ================================================================= *
 *
 * rtl_(allocate|free)ZeroMemory() implemenation.
 *
 * ================================================================= */

void * SAL_CALL rtl_allocateZeroMemory (sal_Size n) SAL_THROW_EXTERN_C()
{
    void * p = rtl_allocateMemory (n);
    if (p != 0)
        memset (p, 0, n);
    return (p);
}

/* ================================================================= */

void SAL_CALL rtl_freeZeroMemory (void * p, sal_Size n) SAL_THROW_EXTERN_C()
{
    if (p != 0)
    {
        memset (p, 0, n);
        rtl_freeMemory (p);
    }
}

/* ================================================================= */

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>warn about massive allocs<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include "alloc_impl.hxx"
#include "rtl/alloc.h"
#include <sal/log.hxx>
#include <sal/macros.h>

#include <cassert>
#include <string.h>
#include <stdio.h>

#include "internal/rtllifecycle.h"

AllocMode alloc_mode = AMode_UNSET;

#if !defined(FORCE_SYSALLOC)
static void determine_alloc_mode()
{
    assert(alloc_mode == AMode_UNSET);
    alloc_mode = (getenv("G_SLICE") == NULL ? AMode_CUSTOM : AMode_SYSTEM);
}

/* ================================================================= *
 *
 * custom allocator includes.
 *
 * ================================================================= */

#include "sal/macros.h"

/* ================================================================= *
 *
 * custom allocator internals.
 *
 * ================================================================= */

static const sal_Size g_alloc_sizes[] =
{
    /* powers of 2**(1/4) */
    4 *    4,           6 *    4,
    4 *    8, 5 *    8, 6 *    8, 7 *    8,
    4 *   16, 5 *   16, 6 *   16, 7 *   16,
    4 *   32, 5 *   32, 6 *   32, 7 *   32,
    4 *   64, 5 *   64, 6 *   64, 7 *   64,
    4 *  128, 5 *  128, 6 *  128, 7 *  128,
    4 *  256, 5 *  256, 6 *  256, 7 *  256,
    4 *  512, 5 *  512, 6 *  512, 7 *  512,
    4 * 1024, 5 * 1024, 6 * 1024, 7 * 1024,
    4 * 2048, 5 * 2048, 6 * 2048, 7 * 2048,
    4 * 4096
};

#define RTL_MEMORY_CACHED_LIMIT 4 * 4096
#define RTL_MEMORY_CACHED_SIZES (SAL_N_ELEMENTS(g_alloc_sizes))

static rtl_cache_type * g_alloc_caches[RTL_MEMORY_CACHED_SIZES] =
{
    0,
};

#define RTL_MEMALIGN       8
#define RTL_MEMALIGN_SHIFT 3

static rtl_cache_type * g_alloc_table[RTL_MEMORY_CACHED_LIMIT >> RTL_MEMALIGN_SHIFT] =
{
    0,
};

static rtl_arena_type * gp_alloc_arena = 0;

/* ================================================================= *
 *
 * custom allocator implemenation.
 *
 * ================================================================= */

void *
SAL_CALL rtl_allocateMemory_CUSTOM (sal_Size n) SAL_THROW_EXTERN_C()
{
    void * p = 0;
    if (n > 0)
    {
        char *     addr;
        sal_Size   size = RTL_MEMORY_ALIGN(n + RTL_MEMALIGN, RTL_MEMALIGN);

        assert(RTL_MEMALIGN >= sizeof(sal_Size));
        if (n >= SAL_MAX_SIZE - (RTL_MEMALIGN + RTL_MEMALIGN - 1))
        {
            /* requested size too large for roundup alignment */
            return 0;
        }

try_alloc:
        if (size <= RTL_MEMORY_CACHED_LIMIT)
            addr = (char*)rtl_cache_alloc(g_alloc_table[(size - 1) >> RTL_MEMALIGN_SHIFT]);
        else
            addr = (char*)rtl_arena_alloc (gp_alloc_arena, &size);

        if (addr != 0)
        {
            ((sal_Size*)(addr))[0] = size;
            p = addr + RTL_MEMALIGN;
        }
        else if (gp_alloc_arena == 0)
        {
            ensureMemorySingleton();
            if (gp_alloc_arena)
            {
                /* try again */
                goto try_alloc;
            }
        }
    }
    return (p);
}

/* ================================================================= */

void SAL_CALL rtl_freeMemory_CUSTOM (void * p) SAL_THROW_EXTERN_C()
{
    if (p != 0)
    {
        char *   addr = (char*)(p) - RTL_MEMALIGN;
        sal_Size size = ((sal_Size*)(addr))[0];

        if (size <= RTL_MEMORY_CACHED_LIMIT)
            rtl_cache_free(g_alloc_table[(size - 1) >> RTL_MEMALIGN_SHIFT], addr);
        else
            rtl_arena_free (gp_alloc_arena, addr, size);
    }
}

/* ================================================================= */

void * SAL_CALL rtl_reallocateMemory_CUSTOM (void * p, sal_Size n) SAL_THROW_EXTERN_C()
{
    if (n > 0)
    {
        if (p != 0)
        {
            void *   p_old = p;
            sal_Size n_old = ((sal_Size*)( (char*)(p) - RTL_MEMALIGN  ))[0] - RTL_MEMALIGN;

            p = rtl_allocateMemory (n);
            if (p != 0)
            {
                memcpy (p, p_old, SAL_MIN(n, n_old));
                rtl_freeMemory (p_old);
            }
        }
        else
        {
            p = rtl_allocateMemory (n);
        }
    }
    else if (p != 0)
    {
        rtl_freeMemory (p), p = 0;
    }
    return (p);
}

#endif

/* ================================================================= *
 *
 * custom allocator initialization / finalization.
 *
 * ================================================================= */

void rtl_memory_init()
{
#if !defined(FORCE_SYSALLOC)
    {
        /* global memory arena */
        assert(gp_alloc_arena == 0);

        gp_alloc_arena = rtl_arena_create (
            "rtl_alloc_arena",
            2048,     /* quantum */
            0,        /* w/o quantum caching */
            0,        /* default source */
            rtl_arena_alloc,
            rtl_arena_free,
            0         /* flags */
        );
        assert(gp_alloc_arena != 0);
    }
    {
        sal_Size size;
        int i, n = RTL_MEMORY_CACHED_SIZES;

        for (i = 0; i < n; i++)
        {
            char name[RTL_CACHE_NAME_LENGTH + 1];
            (void) snprintf (name, sizeof(name), "rtl_alloc_%lu", g_alloc_sizes[i]);
            g_alloc_caches[i] = rtl_cache_create (name, g_alloc_sizes[i], 0, NULL, NULL, NULL, NULL, NULL, 0);
        }

        size = RTL_MEMALIGN;
        for (i = 0; i < n; i++)
        {
            while (size <= g_alloc_sizes[i])
            {
                g_alloc_table[(size - 1) >> RTL_MEMALIGN_SHIFT] = g_alloc_caches[i];
                size += RTL_MEMALIGN;
            }
        }
    }
#endif
    // SAL_INFO("sal", "rtl_memory_init completed");
}

/* ================================================================= */

void rtl_memory_fini()
{
#if !defined(FORCE_SYSALLOC)
    int i, n;

    /* clear g_alloc_table */
    memset (g_alloc_table, 0, sizeof(g_alloc_table));

    /* cleanup g_alloc_caches */
    for (i = 0, n = RTL_MEMORY_CACHED_SIZES; i < n; i++)
    {
        if (g_alloc_caches[i] != 0)
        {
            rtl_cache_destroy (g_alloc_caches[i]);
            g_alloc_caches[i] = 0;
        }
    }

    /* cleanup gp_alloc_arena */
    if (gp_alloc_arena != 0)
    {
        rtl_arena_destroy (gp_alloc_arena);
        gp_alloc_arena = 0;
    }
#endif
    // SAL_INFO("sal", "rtl_memory_fini completed");
}

/* ================================================================= *
 *
 * system allocator implemenation.
 *
 * ================================================================= */

void * SAL_CALL rtl_allocateMemory_SYSTEM (sal_Size n)
{
    return malloc (n);
}

/* ================================================================= */

void SAL_CALL rtl_freeMemory_SYSTEM (void * p)
{
    free (p);
}

/* ================================================================= */

void * SAL_CALL rtl_reallocateMemory_SYSTEM (void * p, sal_Size n)
{
    return realloc (p, n);
}

/* ================================================================= */

void* SAL_CALL rtl_allocateMemory (sal_Size n) SAL_THROW_EXTERN_C()
{
    SAL_WARN_IF(
        n >= SAL_MAX_INT32, "sal",
        "suspicious massive alloc " << n);
#if !defined(FORCE_SYSALLOC)
    while (1)
    {
        if (alloc_mode == AMode_CUSTOM)
        {
            return rtl_allocateMemory_CUSTOM(n);
        }
        if (alloc_mode == AMode_SYSTEM)
        {
            return rtl_allocateMemory_SYSTEM(n);
        }
        determine_alloc_mode();
    }
#else
    return rtl_allocateMemory_SYSTEM(n);
#endif
}

void* SAL_CALL rtl_reallocateMemory (void * p, sal_Size n) SAL_THROW_EXTERN_C()
{
    SAL_WARN_IF(
        n >= SAL_MAX_INT32, "sal",
        "suspicious massive alloc " << n);
#if !defined(FORCE_SYSALLOC)
    while (1)
    {
        if (alloc_mode == AMode_CUSTOM)
        {
            return rtl_reallocateMemory_CUSTOM(p,n);
        }
        if (alloc_mode == AMode_SYSTEM)
        {
            return rtl_reallocateMemory_SYSTEM(p,n);
        }
        determine_alloc_mode();
    }
#else
    return rtl_reallocateMemory_SYSTEM(p,n);
#endif
}

void SAL_CALL rtl_freeMemory (void * p) SAL_THROW_EXTERN_C()
{
#if !defined(FORCE_SYSALLOC)
    while (1)
    {
        if (alloc_mode == AMode_CUSTOM)
        {
            rtl_freeMemory_CUSTOM(p);
            return;
        }
        if (alloc_mode == AMode_SYSTEM)
        {
            rtl_freeMemory_SYSTEM(p);
            return;
        }
        determine_alloc_mode();
    }
#else
    rtl_freeMemory_SYSTEM(p);
#endif
}

/* ================================================================= *
 *
 * rtl_(allocate|free)ZeroMemory() implemenation.
 *
 * ================================================================= */

void * SAL_CALL rtl_allocateZeroMemory (sal_Size n) SAL_THROW_EXTERN_C()
{
    void * p = rtl_allocateMemory (n);
    if (p != 0)
        memset (p, 0, n);
    return (p);
}

/* ================================================================= */

void SAL_CALL rtl_freeZeroMemory (void * p, sal_Size n) SAL_THROW_EXTERN_C()
{
    if (p != 0)
    {
        memset (p, 0, n);
        rtl_freeMemory (p);
    }
}

/* ================================================================= */

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>#include <iostream>
#include <iomanip> // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple> // get<n>(xxx)
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set> // S.insert(M);
// if (S.find(key) != S.end()) { }
// for (auto it=S.begin(); it != S.end(); it++) { }
// auto it = S.lower_bound(M);
#include <random> // random_device rd; mt19937 mt(rd());
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib> // atoi(xxx)
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.
// insert #if<tab> by my emacs. #if DEBUG == 1 ... #end

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

int H, W, N;
ll f;
int sx, sy, gx, gy;
int a[70010];
int b[70010];
char c[70010];
int d[70010];
ll e[70010];

typedef tuple<ll, int> pass;
vector<pass> V[100010];

int main () {
  cin >> H >> W >> N >> f;
  cin >> sx >> sy >> gx >> gy;
  sx--; sy--; gx--; gy--;
  for (auto i = 0; i < N; ++i) {
    cin >> a[i] >> b[i] >> c[i] >> d[i] >> e[i];
    a[i]--; b[i]--;
    if (c[i] == 'W') d[i] = -1 * d[i];
  }
  assert(H == 1);
  for (auto i = 0; i < W-1; ++i) {
    V[i].push_back(pass(f, i+1));
    V[i+1].push_back(pass(f, i));
  }
  for (auto i = 0; i < N; ++i) {
    V[a[i]].push_back(pass(0, b[i]+d[i]));
    int gyaku = a[i]-d[i];
    if (0 <= gyaku && gyaku < W) {
      V[a[i]].push_back(pass(e[i], gyaku));
    }
  }
  priority_queue<pass, vector<pass>, greater<pass> > Q;
  Q.push(pass(0, sy));
  int visited[100010];
  fill(visited, visited+100010, -1);
  while (!Q.empty()) {
    ll cost = get<0>(Q.top());
    int now = get<1>(Q.top());
    Q.pop();
    if (visited[now] == -1) {
      visited[now] = cost;
      if (now == gy) {
        cout << cost << endl;
        return 0;
      }
      for (auto x : V[now]) {
        ll newcost = cost + get<0>(x);
        int dst = get<1>(x);
        if (visited[dst] == -1) {
          Q.push(pass(newcost, dst));
        }
      }
    }
  }
}
<commit_msg>submit F.cpp to 'F - Find the Route!' (s8pc-4) [C++14 (GCC 5.4.1)]<commit_after>#include <iostream>
#include <iomanip> // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple> // get<n>(xxx)
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set> // S.insert(M);
// if (S.find(key) != S.end()) { }
// for (auto it=S.begin(); it != S.end(); it++) { }
// auto it = S.lower_bound(M);
#include <random> // random_device rd; mt19937 mt(rd());
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib> // atoi(xxx)
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.
// insert #if<tab> by my emacs. #if DEBUG == 1 ... #end

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

int H, W, N;
ll f;
int sx, sy, gx, gy;
int a[70010];
int b[70010];
char c[70010];
int d[70010];
ll e[70010];

typedef tuple<ll, int> pass;
vector<pass> V[100010];

int main () {
  cin >> H >> W >> N >> f;
  cin >> sx >> sy >> gx >> gy;
  sx--; sy--; gx--; gy--;
  for (auto i = 0; i < N; ++i) {
    cin >> a[i] >> b[i] >> c[i] >> d[i] >> e[i];
    a[i]--; b[i]--;
    if (c[i] == 'E') d[i] = -1 * d[i];
  }
  assert(H == 1);
  for (auto i = 0; i < W-1; ++i) {
    V[i].push_back(pass(f, i+1));
    V[i+1].push_back(pass(f, i));
  }
  for (auto i = 0; i < N; ++i) {
    V[a[i]].push_back(pass(0, b[i]+d[i]));
    int gyaku = a[i]-d[i];
    if (0 <= gyaku && gyaku < W) {
      V[a[i]].push_back(pass(e[i], gyaku));
    }
  }
  priority_queue<pass, vector<pass>, greater<pass> > Q;
  Q.push(pass(0, sy));
  int visited[100010];
  fill(visited, visited+100010, -1);
  while (!Q.empty()) {
    ll cost = get<0>(Q.top());
    int now = get<1>(Q.top());
    Q.pop();
    if (visited[now] == -1) {
      visited[now] = cost;
      if (now == gy) {
        cout << cost << endl;
        return 0;
      }
      for (auto x : V[now]) {
        ll newcost = cost + get<0>(x);
        int dst = get<1>(x);
        if (visited[dst] == -1) {
          Q.push(pass(newcost, dst));
        }
      }
    }
  }
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2011, Ben Noordhuis <info@bnoordhuis.nl>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <stdlib.h>
#include "v8.h"
#include "node.h"

using namespace v8;
using namespace node;

namespace {

typedef struct proxy_container {
  Persistent<Object> proxy;
  Persistent<Object> target;
  Persistent<Array>  callbacks;
} proxy_container;

Persistent<ObjectTemplate> proxyClass;

bool IsDead(Handle<Object> proxy) {
  assert(proxy->InternalFieldCount() == 1);
  proxy_container *cont = reinterpret_cast<proxy_container*>(
      proxy->GetPointerFromInternalField(0));
  return cont == NULL || cont->target.IsEmpty();
}

Handle<Object> Unwrap(Handle<Object> proxy) {
  assert(!IsDead(proxy));
  proxy_container *cont = reinterpret_cast<proxy_container*>(
      proxy->GetPointerFromInternalField(0));
  return cont->target;
}

Handle<Array> GetCallbacks(Handle<Object> proxy) {
  proxy_container *cont = reinterpret_cast<proxy_container*>(
      proxy->GetPointerFromInternalField(0));
  assert(cont != NULL);
  return cont->callbacks;
}

#define UNWRAP                            \
  HandleScope scope;                      \
  Handle<Object> obj;                     \
  const bool dead = IsDead(info.This());  \
  if (!dead) obj = Unwrap(info.This());   \

Handle<Value> WeakNamedPropertyGetter(Local<String> property,
                                      const AccessorInfo& info) {
  UNWRAP
  return dead ? Local<Value>() : obj->Get(property);
}

Handle<Value> WeakNamedPropertySetter(Local<String> property,
                                      Local<Value> value,
                                      const AccessorInfo& info) {
  UNWRAP
  if (!dead) obj->Set(property, value);
  return value;
}

Handle<Integer> WeakNamedPropertyQuery(Local<String> property,
                                       const AccessorInfo& info) {
  return HandleScope().Close(Integer::New(None));
}

Handle<Boolean> WeakNamedPropertyDeleter(Local<String> property,
                                         const AccessorInfo& info) {
  UNWRAP
  return Boolean::New(!dead && obj->Delete(property));
}

Handle<Value> WeakIndexedPropertyGetter(uint32_t index,
                                        const AccessorInfo& info) {
  UNWRAP
  return dead ? Local<Value>() : obj->Get(index);
}

Handle<Value> WeakIndexedPropertySetter(uint32_t index,
                                        Local<Value> value,
                                        const AccessorInfo& info) {
  UNWRAP
  if (!dead) obj->Set(index, value);
  return value;
}

Handle<Integer> WeakIndexedPropertyQuery(uint32_t index,
                                         const AccessorInfo& info) {
  return HandleScope().Close(Integer::New(None));
}

Handle<Boolean> WeakIndexedPropertyDeleter(uint32_t index,
                                           const AccessorInfo& info) {
  UNWRAP
  return Boolean::New(!dead && obj->Delete(index));
}

Handle<Array> WeakPropertyEnumerator(const AccessorInfo& info) {
  UNWRAP
  return HandleScope().Close(dead ? Array::New(0) : obj->GetPropertyNames());
}

void AddCallback(Handle<Object> proxy, Handle<Function> callback) {
  Handle<Array> callbacks = GetCallbacks(proxy);
  callbacks->Set(Integer::New(callbacks->Length()), callback);
}

void TargetCallback(Persistent<Value> target, void* arg) {
  HandleScope scope;

  assert(target.IsNearDeath());

  proxy_container *cont = reinterpret_cast<proxy_container*>(arg);

  // invoke any listening callbacks
  uint32_t len = cont->callbacks->Length();
  Handle<Value> argv[1];
  argv[0] = target;
  for (uint32_t i=0; i<len; i++) {

    Handle<Function> cb = Handle<Function>::Cast(
        cont->callbacks->Get(Integer::New(i)));

    TryCatch try_catch;

    cb->Call(target->ToObject(), 1, argv);

    if (try_catch.HasCaught()) {
      FatalException(try_catch);
    }
  }

  cont->proxy->SetPointerInInternalField(0, NULL);
  cont->proxy.Dispose();
  cont->proxy.Clear();
  cont->target.Dispose();
  cont->target.Clear();
  cont->callbacks.Dispose();
  cont->callbacks.Clear();
  free(cont);
}

Handle<Value> Create(const Arguments& args) {
  HandleScope scope;

  if (!args[0]->IsObject()) {
    Local<String> message = String::New("Object expected");
    return ThrowException(Exception::TypeError(message));
  }

  proxy_container *cont = (proxy_container *)
    malloc(sizeof(proxy_container));

  cont->target = Persistent<Object>::New(args[0]->ToObject());
  cont->callbacks = Persistent<Array>::New(Array::New());

  cont->proxy = Persistent<Object>::New(proxyClass->NewInstance());
  cont->proxy->SetPointerInInternalField(0, cont);

  cont->target.MakeWeak(cont, TargetCallback);

  if (args.Length() >= 2) {
    AddCallback(cont->proxy, Handle<Function>::Cast(args[1]));
  }

  return cont->proxy;
}

/**
 * TODO: Make this better.
 */

bool isWeakRef (Handle<Value> val) {
  return val->IsObject() && val->ToObject()->InternalFieldCount() == 1;
}

Handle<Value> IsWeakRef (const Arguments& args) {
  HandleScope scope;
  return Boolean::New(isWeakRef(args[0]));
}

Handle<Value> Get(const Arguments& args) {
  HandleScope scope;

  if (!isWeakRef(args[0])) {
    Local<String> message = String::New("Weakref instance expected");
    return ThrowException(Exception::TypeError(message));
  }
  Local<Object> proxy = args[0]->ToObject();

  const bool dead = IsDead(proxy);
  if (dead) return Undefined();

  Handle<Object> obj = Unwrap(proxy);
  return scope.Close(obj);
}

Handle<Value> IsNearDeath(const Arguments& args) {
  HandleScope scope;

  if (!args[0]->IsObject()
         || args[0]->ToObject()->InternalFieldCount() != 1) {
    Local<String> message = String::New("Weakref instance expected");
    return ThrowException(Exception::TypeError(message));
  }
  Local<Object> proxy = args[0]->ToObject();

  proxy_container *cont = reinterpret_cast<proxy_container*>(
      proxy->GetPointerFromInternalField(0));
  assert(cont != NULL);

  Handle<Boolean> rtn = Boolean::New(cont->target.IsNearDeath());

  return scope.Close(rtn);
}

Handle<Value> IsDead(const Arguments& args) {
  HandleScope scope;

  if (!args[0]->IsObject()
         || args[0]->ToObject()->InternalFieldCount() != 1) {
    Local<String> message = String::New("Weakref instance expected");
    return ThrowException(Exception::TypeError(message));
  }
  Local<Object> proxy = args[0]->ToObject();

  const bool dead = IsDead(proxy);
  return Boolean::New(dead);
}

Handle<Value> AddCallback(const Arguments& args) {
  HandleScope scope;
  if (!args[0]->IsObject()
         || args[0]->ToObject()->InternalFieldCount() != 1) {
    Local<String> message = String::New("Weakref instance expected");
    return ThrowException(Exception::TypeError(message));
  }
  Local<Object> proxy = args[0]->ToObject();
  assert(proxy->InternalFieldCount() == 1);

  AddCallback(proxy, Handle<Function>::Cast(args[1]));

  return Undefined();
}

Handle<Value> Callbacks(const Arguments& args) {
  HandleScope scope;
  if (!args[0]->IsObject()
         || args[0]->ToObject()->InternalFieldCount() != 1) {
    Local<String> message = String::New("Weakref instance expected");
    return ThrowException(Exception::TypeError(message));
  }
  Local<Object> proxy = args[0]->ToObject();
  assert(proxy->InternalFieldCount() == 1);

  return scope.Close(GetCallbacks(proxy));
}

void Initialize(Handle<Object> target) {
  HandleScope scope;

  proxyClass = Persistent<ObjectTemplate>::New(ObjectTemplate::New());
  proxyClass->SetNamedPropertyHandler(WeakNamedPropertyGetter,
                                      WeakNamedPropertySetter,
                                      WeakNamedPropertyQuery,
                                      WeakNamedPropertyDeleter,
                                      WeakPropertyEnumerator);
  proxyClass->SetIndexedPropertyHandler(WeakIndexedPropertyGetter,
                                        WeakIndexedPropertySetter,
                                        WeakIndexedPropertyQuery,
                                        WeakIndexedPropertyDeleter,
                                        WeakPropertyEnumerator);
  proxyClass->SetInternalFieldCount(1);

  NODE_SET_METHOD(target, "get", Get);
  NODE_SET_METHOD(target, "create", Create);
  NODE_SET_METHOD(target, "isWeakRef", IsWeakRef);
  NODE_SET_METHOD(target, "isNearDeath", IsNearDeath);
  NODE_SET_METHOD(target, "isDead", IsDead);
  NODE_SET_METHOD(target, "callbacks", Callbacks);
  NODE_SET_METHOD(target, "addCallback", AddCallback);

}

} // anonymous namespace

NODE_MODULE(weakref, Initialize);
<commit_msg>Use isWeakRef() internally.<commit_after>/*
 * Copyright (c) 2011, Ben Noordhuis <info@bnoordhuis.nl>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <stdlib.h>
#include "v8.h"
#include "node.h"

using namespace v8;
using namespace node;

namespace {

typedef struct proxy_container {
  Persistent<Object> proxy;
  Persistent<Object> target;
  Persistent<Array>  callbacks;
} proxy_container;

Persistent<ObjectTemplate> proxyClass;

bool IsDead(Handle<Object> proxy) {
  assert(proxy->InternalFieldCount() == 1);
  proxy_container *cont = reinterpret_cast<proxy_container*>(
      proxy->GetPointerFromInternalField(0));
  return cont == NULL || cont->target.IsEmpty();
}

Handle<Object> Unwrap(Handle<Object> proxy) {
  assert(!IsDead(proxy));
  proxy_container *cont = reinterpret_cast<proxy_container*>(
      proxy->GetPointerFromInternalField(0));
  return cont->target;
}

Handle<Array> GetCallbacks(Handle<Object> proxy) {
  proxy_container *cont = reinterpret_cast<proxy_container*>(
      proxy->GetPointerFromInternalField(0));
  assert(cont != NULL);
  return cont->callbacks;
}

#define UNWRAP                            \
  HandleScope scope;                      \
  Handle<Object> obj;                     \
  const bool dead = IsDead(info.This());  \
  if (!dead) obj = Unwrap(info.This());   \

Handle<Value> WeakNamedPropertyGetter(Local<String> property,
                                      const AccessorInfo& info) {
  UNWRAP
  return dead ? Local<Value>() : obj->Get(property);
}

Handle<Value> WeakNamedPropertySetter(Local<String> property,
                                      Local<Value> value,
                                      const AccessorInfo& info) {
  UNWRAP
  if (!dead) obj->Set(property, value);
  return value;
}

Handle<Integer> WeakNamedPropertyQuery(Local<String> property,
                                       const AccessorInfo& info) {
  return HandleScope().Close(Integer::New(None));
}

Handle<Boolean> WeakNamedPropertyDeleter(Local<String> property,
                                         const AccessorInfo& info) {
  UNWRAP
  return Boolean::New(!dead && obj->Delete(property));
}

Handle<Value> WeakIndexedPropertyGetter(uint32_t index,
                                        const AccessorInfo& info) {
  UNWRAP
  return dead ? Local<Value>() : obj->Get(index);
}

Handle<Value> WeakIndexedPropertySetter(uint32_t index,
                                        Local<Value> value,
                                        const AccessorInfo& info) {
  UNWRAP
  if (!dead) obj->Set(index, value);
  return value;
}

Handle<Integer> WeakIndexedPropertyQuery(uint32_t index,
                                         const AccessorInfo& info) {
  return HandleScope().Close(Integer::New(None));
}

Handle<Boolean> WeakIndexedPropertyDeleter(uint32_t index,
                                           const AccessorInfo& info) {
  UNWRAP
  return Boolean::New(!dead && obj->Delete(index));
}

Handle<Array> WeakPropertyEnumerator(const AccessorInfo& info) {
  UNWRAP
  return HandleScope().Close(dead ? Array::New(0) : obj->GetPropertyNames());
}

void AddCallback(Handle<Object> proxy, Handle<Function> callback) {
  Handle<Array> callbacks = GetCallbacks(proxy);
  callbacks->Set(Integer::New(callbacks->Length()), callback);
}

void TargetCallback(Persistent<Value> target, void* arg) {
  HandleScope scope;

  assert(target.IsNearDeath());

  proxy_container *cont = reinterpret_cast<proxy_container*>(arg);

  // invoke any listening callbacks
  uint32_t len = cont->callbacks->Length();
  Handle<Value> argv[1];
  argv[0] = target;
  for (uint32_t i=0; i<len; i++) {

    Handle<Function> cb = Handle<Function>::Cast(
        cont->callbacks->Get(Integer::New(i)));

    TryCatch try_catch;

    cb->Call(target->ToObject(), 1, argv);

    if (try_catch.HasCaught()) {
      FatalException(try_catch);
    }
  }

  cont->proxy->SetPointerInInternalField(0, NULL);
  cont->proxy.Dispose();
  cont->proxy.Clear();
  cont->target.Dispose();
  cont->target.Clear();
  cont->callbacks.Dispose();
  cont->callbacks.Clear();
  free(cont);
}

Handle<Value> Create(const Arguments& args) {
  HandleScope scope;

  if (!args[0]->IsObject()) {
    Local<String> message = String::New("Object expected");
    return ThrowException(Exception::TypeError(message));
  }

  proxy_container *cont = (proxy_container *)
    malloc(sizeof(proxy_container));

  cont->target = Persistent<Object>::New(args[0]->ToObject());
  cont->callbacks = Persistent<Array>::New(Array::New());

  cont->proxy = Persistent<Object>::New(proxyClass->NewInstance());
  cont->proxy->SetPointerInInternalField(0, cont);

  cont->target.MakeWeak(cont, TargetCallback);

  if (args.Length() >= 2) {
    AddCallback(cont->proxy, Handle<Function>::Cast(args[1]));
  }

  return cont->proxy;
}

/**
 * TODO: Make this better.
 */

bool isWeakRef (Handle<Value> val) {
  return val->IsObject() && val->ToObject()->InternalFieldCount() == 1;
}

Handle<Value> IsWeakRef (const Arguments& args) {
  HandleScope scope;
  return Boolean::New(isWeakRef(args[0]));
}

Handle<Value> Get(const Arguments& args) {
  HandleScope scope;

  if (!isWeakRef(args[0])) {
    Local<String> message = String::New("Weakref instance expected");
    return ThrowException(Exception::TypeError(message));
  }
  Local<Object> proxy = args[0]->ToObject();

  const bool dead = IsDead(proxy);
  if (dead) return Undefined();

  Handle<Object> obj = Unwrap(proxy);
  return scope.Close(obj);
}

Handle<Value> IsNearDeath(const Arguments& args) {
  HandleScope scope;

  if (!isWeakRef(args[0])) {
    Local<String> message = String::New("Weakref instance expected");
    return ThrowException(Exception::TypeError(message));
  }
  Local<Object> proxy = args[0]->ToObject();

  proxy_container *cont = reinterpret_cast<proxy_container*>(
      proxy->GetPointerFromInternalField(0));
  assert(cont != NULL);

  Handle<Boolean> rtn = Boolean::New(cont->target.IsNearDeath());

  return scope.Close(rtn);
}

Handle<Value> IsDead(const Arguments& args) {
  HandleScope scope;

  if (!isWeakRef(args[0])) {
    Local<String> message = String::New("Weakref instance expected");
    return ThrowException(Exception::TypeError(message));
  }
  Local<Object> proxy = args[0]->ToObject();

  const bool dead = IsDead(proxy);
  return Boolean::New(dead);
}

Handle<Value> AddCallback(const Arguments& args) {
  HandleScope scope;

  if (!isWeakRef(args[0])) {
    Local<String> message = String::New("Weakref instance expected");
    return ThrowException(Exception::TypeError(message));
  }
  Local<Object> proxy = args[0]->ToObject();

  AddCallback(proxy, Handle<Function>::Cast(args[1]));

  return Undefined();
}

Handle<Value> Callbacks(const Arguments& args) {
  HandleScope scope;

  if (!isWeakRef(args[0])) {
    Local<String> message = String::New("Weakref instance expected");
    return ThrowException(Exception::TypeError(message));
  }
  Local<Object> proxy = args[0]->ToObject();

  return scope.Close(GetCallbacks(proxy));
}

void Initialize(Handle<Object> target) {
  HandleScope scope;

  proxyClass = Persistent<ObjectTemplate>::New(ObjectTemplate::New());
  proxyClass->SetNamedPropertyHandler(WeakNamedPropertyGetter,
                                      WeakNamedPropertySetter,
                                      WeakNamedPropertyQuery,
                                      WeakNamedPropertyDeleter,
                                      WeakPropertyEnumerator);
  proxyClass->SetIndexedPropertyHandler(WeakIndexedPropertyGetter,
                                        WeakIndexedPropertySetter,
                                        WeakIndexedPropertyQuery,
                                        WeakIndexedPropertyDeleter,
                                        WeakPropertyEnumerator);
  proxyClass->SetInternalFieldCount(1);

  NODE_SET_METHOD(target, "get", Get);
  NODE_SET_METHOD(target, "create", Create);
  NODE_SET_METHOD(target, "isWeakRef", IsWeakRef);
  NODE_SET_METHOD(target, "isNearDeath", IsNearDeath);
  NODE_SET_METHOD(target, "isDead", IsDead);
  NODE_SET_METHOD(target, "callbacks", Callbacks);
  NODE_SET_METHOD(target, "addCallback", AddCallback);

}

} // anonymous namespace

NODE_MODULE(weakref, Initialize);
<|endoftext|>


<commit_before>/**
 * ros_control node for commanding K.H.A.N. via Python
 * \author: Jason Ziglar <jpz@vt.edu>
 * \date: 10/28/2015
 */
#include "khan_control/KHANHWInterface.h"

#include <ros/ros.h>
#include <controller_manager/controller_manager.h>

controller_manager::ControllerManager* CM = NULL;
khan::KHANHWInterface* HWInterface = NULL;

void updateHW(const ros::TimerEvent& event)
{
  CM->update(event.current_real, event.current_real - event.last_real);
  HWInterface->write(event.current_real, event.current_real - event.last_real);
}

int main(int argc, char** argv)
{
  ros::init(argc, argv, "KHANPythonControl");
  ros::NodeHandle nhp("~");

  std::string robot_ns;
  double period;

  nhp.param("robot_namespace", robot_ns, std::string(""));
  nhp.param("period", period, 1.0 / 50.0);
  //Ensure the namespace is valid
  if(!robot_ns.empty() && robot_ns[robot_ns.length() - 1] != '/')
  {
    robot_ns = robot_ns + "/";
  }

  HWInterface = new khan::KHANHWInterface(robot_ns);
  CM = new controller_manager::ControllerManager(HWInterface);
  ros::Timer timer = nhp.createTimer(ros::Duration(period), updateHW);

  ros::spin();
}<commit_msg>Adding multi-threaded spinner to the hardware interface.<commit_after>/**
 * ros_control node for commanding K.H.A.N. via Python
 * \author: Jason Ziglar <jpz@vt.edu>
 * \date: 10/28/2015
 */
#include "khan_control/KHANHWInterface.h"

#include <ros/ros.h>
#include <controller_manager/controller_manager.h>

controller_manager::ControllerManager* CM = NULL;
khan::KHANHWInterface* HWInterface = NULL;

void updateHW(const ros::TimerEvent& event)
{
  CM->update(event.current_real, event.current_real - event.last_real);
  HWInterface->write(event.current_real, event.current_real - event.last_real);
}

int main(int argc, char** argv)
{
  ros::init(argc, argv, "KHANPythonControl");
  ros::NodeHandle nhp("~");

  std::string robot_ns;
  double period;

  nhp.param("robot_namespace", robot_ns, std::string(""));
  nhp.param("period", period, 1.0 / 50.0);
  //Ensure the namespace is valid
  if(!robot_ns.empty() && robot_ns[robot_ns.length() - 1] != '/')
  {
    robot_ns = robot_ns + "/";
  }

  HWInterface = new khan::KHANHWInterface(robot_ns);
  CM = new controller_manager::ControllerManager(HWInterface);
  ros::Timer timer = nhp.createTimer(ros::Duration(period), updateHW);

  ros::MultiThreadedSpinner spinner(2);
  spinner.spin();

  return 0;
}<|endoftext|>


<commit_before>/*
 * IceWM
 *
 * Copyright (C) 1997-2003 Marko Macek
 *
 * Dialogs
 */
#include "config.h"

#include "ylib.h"
#include "wmabout.h"

#include "yprefs.h"
#include "prefs.h"
#include "wmapp.h"
#include "wmframe.h"
#include "sysdep.h"
#include "WinMgr.h"

#include "intl.h"

AboutDlg::AboutDlg(): YDialog() {
    char const *version("IceWM " VERSION " (" HOSTOS "/" HOSTCPU ")");
    ustring copyright =
        ustring("Copyright ")
        .append(_("(C)"))
        .append(" 1997-2008 Marko Macek, ")
        .append(_("(C)"))
        .append(" 2001 Mathias Hasselmann");

    fProgTitle = new YLabel(version, this);
    fCopyright = new YLabel(copyright, this);

    fThemeNameS = new YLabel(_("Theme:"), this);
    fThemeDescriptionS = new YLabel(_("Theme Description:"), this);
    fThemeAuthorS = new YLabel(_("Theme Author:"), this);
    fThemeName = new YLabel(themeName, this);
    fThemeDescription = new YLabel(themeDescription, this);
    fThemeAuthor = new YLabel(themeAuthor, this);
    fCodeSetS = new YLabel(_("CodeSet:"), this);
    fLanguageS = new YLabel(_("Language:"), this);
    const char *codeset = "";
    const char *language = "";
#ifdef CONFIG_I18N
    codeset = nl_langinfo(CODESET);
    language = getenv("LANG");
#endif

    fCodeSet = new YLabel(codeset, this);
    fLanguage = new YLabel(language, this);

    autoSize();
    fProgTitle->show();
    fCopyright->show();
    fThemeNameS->show();
    fThemeName->show();
    fThemeDescriptionS->show();
    fThemeDescription->show();
    fThemeAuthorS->show();
    fThemeAuthor->show();
    fCodeSetS->show();
    fCodeSet->show();
    fLanguageS->show();
    fLanguage->show();

    setWindowTitle(_("icewm - About"));
    //setIconTitle("icewm - About");
    setWinLayerHint(WinLayerAboveDock);
    setWinWorkspaceHint(-1);
    setWinHintsHint(WinHintsSkipWindowMenu);
    setMwmHints(MwmHints(
       MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS,
       MWM_FUNC_MOVE | MWM_FUNC_CLOSE,
       MWM_DECOR_BORDER | MWM_DECOR_TITLE | MWM_DECOR_MENU,
       0,
       0));
}

AboutDlg::~AboutDlg() {
    delete fProgTitle;
    delete fCopyright;
    delete fThemeName;
    delete fThemeDescription;
    delete fThemeAuthor;
    delete fThemeNameS;
    delete fThemeDescriptionS;
    delete fThemeAuthorS;
    delete fCodeSetS;
    delete fCodeSet;
    delete fLanguageS;
    delete fLanguage;
}

#define RX(w) (int((w)->x() + (w)->width()))
#define XMAX(x,nx) ((nx) > (x) ? (nx) : (x))

void AboutDlg::autoSize() {
    int dx = 20, dx1 = 20;
    int dy = 20;
    int W = 0, H;
    int cy;

    fProgTitle->setPosition(dx, dy); dy += fProgTitle->height();
    W = XMAX(W, RX(fProgTitle));
    dy += 4;
    fCopyright->setPosition(dx, dy); dy += fCopyright->height();
    W = XMAX(W, RX(fCopyright));
    dy += 20;

    fThemeNameS->setPosition(dx, dy);
    fThemeDescriptionS->setPosition(dx, dy);
    fThemeAuthorS->setPosition(dx, dy);
    fCodeSetS->setPosition(dx, dy);
    fLanguageS->setPosition(dx, dy);

    dx = XMAX(dx, RX(fThemeNameS));
    dx = XMAX(dx, RX(fThemeDescriptionS));
    dx = XMAX(dx, RX(fThemeAuthorS));
    dx = XMAX(dx, RX(fCodeSetS));
    dx = XMAX(dx, RX(fLanguageS));
    dx += 20;

    fThemeNameS->setPosition(dx1, dy);
    cy = fThemeNameS->height();
    W = XMAX(W, RX(fThemeName));
    fThemeName->setPosition(dx, dy);
    cy = XMAX(cy, int(fThemeName->height()));
    W = XMAX(W, RX(fThemeName));
    dy += cy;
    dy += 4;

    fThemeDescriptionS->setPosition(dx1, dy);
    cy = fThemeDescriptionS->height();
    W = XMAX(W, RX(fThemeDescriptionS));
    fThemeDescription->setPosition(dx, dy);
    cy = XMAX(cy, int(fThemeDescription->height()));
    W = XMAX(W, RX(fThemeDescription));
    dy += cy;

    dy += 4;

    fThemeAuthorS->setPosition(dx1, dy);
    cy = fThemeAuthorS->height();
    W = XMAX(W, RX(fThemeAuthorS));
    fThemeAuthor->setPosition(dx, dy);
    cy = XMAX(cy, int(fThemeAuthor->height()));
    W = XMAX(W, RX(fThemeAuthor));
    dy += cy;

    dy += 20;

    fCodeSetS->setPosition(dx1, dy);
    cy = fCodeSetS->height();
    W = XMAX(W, RX(fCodeSetS));
    fCodeSet->setPosition(dx, dy);
    cy = XMAX(cy, int(fCodeSet->height()));
    W = XMAX(W, RX(fCodeSet));
    dy += cy;

    dy += 4;

    fLanguageS->setPosition(dx1, dy);
    cy = fLanguageS->height();
    W = XMAX(W, RX(fLanguageS));
    fLanguage->setPosition(dx, dy);
    cy = XMAX(cy, int(fLanguage->height()));
    W = XMAX(W, RX(fLanguage));
    dy += cy;

    H = dy + 20;

    W += 20;
    setSize(W, H);
}

void AboutDlg::showFocused() {
    int dx, dy;
    unsigned dw, dh;
    manager->getScreenGeometry(&dx, &dy, &dw, &dh);

    if (getFrame() == 0)
        manager->manageClient(handle(), false);
    if (getFrame() != 0) {
        getFrame()->setNormalPositionOuter(
            dx + dw / 2 - getFrame()->width() / 2,
            dy + dh / 2 - getFrame()->height() / 2);
        getFrame()->activateWindow(true);
    }
}

void AboutDlg::handleClose() {
    if (!getFrame()->isHidden())
        getFrame()->wmHide();
}

// vim: set sw=4 ts=4 et:
<commit_msg>Set About title + class.<commit_after>/*
 * IceWM
 *
 * Copyright (C) 1997-2003 Marko Macek
 *
 * Dialogs
 */
#include "config.h"

#include "ylib.h"
#include "wmabout.h"

#include "yprefs.h"
#include "prefs.h"
#include "wmapp.h"
#include "wmframe.h"
#include "sysdep.h"
#include "WinMgr.h"

#include "intl.h"

AboutDlg::AboutDlg(): YDialog() {
    char const *version("IceWM " VERSION " (" HOSTOS "/" HOSTCPU ")");
    ustring copyright =
        ustring("Copyright ")
        .append(_("(C)"))
        .append(" 1997-2008 Marko Macek, ")
        .append(_("(C)"))
        .append(" 2001 Mathias Hasselmann");

    fProgTitle = new YLabel(version, this);
    fCopyright = new YLabel(copyright, this);

    fThemeNameS = new YLabel(_("Theme:"), this);
    fThemeDescriptionS = new YLabel(_("Theme Description:"), this);
    fThemeAuthorS = new YLabel(_("Theme Author:"), this);
    fThemeName = new YLabel(themeName, this);
    fThemeDescription = new YLabel(themeDescription, this);
    fThemeAuthor = new YLabel(themeAuthor, this);
    fCodeSetS = new YLabel(_("CodeSet:"), this);
    fLanguageS = new YLabel(_("Language:"), this);
    const char *codeset = "";
    const char *language = "";
#ifdef CONFIG_I18N
    codeset = nl_langinfo(CODESET);
    language = getenv("LANG");
#endif

    fCodeSet = new YLabel(codeset, this);
    fLanguage = new YLabel(language, this);

    autoSize();
    fProgTitle->show();
    fCopyright->show();
    fThemeNameS->show();
    fThemeName->show();
    fThemeDescriptionS->show();
    fThemeDescription->show();
    fThemeAuthorS->show();
    fThemeAuthor->show();
    fCodeSetS->show();
    fCodeSet->show();
    fLanguageS->show();
    fLanguage->show();

    setTitle("About");
    setWindowTitle(_("icewm - About"));
    //setIconTitle("icewm - About");
    setClassHint("about", "IceWM");

    setWinLayerHint(WinLayerAboveDock);
    setWinWorkspaceHint(-1);
    setWinHintsHint(WinHintsSkipWindowMenu);
    setMwmHints(MwmHints(
       MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS,
       MWM_FUNC_MOVE | MWM_FUNC_CLOSE,
       MWM_DECOR_BORDER | MWM_DECOR_TITLE | MWM_DECOR_MENU,
       0,
       0));
}

AboutDlg::~AboutDlg() {
    delete fProgTitle;
    delete fCopyright;
    delete fThemeName;
    delete fThemeDescription;
    delete fThemeAuthor;
    delete fThemeNameS;
    delete fThemeDescriptionS;
    delete fThemeAuthorS;
    delete fCodeSetS;
    delete fCodeSet;
    delete fLanguageS;
    delete fLanguage;
}

#define RX(w) (int((w)->x() + (w)->width()))
#define XMAX(x,nx) ((nx) > (x) ? (nx) : (x))

void AboutDlg::autoSize() {
    int dx = 20, dx1 = 20;
    int dy = 20;
    int W = 0, H;
    int cy;

    fProgTitle->setPosition(dx, dy); dy += fProgTitle->height();
    W = XMAX(W, RX(fProgTitle));
    dy += 4;
    fCopyright->setPosition(dx, dy); dy += fCopyright->height();
    W = XMAX(W, RX(fCopyright));
    dy += 20;

    fThemeNameS->setPosition(dx, dy);
    fThemeDescriptionS->setPosition(dx, dy);
    fThemeAuthorS->setPosition(dx, dy);
    fCodeSetS->setPosition(dx, dy);
    fLanguageS->setPosition(dx, dy);

    dx = XMAX(dx, RX(fThemeNameS));
    dx = XMAX(dx, RX(fThemeDescriptionS));
    dx = XMAX(dx, RX(fThemeAuthorS));
    dx = XMAX(dx, RX(fCodeSetS));
    dx = XMAX(dx, RX(fLanguageS));
    dx += 20;

    fThemeNameS->setPosition(dx1, dy);
    cy = fThemeNameS->height();
    W = XMAX(W, RX(fThemeName));
    fThemeName->setPosition(dx, dy);
    cy = XMAX(cy, int(fThemeName->height()));
    W = XMAX(W, RX(fThemeName));
    dy += cy;
    dy += 4;

    fThemeDescriptionS->setPosition(dx1, dy);
    cy = fThemeDescriptionS->height();
    W = XMAX(W, RX(fThemeDescriptionS));
    fThemeDescription->setPosition(dx, dy);
    cy = XMAX(cy, int(fThemeDescription->height()));
    W = XMAX(W, RX(fThemeDescription));
    dy += cy;

    dy += 4;

    fThemeAuthorS->setPosition(dx1, dy);
    cy = fThemeAuthorS->height();
    W = XMAX(W, RX(fThemeAuthorS));
    fThemeAuthor->setPosition(dx, dy);
    cy = XMAX(cy, int(fThemeAuthor->height()));
    W = XMAX(W, RX(fThemeAuthor));
    dy += cy;

    dy += 20;

    fCodeSetS->setPosition(dx1, dy);
    cy = fCodeSetS->height();
    W = XMAX(W, RX(fCodeSetS));
    fCodeSet->setPosition(dx, dy);
    cy = XMAX(cy, int(fCodeSet->height()));
    W = XMAX(W, RX(fCodeSet));
    dy += cy;

    dy += 4;

    fLanguageS->setPosition(dx1, dy);
    cy = fLanguageS->height();
    W = XMAX(W, RX(fLanguageS));
    fLanguage->setPosition(dx, dy);
    cy = XMAX(cy, int(fLanguage->height()));
    W = XMAX(W, RX(fLanguage));
    dy += cy;

    H = dy + 20;

    W += 20;
    setSize(W, H);
}

void AboutDlg::showFocused() {
    int dx, dy;
    unsigned dw, dh;
    manager->getScreenGeometry(&dx, &dy, &dw, &dh);

    if (getFrame() == 0)
        manager->manageClient(handle(), false);
    if (getFrame() != 0) {
        getFrame()->setNormalPositionOuter(
            dx + dw / 2 - getFrame()->width() / 2,
            dy + dh / 2 - getFrame()->height() / 2);
        getFrame()->activateWindow(true);
    }
}

void AboutDlg::handleClose() {
    if (!getFrame()->isHidden())
        getFrame()->wmHide();
}

// vim: set sw=4 ts=4 et:
<|endoftext|>