<commit_before>// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <boost/python.hpp>
#include <libtorrent/session.hpp>

using namespace boost::python;
using namespace libtorrent;

void bind_session_settings()
{
    class_<session_settings>("session_settings")
        .def_readwrite("user_agent", &session_settings::user_agent)
        .def_readwrite("tracker_completion_timeout", &session_settings::tracker_completion_timeout)
        .def_readwrite("tracker_receive_timeout", &session_settings::tracker_receive_timeout)
        .def_readwrite("stop_tracker_timeout", &session_settings::stop_tracker_timeout)
        .def_readwrite("tracker_maximum_response_length", &session_settings::tracker_maximum_response_length)
        .def_readwrite("piece_timeout", &session_settings::piece_timeout)
        .def_readwrite("request_timeout", &session_settings::request_timeout)
        .def_readwrite("request_queue_time", &session_settings::request_queue_time)
        .def_readwrite("max_allowed_in_request_queue", &session_settings::max_allowed_in_request_queue)
        .def_readwrite("max_out_request_queue", &session_settings::max_out_request_queue)
        .def_readwrite("whole_pieces_threshold", &session_settings::whole_pieces_threshold)
        .def_readwrite("peer_timeout", &session_settings::peer_timeout)
        .def_readwrite("urlseed_timeout", &session_settings::urlseed_timeout)
        .def_readwrite("urlseed_pipeline_size", &session_settings::urlseed_pipeline_size)
        .def_readwrite("urlseed_wait_retry", &session_settings::urlseed_wait_retry)
        .def_readwrite("file_pool_size", &session_settings::file_pool_size)
        .def_readwrite("allow_multiple_connections_per_ip", &session_settings::allow_multiple_connections_per_ip)
        .def_readwrite("max_failcount", &session_settings::max_failcount)
        .def_readwrite("min_reconnect_time", &session_settings::min_reconnect_time)
        .def_readwrite("peer_connect_timeout", &session_settings::peer_connect_timeout)
        .def_readwrite("ignore_limits_on_local_network", &session_settings::ignore_limits_on_local_network)
        .def_readwrite("connection_speed", &session_settings::connection_speed)
        .def_readwrite("send_redundant_have", &session_settings::send_redundant_have)
        .def_readwrite("lazy_bitfields", &session_settings::lazy_bitfields)
        .def_readwrite("inactivity_timeout", &session_settings::inactivity_timeout)
        .def_readwrite("unchoke_interval", &session_settings::unchoke_interval)
        .def_readwrite("optimistic_unchoke_multiplier", &session_settings::optimistic_unchoke_multiplier)
        .def_readwrite("num_want", &session_settings::num_want)
        .def_readwrite("initial_picker_threshold", &session_settings::initial_picker_threshold)
        .def_readwrite("allowed_fast_set_size", &session_settings::allowed_fast_set_size)
        .def_readwrite("max_outstanding_disk_bytes_per_connection", &session_settings::max_outstanding_disk_bytes_per_connection)
        .def_readwrite("handshake_timeout", &session_settings::handshake_timeout)
#ifndef TORRENT_DISABLE_DHT
        .def_readwrite("use_dht_as_fallback", &session_settings::use_dht_as_fallback)
#endif
        .def_readwrite("free_torrent_hashes", &session_settings::free_torrent_hashes)
        .def_readwrite("upnp_ignore_nonrouters", &session_settings::upnp_ignore_nonrouters)
        .def_readwrite("send_buffer_watermark", &session_settings::send_buffer_watermark)
        .def_readwrite("auto_upload_slots", &session_settings::auto_upload_slots)
        .def_readwrite("auto_upload_slots_rate_based", &session_settings::auto_upload_slots_rate_based)
        .def_readwrite("use_parole_mode", &session_settings::use_parole_mode)
        .def_readwrite("cache_size", &session_settings::cache_size)
        .def_readwrite("cache_buffer_chunk_size", &session_settings::cache_buffer_chunk_size)
        .def_readwrite("cache_expiry", &session_settings::cache_expiry)
        .def_readwrite("use_read_cache", &session_settings::use_read_cache)
        .def_readwrite("disk_io_write_mode", &session_settings::disk_io_write_mode)
        .def_readwrite("disk_io_read_mode", &session_settings::disk_io_read_mode)
        .def_readwrite("coalesce_reads", &session_settings::coalesce_reads)
        .def_readwrite("coalesce_writes", &session_settings:coalesce_writes)
        .def_readwrite("outgoing_ports", &session_settings::outgoing_ports)
        .def_readwrite("peer_tos", &session_settings::peer_tos)
        .def_readwrite("active_downloads", &session_settings::active_downloads)
        .def_readwrite("active_seeds", &session_settings::active_seeds)
        .def_readwrite("active_limit", &session_settings::active_limit)
        .def_readwrite("auto_manage_prefer_seeds", &session_settings::automanaged_prefer_seeds)
        .def_readwrite("dont_count_slow_torrents", &session_settings::dont_count_slow_torrents)
        .def_readwrite("auto_manage_interval", &session_settings::auto_manage_interval)
        .def_readwrite("share_ratio_limit", &session_settings::share_ratio_limit)
        .def_readwrite("seed_time_ratio_limit", &session_settings::seed_time_ratio_limit)
        .def_readwrite("seed_time_limit", &session_settings::seed_time_limit)
        .def_readwrite("peer_turnover", &session_settings::peer_turnover)
        .def_readwrite("peer_turnover_cutoff", &session_settings::peer_turnover_cutoff)
        .def_readwrite("close_redundant_connections", &session_settings::close_redundant_connections)
        .def_readwrite("auto_scrape_interval", &session_settings::auto_scrape_interval)
        .def_readwrite("auto_scrape_min_interval", &session_settings::auto_scrape_min_interval)
        .def_readwrite("max_peerlist_size", &session_settings::max_peerlist_size)
        .def_readwrite("max_paused_peerlist_size", &session_settings::max_paused_peerlist_size)
        .def_readwrite("min_announce_interval", &session_settings::min_announce_interval)
        .def_readwrite("prioritize_partial_pieces", &session_settings::prioritize_partial_pieces)
        .def_readwrite("auto_manage_startup", &session_settings::auto_manage_startup)
        .def_readwrite("rate_limit_ip_overhead", &session_settings::rate_limit_ip_overhead)
        .def_readwrite("announce_to_all_trackers", &session_settings::announce_to_all_trackers)
        .def_readwrite("prefer_udp_trackers", &session_settings::prefer_udp_trackers)
        .def_readwrite("strict_super_seeding", &session_settings::strict_super_seeding)
        .def_readwrite("seeding_piece_quota", &session_settings::seeding_piece_quota)
        .def_readwrite("max_sparse_regions", &session_settings::max_sparse_regions)
#ifndef TORRENT_DISABLE_MLOCK
        .def_readwrite("lock_disk_cache", &session_settings::lock_disk_cache)
#endif
        .def_readwrite("max_rejects", &session_settings::max_rejects)
        .def_readwrite("recv_socket_buffer_size", &session_settings::recv_socket_buffer_size)
        .def_readwrite("send_socket_buffer_size", &session_settings::send_socket_buffer_size)
        .def_readwrite("optimize_hashing_for_speed", &session_settings::optimize_hashing_for_speed)
        .def_readwrite("file_checks_delay_per_block", &session_settings::file_checks_delay_per_block)
        .def_readwrite("disk_cache_algorithm", &session_settings::disk_cache_algorithm)
        .def_readwrite("read_cache_line_size", &session_settings::read_cache_line_size)
        .def_readwrite("write_cache_line_size", &session_settings::write_cache_line_size)
    ;

    enum_<proxy_settings::proxy_type>("proxy_type")
        .value("none", proxy_settings::none)
        .value("socks4", proxy_settings::socks4)
        .value("socks5", proxy_settings::socks5)
        .value("socks5_pw", proxy_settings::socks5_pw)
        .value("http", proxy_settings::http)
        .value("http_pw", proxy_settings::http_pw)
    ;

    enum_<session_settings::disk_cache_algo_t("disk_cache_algo_t")
        .value("lru", session_settings::disk_cache_algo_t::lru)
        .value("largest_contiguous", session_settings::disk_cache_algo_t::largest_contiguous)
    ;

    enum_<session_settings::io_buffer_mode_t("io_buffer_mode_t")
        .value("enable_os_cache", session_settings::io_buffer_mode_t::enable_os_cache)
        .value("disable_os_cache_for_aligned_files", session_settings::io_buffer_mode_t:disable_os_cache_for_aligned_files)
        .value("disable_os_cache", session_settings::io_buffer_mode_t::disable_os_cache)
    ;

    class_<proxy_settings>("proxy_settings")
        .def_readwrite("hostname", &proxy_settings::hostname)
        .def_readwrite("port", &proxy_settings::port)
        .def_readwrite("password", &proxy_settings::password)
        .def_readwrite("username", &proxy_settings::username)
        .def_readwrite("type", &proxy_settings::type)
    ;

#ifndef TORRENT_DISABLE_DHT
    class_<dht_settings>("dht_settings")
        .def_readwrite("max_peers_reply", dht_settings::max_peers_reply)
        .def_readwrite("search_branching", dht_settings::search_branching)
        .def_readwrite("service_port", dht_settings::service_port)
        .def_readwrite("max_fail_count", dht_settings::max_fail_count)
    ;
#endif

#ifndef TORRENT_DISABLE_ENCRYPTION
    enum_<pe_settings::enc_policy>("enc_policy")
        .value("forced", pe_settings::forced)
        .value("enabled", pe_settings::enabled)
        .value("disabled", pe_settings::disabled)
    ;

    enum_<pe_settings::enc_level>("enc_level")
        .value("rc4", pe_settings::rc4)
        .value("plaintext", pe_settings::plaintext)
        .value("both", pe_settings::both)
    ;

    class_<pe_settings>("pe_settings")
        .def_readwrite("out_enc_policy", &pe_settings::out_enc_policy)
        .def_readwrite("in_enc_policy", &pe_settings::in_enc_policy)
        .def_readwrite("allowed_enc_level", &pe_settings::allowed_enc_level)
        .def_readwrite("prefer_rc4", &pe_settings::prefer_rc4)
    ;
#endif

}
<commit_msg>Fix typo<commit_after>// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <boost/python.hpp>
#include <libtorrent/session.hpp>

using namespace boost::python;
using namespace libtorrent;

void bind_session_settings()
{
    class_<session_settings>("session_settings")
        .def_readwrite("user_agent", &session_settings::user_agent)
        .def_readwrite("tracker_completion_timeout", &session_settings::tracker_completion_timeout)
        .def_readwrite("tracker_receive_timeout", &session_settings::tracker_receive_timeout)
        .def_readwrite("stop_tracker_timeout", &session_settings::stop_tracker_timeout)
        .def_readwrite("tracker_maximum_response_length", &session_settings::tracker_maximum_response_length)
        .def_readwrite("piece_timeout", &session_settings::piece_timeout)
        .def_readwrite("request_timeout", &session_settings::request_timeout)
        .def_readwrite("request_queue_time", &session_settings::request_queue_time)
        .def_readwrite("max_allowed_in_request_queue", &session_settings::max_allowed_in_request_queue)
        .def_readwrite("max_out_request_queue", &session_settings::max_out_request_queue)
        .def_readwrite("whole_pieces_threshold", &session_settings::whole_pieces_threshold)
        .def_readwrite("peer_timeout", &session_settings::peer_timeout)
        .def_readwrite("urlseed_timeout", &session_settings::urlseed_timeout)
        .def_readwrite("urlseed_pipeline_size", &session_settings::urlseed_pipeline_size)
        .def_readwrite("urlseed_wait_retry", &session_settings::urlseed_wait_retry)
        .def_readwrite("file_pool_size", &session_settings::file_pool_size)
        .def_readwrite("allow_multiple_connections_per_ip", &session_settings::allow_multiple_connections_per_ip)
        .def_readwrite("max_failcount", &session_settings::max_failcount)
        .def_readwrite("min_reconnect_time", &session_settings::min_reconnect_time)
        .def_readwrite("peer_connect_timeout", &session_settings::peer_connect_timeout)
        .def_readwrite("ignore_limits_on_local_network", &session_settings::ignore_limits_on_local_network)
        .def_readwrite("connection_speed", &session_settings::connection_speed)
        .def_readwrite("send_redundant_have", &session_settings::send_redundant_have)
        .def_readwrite("lazy_bitfields", &session_settings::lazy_bitfields)
        .def_readwrite("inactivity_timeout", &session_settings::inactivity_timeout)
        .def_readwrite("unchoke_interval", &session_settings::unchoke_interval)
        .def_readwrite("optimistic_unchoke_multiplier", &session_settings::optimistic_unchoke_multiplier)
        .def_readwrite("num_want", &session_settings::num_want)
        .def_readwrite("initial_picker_threshold", &session_settings::initial_picker_threshold)
        .def_readwrite("allowed_fast_set_size", &session_settings::allowed_fast_set_size)
        .def_readwrite("max_outstanding_disk_bytes_per_connection", &session_settings::max_outstanding_disk_bytes_per_connection)
        .def_readwrite("handshake_timeout", &session_settings::handshake_timeout)
#ifndef TORRENT_DISABLE_DHT
        .def_readwrite("use_dht_as_fallback", &session_settings::use_dht_as_fallback)
#endif
        .def_readwrite("free_torrent_hashes", &session_settings::free_torrent_hashes)
        .def_readwrite("upnp_ignore_nonrouters", &session_settings::upnp_ignore_nonrouters)
        .def_readwrite("send_buffer_watermark", &session_settings::send_buffer_watermark)
        .def_readwrite("auto_upload_slots", &session_settings::auto_upload_slots)
        .def_readwrite("auto_upload_slots_rate_based", &session_settings::auto_upload_slots_rate_based)
        .def_readwrite("use_parole_mode", &session_settings::use_parole_mode)
        .def_readwrite("cache_size", &session_settings::cache_size)
        .def_readwrite("cache_buffer_chunk_size", &session_settings::cache_buffer_chunk_size)
        .def_readwrite("cache_expiry", &session_settings::cache_expiry)
        .def_readwrite("use_read_cache", &session_settings::use_read_cache)
        .def_readwrite("disk_io_write_mode", &session_settings::disk_io_write_mode)
        .def_readwrite("disk_io_read_mode", &session_settings::disk_io_read_mode)
        .def_readwrite("coalesce_reads", &session_settings::coalesce_reads)
        .def_readwrite("coalesce_writes", &session_settings:coalesce_writes)
        .def_readwrite("outgoing_ports", &session_settings::outgoing_ports)
        .def_readwrite("peer_tos", &session_settings::peer_tos)
        .def_readwrite("active_downloads", &session_settings::active_downloads)
        .def_readwrite("active_seeds", &session_settings::active_seeds)
        .def_readwrite("active_limit", &session_settings::active_limit)
        .def_readwrite("auto_manage_prefer_seeds", &session_settings::automanaged_prefer_seeds)
        .def_readwrite("dont_count_slow_torrents", &session_settings::dont_count_slow_torrents)
        .def_readwrite("auto_manage_interval", &session_settings::auto_manage_interval)
        .def_readwrite("share_ratio_limit", &session_settings::share_ratio_limit)
        .def_readwrite("seed_time_ratio_limit", &session_settings::seed_time_ratio_limit)
        .def_readwrite("seed_time_limit", &session_settings::seed_time_limit)
        .def_readwrite("peer_turnover", &session_settings::peer_turnover)
        .def_readwrite("peer_turnover_cutoff", &session_settings::peer_turnover_cutoff)
        .def_readwrite("close_redundant_connections", &session_settings::close_redundant_connections)
        .def_readwrite("auto_scrape_interval", &session_settings::auto_scrape_interval)
        .def_readwrite("auto_scrape_min_interval", &session_settings::auto_scrape_min_interval)
        .def_readwrite("max_peerlist_size", &session_settings::max_peerlist_size)
        .def_readwrite("max_paused_peerlist_size", &session_settings::max_paused_peerlist_size)
        .def_readwrite("min_announce_interval", &session_settings::min_announce_interval)
        .def_readwrite("prioritize_partial_pieces", &session_settings::prioritize_partial_pieces)
        .def_readwrite("auto_manage_startup", &session_settings::auto_manage_startup)
        .def_readwrite("rate_limit_ip_overhead", &session_settings::rate_limit_ip_overhead)
        .def_readwrite("announce_to_all_trackers", &session_settings::announce_to_all_trackers)
        .def_readwrite("prefer_udp_trackers", &session_settings::prefer_udp_trackers)
        .def_readwrite("strict_super_seeding", &session_settings::strict_super_seeding)
        .def_readwrite("seeding_piece_quota", &session_settings::seeding_piece_quota)
        .def_readwrite("max_sparse_regions", &session_settings::max_sparse_regions)
#ifndef TORRENT_DISABLE_MLOCK
        .def_readwrite("lock_disk_cache", &session_settings::lock_disk_cache)
#endif
        .def_readwrite("max_rejects", &session_settings::max_rejects)
        .def_readwrite("recv_socket_buffer_size", &session_settings::recv_socket_buffer_size)
        .def_readwrite("send_socket_buffer_size", &session_settings::send_socket_buffer_size)
        .def_readwrite("optimize_hashing_for_speed", &session_settings::optimize_hashing_for_speed)
        .def_readwrite("file_checks_delay_per_block", &session_settings::file_checks_delay_per_block)
        .def_readwrite("disk_cache_algorithm", &session_settings::disk_cache_algorithm)
        .def_readwrite("read_cache_line_size", &session_settings::read_cache_line_size)
        .def_readwrite("write_cache_line_size", &session_settings::write_cache_line_size)
    ;

    enum_<proxy_settings::proxy_type>("proxy_type")
        .value("none", proxy_settings::none)
        .value("socks4", proxy_settings::socks4)
        .value("socks5", proxy_settings::socks5)
        .value("socks5_pw", proxy_settings::socks5_pw)
        .value("http", proxy_settings::http)
        .value("http_pw", proxy_settings::http_pw)
    ;

    enum_<session_settings::disk_cache_algo_t("disk_cache_algo_t")
        .value("lru", session_settings::disk_cache_algo_t::lru)
        .value("largest_contiguous", session_settings::disk_cache_algo_t::largest_contiguous)
    ;

    enum_<session_settings::io_buffer_mode_t("io_buffer_mode_t")
        .value("enable_os_cache", session_settings::io_buffer_mode_t::enable_os_cache)
        .value("disable_os_cache_for_aligned_files", session_settings::io_buffer_mode_t:disable_os_cache_for_aligned_files)
        .value("disable_os_cache", session_settings::io_buffer_mode_t::disable_os_cache)
    ;

    class_<proxy_settings>("proxy_settings")
        .def_readwrite("hostname", &proxy_settings::hostname)
        .def_readwrite("port", &proxy_settings::port)
        .def_readwrite("password", &proxy_settings::password)
        .def_readwrite("username", &proxy_settings::username)
        .def_readwrite("type", &proxy_settings::type)
    ;

#ifndef TORRENT_DISABLE_DHT
    class_<dht_settings>("dht_settings")
        .def_readwrite("max_peers_reply", &dht_settings::max_peers_reply)
        .def_readwrite("search_branching", &dht_settings::search_branching)
        .def_readwrite("service_port", &dht_settings::service_port)
        .def_readwrite("max_fail_count", &dht_settings::max_fail_count)
    ;
#endif

#ifndef TORRENT_DISABLE_ENCRYPTION
    enum_<pe_settings::enc_policy>("enc_policy")
        .value("forced", pe_settings::forced)
        .value("enabled", pe_settings::enabled)
        .value("disabled", pe_settings::disabled)
    ;

    enum_<pe_settings::enc_level>("enc_level")
        .value("rc4", pe_settings::rc4)
        .value("plaintext", pe_settings::plaintext)
        .value("both", pe_settings::both)
    ;

    class_<pe_settings>("pe_settings")
        .def_readwrite("out_enc_policy", &pe_settings::out_enc_policy)
        .def_readwrite("in_enc_policy", &pe_settings::in_enc_policy)
        .def_readwrite("allowed_enc_level", &pe_settings::allowed_enc_level)
        .def_readwrite("prefer_rc4", &pe_settings::prefer_rc4)
    ;
#endif

}
<|endoftext|>


<commit_before>/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.

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/framework/op_registry.h"
#include "paddle/operators/math/math_function.h"

namespace paddle {
namespace operators {

using Tensor = framework::Tensor;
using LoDTensor = framework::LoDTensor;

class BipartiteMatchOp : public framework::OperatorWithKernel {
 public:
  using framework::OperatorWithKernel::OperatorWithKernel;

  void InferShape(framework::InferShapeContext* ctx) const override {
    PADDLE_ENFORCE(ctx->HasInput("DisMat"),
                   "Input(DisMat) of BipartiteMatch should not be null.");

    auto dims = ctx->GetInputDim("DisMat");
    PADDLE_ENFORCE_EQ(dims.size(), 2, "The rank of Input(DisMat) must be 2.");

    ctx->SetOutputDim("ColToRowMatchIndices", dims);
    ctx->SetOutputDim("ColToRowMatchDis", dims);
  }
};

template <typename T>
class BipartiteMatchKernel : public framework::OpKernel<T> {
 public:
  // The match_indices must be initialized to -1 at first.
  // The match_dis must be initialized to 0 at first.
  void BipartiteMatch(const Tensor& dis, int* match_indices,
                      T* match_dis) const {
    int64_t row = dis.dims()[0];
    int64_t col = dis.dims()[1];
    auto* dis_data = dis.data<T>();
    std::vector<int> row_pool;
    for (int i = 0; i < row; ++i) {
      row_pool.push_back(i);
    }
    while (row_pool.size() > 0) {
      int max_idx = -1;
      int max_row_idx = -1;
      T max_dis = -1;
      for (int64_t j = 0; j < col; ++j) {
        if (match_indices[j] != -1) {
          continue;
        }
        for (int k = 0; k < row_pool.size(); ++k) {
          int m = row_pool[k];
          // distance is 0 between m-th row and j-th column
          if (dis_data[m * col + j] < 1e-6) {
            continue;
          }
          if (dis_data[m * col + j] > max_dis) {
            max_idx = j;
            max_row_idx = m;
            max_dis = dis_data[m * col + j];
          }
        }
      }
      if (max_idx == -1) {
        // Cannot find good match.
        break;
      } else {
        PADDLE_ENFORCE_EQ(match_indices[max_idx], -1);
        match_indices[max_idx] = max_row_idx;
        match_dis[max_idx] = max_dis;
        // Erase the row index.
        row_pool.erase(
            std::find(row_pool.begin(), row_pool.end(), max_row_idx));
      }
    }
  }

  void Compute(const framework::ExecutionContext& context) const override {
    auto* dis_mat = context.Input<LoDTensor>("DisMat");
    auto* match_indices = context.Output<Tensor>("ColToRowMatchIndices");
    auto* match_dis = context.Output<Tensor>("ColToRowMatchDis");

    auto& dev_ctx = context.device_context<platform::CPUDeviceContext>();

    auto col = dis_mat->dims()[1];

    int64_t n = dis_mat->lod().size() == 0
                    ? 1
                    : static_cast<int64_t>(dis_mat->lod().back().size() - 1);
    match_indices->mutable_data<int>({n, col}, context.GetPlace());
    match_dis->mutable_data<T>({n, col}, context.GetPlace());

    math::SetConstant<platform::CPUDeviceContext, int> iset;
    iset(dev_ctx, match_indices, static_cast<int>(-1));
    math::SetConstant<platform::CPUDeviceContext, T> tset;
    tset(dev_ctx, match_dis, static_cast<T>(0));

    int* indices = match_indices->data<int>();
    T* dis = match_dis->data<T>();
    if (n == 1) {
      BipartiteMatch(*dis_mat, indices, dis);
    } else {
      auto lod = dis_mat->lod().back();
      for (size_t i = 0; i < lod.size() - 1; ++i) {
        Tensor one_ins = dis_mat->Slice(lod[i], lod[i + 1]);
        BipartiteMatch(one_ins, indices + i * col, dis + i * col);
      }
    }
  }
};

class BipartiteMatchOpMaker : public framework::OpProtoAndCheckerMaker {
 public:
  BipartiteMatchOpMaker(OpProto* proto, OpAttrChecker* op_checker)
      : OpProtoAndCheckerMaker(proto, op_checker) {
    AddInput(
        "DisMat",
        "(LoDTensor or Tensor) this input is a 2-D LoDTensor with shape "
        "[K, M]. It is pair-wise distance matrix between the entities "
        "represented by each row and each column. For example, assumed one "
        "entity is A with shape [K], another entity is B with shape [M]. The "
        "DisMat[i][j] is the distance between A[i] and B[j]. The bigger "
        "the distance is, the more similar the pairs are. Please note, "
        "This tensor can contain LoD information to represent a batch of "
        "inputs. One instance of this batch can contain different numbers of "
        "entities.");
    AddOutput("ColToRowMatchIndices",
              "(Tensor) A 2-D Tensor with shape [N, M] in int type. "
              "N is the batch size. If ColToRowMatchIndices[i][j] is -1, it "
              "means B[j] does not match any entity in i-th instance. "
              "Otherwise, it means B[j] is matched to row "
              "RowToColMatchIndices[i][j] in i-th instance. The row number of "
              "i-th instance is saved in RowToColMatchIndices[i][j].");
    AddOutput("ColToRowMatchDis",
              "(Tensor) A 2-D Tensor with shape [N, M] in float type. "
              "N is batch size. If ColToRowMatchIndices[i][j] is -1, "
              "ColToRowMatchDis[i][j] is also -1.0. Otherwise, assumed "
              "RowToColMatchIndices[i][j] = d, and the row offsets of each "
              "instance are called LoD. Then "
              "ColToRowMatchDis[i][j] = DisMat[d+LoD[i]][j]");
    AddComment(R"DOC(
This operator is a greedy bipartite matching algorithm, which is used to
obtain the matching with the (greedy) maximum distance based on the input
distance matrix. There are two outputs to save matched indices and distance.
And this operator only calculate matched indices from column to row.
A simple description, this algothrim matched the best (maximum distance)
row entity to the column entity and the matched indices are not duplicated
in each row of ColToRowMatchIndices. If the column entity is not matched
any row entity, set -1 in ColToRowMatchIndices.

Please note that the input DisMat can be LoDTensor (with LoD) or Tensor.
If LoDTensor with LoD, the height of ColToRowMatchIndices is batch size.
If Tensor, the height of ColToRowMatchIndices is 1.

)DOC");
  }
};

}  // namespace operators
}  // namespace paddle

namespace ops = paddle::operators;
REGISTER_OPERATOR(bipartite_match, ops::BipartiteMatchOp,
                  ops::BipartiteMatchOpMaker,
                  paddle::framework::EmptyGradOpMaker);
REGISTER_OP_CPU_KERNEL(bipartite_match, ops::BipartiteMatchKernel<float>,
                       ops::BipartiteMatchKernel<double>);
<commit_msg>Update some comments and add more check.<commit_after>/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.

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/framework/op_registry.h"
#include "paddle/operators/math/math_function.h"

namespace paddle {
namespace operators {

using Tensor = framework::Tensor;
using LoDTensor = framework::LoDTensor;

constexpr char kEPS = 1e-6;

class BipartiteMatchOp : public framework::OperatorWithKernel {
 public:
  using framework::OperatorWithKernel::OperatorWithKernel;

  void InferShape(framework::InferShapeContext* ctx) const override {
    PADDLE_ENFORCE(ctx->HasInput("DisMat"),
                   "Input(DisMat) of BipartiteMatch should not be null.");

    auto dims = ctx->GetInputDim("DisMat");
    PADDLE_ENFORCE_EQ(dims.size(), 2, "The rank of Input(DisMat) must be 2.");

    ctx->SetOutputDim("ColToRowMatchIndices", dims);
    ctx->SetOutputDim("ColToRowMatchDis", dims);
  }
};

template <typename T>
class BipartiteMatchKernel : public framework::OpKernel<T> {
 public:
  // The match_indices must be initialized to -1 at first.
  // The match_dist must be initialized to 0 at first.
  void BipartiteMatch(const Tensor& dist, int* match_indices,
                      T* match_dist) const {
    PADDLE_ENFORCE_EQ(dist.dims().size(), 2, "The rank of dist must be 2.");
    int64_t row = dist.dims()[0];
    int64_t col = dist.dims()[1];
    auto* dist_data = dist.data<T>();
    std::vector<int> row_pool;
    for (int i = 0; i < row; ++i) {
      row_pool.push_back(i);
    }
    while (row_pool.size() > 0) {
      int max_idx = -1;
      int max_row_idx = -1;
      T max_dist = -1;
      for (int64_t j = 0; j < col; ++j) {
        if (match_indices[j] != -1) {
          continue;
        }
        for (int k = 0; k < row_pool.size(); ++k) {
          int m = row_pool[k];
          // distance is 0 between m-th row and j-th column
          if (dist_data[m * col + j] < kEPS) {
            continue;
          }
          if (dist_data[m * col + j] > max_dist) {
            max_idx = j;
            max_row_idx = m;
            max_dist = dist_data[m * col + j];
          }
        }
      }
      if (max_idx == -1) {
        // Cannot find good match.
        break;
      } else {
        PADDLE_ENFORCE_EQ(match_indices[max_idx], -1);
        match_indices[max_idx] = max_row_idx;
        match_dist[max_idx] = max_dist;
        // Erase the row index.
        row_pool.erase(
            std::find(row_pool.begin(), row_pool.end(), max_row_idx));
      }
    }
  }

  void Compute(const framework::ExecutionContext& context) const override {
    auto* dist_mat = context.Input<LoDTensor>("DisMat");
    auto* match_indices = context.Output<Tensor>("ColToRowMatchIndices");
    auto* match_dist = context.Output<Tensor>("ColToRowMatchDis");

    auto& dev_ctx = context.device_context<platform::CPUDeviceContext>();

    auto col = dist_mat->dims()[1];

    int64_t n = dist_mat->lod().size() == 0UL
                    ? 1
                    : static_cast<int64_t>(dist_mat->lod().back().size() - 1);
    if (dist_mat->lod().size()) {
      PADDLE_ENFORCE_EQ(dist_mat->lod().size(), 1UL,
                        "Only support 1 level of LoD.");
    }
    match_indices->mutable_data<int>({n, col}, context.GetPlace());
    match_dist->mutable_data<T>({n, col}, context.GetPlace());

    math::SetConstant<platform::CPUDeviceContext, int> iset;
    iset(dev_ctx, match_indices, static_cast<int>(-1));
    math::SetConstant<platform::CPUDeviceContext, T> tset;
    tset(dev_ctx, match_dist, static_cast<T>(0));

    int* indices = match_indices->data<int>();
    T* dist = match_dist->data<T>();
    if (n == 1) {
      BipartiteMatch(*dist_mat, indices, dist);
    } else {
      auto lod = dist_mat->lod().back();
      for (size_t i = 0; i < lod.size() - 1; ++i) {
        Tensor one_ins = dist_mat->Slice(lod[i], lod[i + 1]);
        BipartiteMatch(one_ins, indices + i * col, dist + i * col);
      }
    }
  }
};

class BipartiteMatchOpMaker : public framework::OpProtoAndCheckerMaker {
 public:
  BipartiteMatchOpMaker(OpProto* proto, OpAttrChecker* op_checker)
      : OpProtoAndCheckerMaker(proto, op_checker) {
    AddInput(
        "DisMat",
        "(LoDTensor or Tensor) this input is a 2-D LoDTensor with shape "
        "[K, M]. It is pair-wise distance matrix between the entities "
        "represented by each row and each column. For example, assumed one "
        "entity is A with shape [K], another entity is B with shape [M]. The "
        "DisMat[i][j] is the distance between A[i] and B[j]. The bigger "
        "the distance is, the better macthing the pairs are. Please note, "
        "This tensor can contain LoD information to represent a batch of "
        "inputs. One instance of this batch can contain different numbers of "
        "entities.");
    AddOutput("ColToRowMatchIndices",
              "(Tensor) A 2-D Tensor with shape [N, M] in int type. "
              "N is the batch size. If ColToRowMatchIndices[i][j] is -1, it "
              "means B[j] does not match any entity in i-th instance. "
              "Otherwise, it means B[j] is matched to row "
              "ColToRowMatchIndices[i][j] in i-th instance. The row number of "
              "i-th instance is saved in ColToRowMatchIndices[i][j].");
    AddOutput("ColToRowMatchDis",
              "(Tensor) A 2-D Tensor with shape [N, M] in float type. "
              "N is batch size. If ColToRowMatchIndices[i][j] is -1, "
              "ColToRowMatchDis[i][j] is also -1.0. Otherwise, assumed "
              "ColToRowMatchIndices[i][j] = d, and the row offsets of each "
              "instance are called LoD. Then "
              "ColToRowMatchDis[i][j] = DisMat[d+LoD[i]][j]");
    AddComment(R"DOC(
This operator is a greedy bipartite matching algorithm, which is used to
obtain the matching with the maximum distance based on the input
distance matrix. For input 2D matrix, the bipartite matching algorithm can
find the matched column for each row, also can find the matched row for
each column. And this operator only calculate matched indices from column
to row. For each instance, the number of matched indices is the number of
of columns of the input ditance matrix.

There are two outputs to save matched indices and distance.
A simple description, this algothrim matched the best (maximum distance)
row entity to the column entity and the matched indices are not duplicated
in each row of ColToRowMatchIndices. If the column entity is not matched
any row entity, set -1 in ColToRowMatchIndices.

Please note that the input DisMat can be LoDTensor (with LoD) or Tensor.
If LoDTensor with LoD, the height of ColToRowMatchIndices is batch size.
If Tensor, the height of ColToRowMatchIndices is 1.

)DOC");
  }
};

}  // namespace operators
}  // namespace paddle

namespace ops = paddle::operators;
REGISTER_OPERATOR(bipartite_match, ops::BipartiteMatchOp,
                  ops::BipartiteMatchOpMaker,
                  paddle::framework::EmptyGradOpMaker);
REGISTER_OP_CPU_KERNEL(bipartite_match, ops::BipartiteMatchKernel<float>,
                       ops::BipartiteMatchKernel<double>);
<|endoftext|>


<commit_before>#pragma once

#include <iterator>

#include <cstdlib> //malloc, realloc
#include <exception> //bad_alloc
#include <utility>

#include <cassert>

namespace tyti {
template<typename T>
class any_iterator : std::iterator<std::bidirectional_iterator_tag, T>
{
    struct AbstractIterHolder
    {
        virtual ~AbstractIterHolder() {};
        virtual void inc() = 0;
        virtual void dec() = 0;
        virtual const T* deref() = 0;
        virtual bool equal_holder(const void* in) const = 0;
        virtual bool equal(const void* in) const = 0;

        virtual void copy_and_assign_to(void* dst) const = 0;
        virtual size_t holder_size() = 0;
    };

    template<typename IterT>
    struct IterHolder : public AbstractIterHolder
    {
    private:
        IterT iter_;
    public:
        IterHolder(IterT t):iter_{std::move(t)}{}
        ~IterHolder(){}
        void inc() { ++iter_; }
        void dec() { --iter_; }
        const T* deref() { return &(*iter_); }
        bool equal_holder(const void* in) const { return iter_ == reinterpret_cast<const IterHolder<IterT>*>(in)->iter_; }
        bool equal(const void* in) const { return iter_ == *reinterpret_cast<const IterT*>(in); }
        void copy_and_assign_to(void* dst) const { new (dst) IterHolder(iter_); }
        size_t holder_size() { return sizeof(IterHolder<IterT>); }
    };

    // helper functions
    inline void destruct()
    {
        ptr_->~AbstractIterHolder();
    }

    void check_allocation(size_t oldsize, size_t newsize)
    {
        if (oldsize < newsize)
        {
            ptr_ = reinterpret_cast<AbstractIterHolder*>(std::realloc(ptr_, newsize));
            if (!ptr_)
                throw std::bad_alloc();
        }
    }

    // member variables
    AbstractIterHolder* ptr_;

    /// Interface
public:
    template <typename IterType, class = typename std::enable_if<!std::is_rvalue_reference<IterType>::value>::type>
    explicit any_iterator(IterType _iter)
        : ptr_(reinterpret_cast<AbstractIterHolder*>(std::malloc(sizeof(IterHolder<IterType>))))
    {
        if (!ptr_)
            throw std::bad_alloc();
        new (ptr_) IterHolder<IterType>(std::move(_iter));
    }

    any_iterator(const any_iterator& _iter)
        : ptr_(reinterpret_cast<AbstractIterHolder*>(std::malloc(_iter.ptr_->holder_size())))
    {
        if (!ptr_)
            throw std::bad_alloc();
        _iter.ptr_->copy_and_assign_to(ptr_);
    }

    any_iterator(any_iterator&& _iter)
        :ptr_(std::move(_iter.ptr_))
    {
        _iter.ptr_ = nullptr;
    }

    template <typename IterType, class = typename std::enable_if<!std::is_rvalue_reference<IterType>::value>::type >
    const any_iterator& operator=(IterType _iter)
    {
        const size_t old_size = ptr_->holder_size();
        destruct();
        check_allocation(old_size, sizeof(IterHolder<IterType>));
        new (ptr_) IterHolder<IterType>(std::move(_iter));
        return *this;
    }

    const any_iterator& operator=(const any_iterator& _iter)
    {
        const size_t old_size = ptr_->holder_size();
        destruct();
        check_allocation(old_size, _iter.ptr_->holder_size());
        _iter.ptr_->copy_and_assign_to(ptr_);
        return *this;
    }

    const any_iterator& operator=(any_iterator&& _iter)
    {
        std::swap(ptr_, _iter.ptr_);
        //old ptr gets destructed via _iter
        return *this;
    }

    ~any_iterator()
    {
        if (ptr_)
        {
            destruct();
            std::free(ptr_);
        }
    }

    bool operator==(const any_iterator& _rhs) const
    {
        if (typeid(*ptr_) != typeid(*_rhs.ptr_)) //different types
            return false;
        return ptr_->equal_holder(_rhs.ptr_);
    }

    template <typename IterType>
    bool operator==(const IterType& _rhs) const {
        return ptr_->equal(reinterpret_cast<const void*>(&_rhs));
    }

    template <typename IterType>
    bool operator!=(const IterType& _rhs) const{
        return !operator==(_rhs);
    }

    /// Standard pre-increment operator
    any_iterator& operator++() {
        ptr_->inc();
        return *this;
    }

    /// Standard post-increment operator
    any_iterator operator++(int) {
        any_iterator cpy(*this);
        ptr_->inc();
        return cpy;
    }

    /// Standard pre-decrement operator
    any_iterator& operator--() {
        ptr_->dec();
        return *this;
    }

    /// Standard post-decrement operator
    any_iterator operator--(int) {
        any_iterator cpy(*this);
        ptr_->dec();
        return cpy;
    }

    const T& operator*() const {
        return *ptr_->deref();
    }

    /// Standard pointer operator.
    const T* operator->() const {
        return ptr_->deref();
    }
};

} // end namespace tyti

template<typename IterT, typename T>
bool operator==(const IterT&& _lhs, const tyti::any_iterator<T>&& _rhs)
{
    return _rhs.operator==(std::forward<IterT>(_lhs));
}

template<typename IterT, typename T>
bool operator!=(IterT&& _lhs, tyti::any_iterator<T>&& _rhs)
{
    return _rhs.operator!=(std::forward<IterT>(_lhs));
}<commit_msg>non const deref<commit_after>#pragma once

#include <iterator>

#include <cstdlib> //malloc, realloc
#include <exception> //bad_alloc
#include <utility>

#include <cassert>

namespace tyti {
template<typename T>
class any_iterator : std::iterator<std::bidirectional_iterator_tag, T>
{
    struct AbstractIterHolder
    {
        virtual ~AbstractIterHolder() {};
        virtual void inc() = 0;
        virtual void dec() = 0;
        virtual T* deref() = 0;
        virtual bool equal_holder(const void* in) const = 0;
        virtual bool equal(const void* in) const = 0;

        virtual void copy_and_assign_to(void* dst) const = 0;
        virtual size_t holder_size() = 0;
    };

    template<typename IterT>
    struct IterHolder : public AbstractIterHolder
    {
    private:
        IterT iter_;
    public:
        IterHolder(IterT t):iter_{std::move(t)}{}
        ~IterHolder(){}
        void inc() { ++iter_; }
        void dec() { --iter_; }
        T* deref() { return &(*iter_); }
        bool equal_holder(const void* in) const { return iter_ == reinterpret_cast<const IterHolder<IterT>*>(in)->iter_; }
        bool equal(const void* in) const { return iter_ == *reinterpret_cast<const IterT*>(in); }
        void copy_and_assign_to(void* dst) const { new (dst) IterHolder(iter_); }
        size_t holder_size() { return sizeof(IterHolder<IterT>); }
    };

    // helper functions
    inline void destruct()
    {
        ptr_->~AbstractIterHolder();
    }

    void check_allocation(size_t oldsize, size_t newsize)
    {
        if (oldsize < newsize)
        {
            ptr_ = reinterpret_cast<AbstractIterHolder*>(std::realloc(ptr_, newsize));
            if (!ptr_)
                throw std::bad_alloc();
        }
    }

    // member variables
    AbstractIterHolder* ptr_;

    /// Interface
public:
    template <typename IterType, class = typename std::enable_if<!std::is_rvalue_reference<IterType>::value>::type>
    explicit any_iterator(IterType _iter)
        : ptr_(reinterpret_cast<AbstractIterHolder*>(std::malloc(sizeof(IterHolder<IterType>))))
    {
        if (!ptr_)
            throw std::bad_alloc();
        new (ptr_) IterHolder<IterType>(std::move(_iter));
    }

    any_iterator(const any_iterator& _iter)
        : ptr_(reinterpret_cast<AbstractIterHolder*>(std::malloc(_iter.ptr_->holder_size())))
    {
        if (!ptr_)
            throw std::bad_alloc();
        _iter.ptr_->copy_and_assign_to(ptr_);
    }

    any_iterator(any_iterator&& _iter)
        :ptr_(std::move(_iter.ptr_))
    {
        _iter.ptr_ = nullptr;
    }

    template <typename IterType, class = typename std::enable_if<!std::is_rvalue_reference<IterType>::value>::type >
    const any_iterator& operator=(IterType _iter)
    {
        const size_t old_size = ptr_->holder_size();
        destruct();
        check_allocation(old_size, sizeof(IterHolder<IterType>));
        new (ptr_) IterHolder<IterType>(std::move(_iter));
        return *this;
    }

    const any_iterator& operator=(const any_iterator& _iter)
    {
        const size_t old_size = ptr_->holder_size();
        destruct();
        check_allocation(old_size, _iter.ptr_->holder_size());
        _iter.ptr_->copy_and_assign_to(ptr_);
        return *this;
    }

    const any_iterator& operator=(any_iterator&& _iter)
    {
        std::swap(ptr_, _iter.ptr_);
        //old ptr gets destructed via _iter
        return *this;
    }

    ~any_iterator()
    {
        if (ptr_)
        {
            destruct();
            std::free(ptr_);
        }
    }

    bool operator==(const any_iterator& _rhs) const
    {
        if (typeid(*ptr_) != typeid(*_rhs.ptr_)) //different types
            return false;
        return ptr_->equal_holder(_rhs.ptr_);
    }

    template <typename IterType>
    bool operator==(const IterType& _rhs) const {
        return ptr_->equal(reinterpret_cast<const void*>(&_rhs));
    }

    template <typename IterType>
    bool operator!=(const IterType& _rhs) const{
        return !operator==(_rhs);
    }

    /// Standard pre-increment operator
    any_iterator& operator++() {
        ptr_->inc();
        return *this;
    }

    /// Standard post-increment operator
    any_iterator operator++(int) {
        any_iterator cpy(*this);
        ptr_->inc();
        return cpy;
    }

    /// Standard pre-decrement operator
    any_iterator& operator--() {
        ptr_->dec();
        return *this;
    }

    /// Standard post-decrement operator
    any_iterator operator--(int) {
        any_iterator cpy(*this);
        ptr_->dec();
        return cpy;
    }

    const T& operator*() const {
        return *ptr_->deref();
    }

    T& operator*() {
        return *ptr_->deref();
    }

    /// Standard pointer operator.
    const T* operator->() const {
        return ptr_->deref();
    }

    T* operator->() {
        return ptr_->deref();
    }
};

} // end namespace tyti

template<typename IterT, typename T>
bool operator==(const IterT&& _lhs, const tyti::any_iterator<T>&& _rhs)
{
    return _rhs.operator==(std::forward<IterT>(_lhs));
}

template<typename IterT, typename T>
bool operator!=(IterT&& _lhs, tyti::any_iterator<T>&& _rhs)
{
    return _rhs.operator!=(std::forward<IterT>(_lhs));
}<|endoftext|>


<commit_before>// cpsm - fuzzy path matcher
// Copyright (C) 2015 Jamie Liu
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

#define PY_SSIZE_T_CLEAN
#include <Python.h>

#include <algorithm>
#include <memory>
#include <string>

#include <boost/utility/string_ref.hpp>

#include "ctrlp_util.h"
#include "match.h"
#include "matcher.h"

namespace {

struct PyObjectDeleter {
  void operator()(PyObject* const p) const {
    Py_DECREF(p);
  }
};

// Reference-owning, self-releasing PyObject smart pointer.
typedef std::unique_ptr<PyObject, PyObjectDeleter> PyObjectPtr;

} // namespace

extern "C" {

static PyObject* cpsm_ctrlp_match(PyObject* self, PyObject* args,
                                  PyObject* kwargs) {
  static char const* kwlist[] = {"items", "query", "limit", "mmode", "ispath",
                                 "crfile", nullptr};
  PyObject* items_obj;
  char const* query_data;
  Py_ssize_t query_size;
  int limit = -1;
  char const* mmode_data = nullptr;
  Py_ssize_t mmode_size = 0;
  int is_path = 0;
  char const* cur_file_data = nullptr;
  Py_ssize_t cur_file_size = 0;
  if (!PyArg_ParseTupleAndKeywords(
          args, kwargs, "Os#|is#is#", const_cast<char**>(kwlist), &items_obj,
          &query_data, &query_size, &limit, &mmode_data, &mmode_size, &is_path,
          &cur_file_data, &cur_file_size)) {
    return nullptr;
  }

  try {
    cpsm::MatcherOpts mopts;
    mopts.cur_file = std::string(cur_file_data, cur_file_size);
    mopts.is_path = is_path;
    mopts.item_substr_fn = cpsm::match_mode_item_substr_fn(
        boost::string_ref(mmode_data, mmode_size));
    cpsm::Matcher matcher(std::string(query_data, query_size),
                          std::move(mopts));
    std::vector<cpsm::Match> matches;
    PyObjectPtr items_iter(PyObject_GetIter(items_obj));
    if (!items_iter) {
      return nullptr;
    }
    PyObjectPtr item_obj(PyIter_Next(items_iter.get()));
    while (item_obj) {
      char* item_data;
      Py_ssize_t item_size;
      if (PyString_AsStringAndSize(item_obj.get(), &item_data, &item_size) < 0) {
        return nullptr;
      }
      boost::string_ref item(item_data, item_size);
      matcher.append_match(item, matches);
      item_obj.reset(PyIter_Next(items_iter.get()));
    }
    std::sort(matches.begin(), matches.end());
    if (limit >= 0 && matches.size() > std::size_t(limit)) {
      matches.resize(limit);
    }

    PyObjectPtr matches_list(PyList_New(0));
    if (!matches_list) {
      return nullptr;
    }
    for (auto const& match : matches) {
      PyObjectPtr match_str(
          PyString_FromStringAndSize(match.item().data(), match.item().size()));
      if (!match_str) {
        return nullptr;
      }
      if (PyList_Append(matches_list.get(), match_str.get()) < 0) {
        return nullptr;
      }
    }
    return matches_list.release();
  } catch (std::exception const& ex) {
    PyErr_SetString(PyExc_RuntimeError, ex.what());
    return nullptr;
  }
}

static PyMethodDef cpsm_methods[] = {
    {"ctrlp_match", reinterpret_cast<PyCFunction>(cpsm_ctrlp_match),
     METH_VARARGS | METH_KEYWORDS,
     "Match strings with a CtrlP-compatible interface"},
    {nullptr, nullptr, 0, nullptr}};

PyMODINIT_FUNC initcpsm() {
  Py_InitModule("cpsm", cpsm_methods);
}

}
<commit_msg>Fix python_extension_main.cc license<commit_after>// cpsm - fuzzy path matcher
// Copyright (C) 2015 Jamie Liu
//
// 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.

#define PY_SSIZE_T_CLEAN
#include <Python.h>

#include <algorithm>
#include <memory>
#include <string>

#include <boost/utility/string_ref.hpp>

#include "ctrlp_util.h"
#include "match.h"
#include "matcher.h"

namespace {

struct PyObjectDeleter {
  void operator()(PyObject* const p) const {
    Py_DECREF(p);
  }
};

// Reference-owning, self-releasing PyObject smart pointer.
typedef std::unique_ptr<PyObject, PyObjectDeleter> PyObjectPtr;

} // namespace

extern "C" {

static PyObject* cpsm_ctrlp_match(PyObject* self, PyObject* args,
                                  PyObject* kwargs) {
  static char const* kwlist[] = {"items", "query", "limit", "mmode", "ispath",
                                 "crfile", nullptr};
  PyObject* items_obj;
  char const* query_data;
  Py_ssize_t query_size;
  int limit = -1;
  char const* mmode_data = nullptr;
  Py_ssize_t mmode_size = 0;
  int is_path = 0;
  char const* cur_file_data = nullptr;
  Py_ssize_t cur_file_size = 0;
  if (!PyArg_ParseTupleAndKeywords(
          args, kwargs, "Os#|is#is#", const_cast<char**>(kwlist), &items_obj,
          &query_data, &query_size, &limit, &mmode_data, &mmode_size, &is_path,
          &cur_file_data, &cur_file_size)) {
    return nullptr;
  }

  try {
    cpsm::MatcherOpts mopts;
    mopts.cur_file = std::string(cur_file_data, cur_file_size);
    mopts.is_path = is_path;
    mopts.item_substr_fn = cpsm::match_mode_item_substr_fn(
        boost::string_ref(mmode_data, mmode_size));
    cpsm::Matcher matcher(std::string(query_data, query_size),
                          std::move(mopts));
    std::vector<cpsm::Match> matches;
    PyObjectPtr items_iter(PyObject_GetIter(items_obj));
    if (!items_iter) {
      return nullptr;
    }
    PyObjectPtr item_obj(PyIter_Next(items_iter.get()));
    while (item_obj) {
      char* item_data;
      Py_ssize_t item_size;
      if (PyString_AsStringAndSize(item_obj.get(), &item_data, &item_size) < 0) {
        return nullptr;
      }
      boost::string_ref item(item_data, item_size);
      matcher.append_match(item, matches);
      item_obj.reset(PyIter_Next(items_iter.get()));
    }
    std::sort(matches.begin(), matches.end());
    if (limit >= 0 && matches.size() > std::size_t(limit)) {
      matches.resize(limit);
    }

    PyObjectPtr matches_list(PyList_New(0));
    if (!matches_list) {
      return nullptr;
    }
    for (auto const& match : matches) {
      PyObjectPtr match_str(
          PyString_FromStringAndSize(match.item().data(), match.item().size()));
      if (!match_str) {
        return nullptr;
      }
      if (PyList_Append(matches_list.get(), match_str.get()) < 0) {
        return nullptr;
      }
    }
    return matches_list.release();
  } catch (std::exception const& ex) {
    PyErr_SetString(PyExc_RuntimeError, ex.what());
    return nullptr;
  }
}

static PyMethodDef cpsm_methods[] = {
    {"ctrlp_match", reinterpret_cast<PyCFunction>(cpsm_ctrlp_match),
     METH_VARARGS | METH_KEYWORDS,
     "Match strings with a CtrlP-compatible interface"},
    {nullptr, nullptr, 0, nullptr}};

PyMODINIT_FUNC initcpsm() {
  Py_InitModule("cpsm", cpsm_methods);
}

}
<|endoftext|>


<commit_before>// Filename: ffmpegVirtualFile.cxx
// Created by: jyelon (02Jul07)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University.  All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license.  You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////

#include "pandabase.h"

#ifdef HAVE_FFMPEG

#include "config_movies.h"
#include "ffmpegVirtualFile.h"
#include "virtualFileSystem.h"

extern "C" {
  #include "libavcodec/avcodec.h"
  #include "libavformat/avformat.h"
}

#ifndef AVSEEK_SIZE
  #define AVSEEK_SIZE 0x10000
#endif

////////////////////////////////////////////////////////////////////
//     Function: FfmpegVirtualFile::Constructor
//       Access: Public
//  Description:
////////////////////////////////////////////////////////////////////
FfmpegVirtualFile::
FfmpegVirtualFile() :
  _format_context(NULL),
  _in(NULL),
  _owns_in(false)
{
}

////////////////////////////////////////////////////////////////////
//     Function: FfmpegVirtualFile::Destructor
//       Access: Public
//  Description:
////////////////////////////////////////////////////////////////////
FfmpegVirtualFile::
~FfmpegVirtualFile() {
  close();
}

////////////////////////////////////////////////////////////////////
//     Function: FfmpegVirtualFile::Copy Constructor
//       Access: Private
//  Description: These objects are not meant to be copied.
////////////////////////////////////////////////////////////////////
FfmpegVirtualFile::
FfmpegVirtualFile(const FfmpegVirtualFile &copy) {
  nassertv(false);
}

////////////////////////////////////////////////////////////////////
//     Function: FfmpegVirtualFile::Copy Assignment Operator
//       Access: Private
//  Description: These objects are not meant to be copied.
////////////////////////////////////////////////////////////////////
void FfmpegVirtualFile::
operator = (const FfmpegVirtualFile &copy) {
  nassertv(false);
}

////////////////////////////////////////////////////////////////////
//     Function: FfmpegVirtualFile::open_vfs
//       Access: Public
//  Description: Opens the movie file via Panda's VFS.  Returns true
//               on success, false on failure.  If successful, use
//               get_format_context() to get the open file handle.
////////////////////////////////////////////////////////////////////
bool FfmpegVirtualFile::
open_vfs(const Filename &filename) {
  close();

  if (ffmpeg_cat.is_debug()) {
    ffmpeg_cat.debug()
      << "ffmpeg open_vfs(" << filename << ")\n";
  }

  VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
  Filename fname = filename;
  fname.set_binary();
  PT(VirtualFile) vfile = vfs->get_file(fname);
  if (vfile == NULL) {
    return false;
  }

  _in = vfile->open_read_file(true);
  if (_in == NULL) {
    return false;
  }

  _owns_in = true;
  _start = 0;
  _size = vfile->get_file_size(_in);

  // I tried to use av_open_input_stream(), but it (a) required a lot
  // of low-level stream analysis calls that really should be
  // automatic (and are automatic in av_open_input_file()), and (b)
  // was broken on the ffmpeg build I happened to grab.  Screw it,
  // clearly av_open_input_file() is the preferred and more
  // heavily-exercised interface.  So we'll continue to use url
  // synthesis as a hacky hook into this interface.

  // Nowadays we synthesize a "url" that references this pointer.
  ostringstream strm;
  strm << "pandavfs://" << (void *)this;
  string url = strm.str();

  // Now we can open the stream.
  int result =
    av_open_input_file(&_format_context, url.c_str(), NULL, 0, NULL);
  if (result < 0) {
    close();
    return false;
  }

  return true;
}

////////////////////////////////////////////////////////////////////
//     Function: FfmpegVirtualFile::open_subfile
//       Access: Public
//  Description: Opens the movie file directly from a file on disk
//               (does not go through the VFS).  Returns true on
//               success, false on failure.  If successful, use
//               get_format_context() to get the open file handle.
////////////////////////////////////////////////////////////////////
bool FfmpegVirtualFile::
open_subfile(const SubfileInfo &info) {
  close();

  Filename fname = info.get_filename();
  fname.set_binary();
  if (!fname.open_read(_file_in)) {
    return false;
  }
  if (ffmpeg_cat.is_debug()) {
    ffmpeg_cat.debug()
      << "ffmpeg open_subfile(" << fname << ")\n";
  }

  _in = &_file_in;
  _owns_in = false;
  _start = info.get_start();
  _size = info.get_size();

  _in->seekg(_start);

  // I tried to use av_open_input_stream(), but it (a) required a lot
  // of low-level ffmpeg calls that really shouldn't be part of the
  // public API (and which aren't necessary with av_open_input_file()
  // because they happen implicitly there), and (b) was completely
  // broken on the ffmpeg build I happened to grab.  Screw it; clearly
  // av_open_input_file() is the preferred and more heavily-exercised
  // interface.  So we'll use it, even though it requires a bit of a
  // hack.

  // The hack is that we synthesize a "url" that references this
  // pointer, then open that url.  This calls pandavfs_open(), which
  // decodes the pointer and stores it for future callbacks.
  ostringstream strm;
  strm << "pandavfs://" << (void *)this;
  string url = strm.str();

  // Now we can open the stream.
  int result =
    av_open_input_file(&_format_context, url.c_str(), NULL, 0, NULL);
  if (result < 0) {
    close();
    return false;
  }

  return true;
}

////////////////////////////////////////////////////////////////////
//     Function: FfmpegVirtualFile::close
//       Access: Public
//  Description: Explicitly closes the opened file.  This is also
//               called implicitly by the destructor if necessary.
////////////////////////////////////////////////////////////////////
void FfmpegVirtualFile::
close() {
  if (_format_context != NULL) {
    av_close_input_file(_format_context);
    _format_context = NULL;
  }

  if (_owns_in) {
    nassertv(_in != NULL);
    VirtualFileSystem::close_read_file(_in);
    _owns_in = false;
  }
  _in = NULL;
}

////////////////////////////////////////////////////////////////////
//     Function: FfmpegVirtualFile::register_protocol
//       Access: Public, Static
//  Description: Should be called at startup to attach the appropriate
//               hooks between Panda and FFMpeg.
////////////////////////////////////////////////////////////////////
void FfmpegVirtualFile::
register_protocol() {
  static bool initialized = false;
  if (initialized) {
    return;
  }

  // Here's a good place to call this global ffmpeg initialization
  // function.
  av_register_all();

  // And this one.
#if LIBAVFORMAT_VERSION_INT >= 0x351400
  avformat_network_init();
#endif

  static URLProtocol protocol;
  protocol.name = "pandavfs";
  protocol.url_open  = pandavfs_open;
  protocol.url_read  = pandavfs_read;

#if LIBAVFORMAT_VERSION_INT < 3425280
  protocol.url_write = (int (*)(URLContext *, unsigned char *, int))pandavfs_write;
#else
  protocol.url_write = pandavfs_write;
#endif

  protocol.url_seek  = pandavfs_seek;
  protocol.url_close = pandavfs_close;
#if LIBAVFORMAT_VERSION_INT < 3415296
  ::register_protocol(&protocol);
#elif LIBAVFORMAT_VERSION_MAJOR < 53
  av_register_protocol(&protocol);
#else
  av_register_protocol2(&protocol, sizeof(protocol));
#endif

  // Let's also register the logging to Panda's notify callback.
  av_log_set_callback(&log_callback);
}

////////////////////////////////////////////////////////////////////
//     Function: FfmpegVirtualFile::pandavfs_open
//       Access: Private, Static
//  Description: A callback to "open" a virtual file.  Actually, all
//               this does is assign the pointer back to the
//               FfmpegVirtualFile instance.
////////////////////////////////////////////////////////////////////
int FfmpegVirtualFile::
pandavfs_open(URLContext *h, const char *filename, int flags) {
  filename += 11; // Skip over "pandavfs://"
  istringstream strm(filename);
  void *ptr = 0;
  strm >> ptr;

  FfmpegVirtualFile *self = (FfmpegVirtualFile *)ptr;
  h->priv_data = self;
  return 0;
}

////////////////////////////////////////////////////////////////////
//     Function: FfmpegVirtualFile::pandavfs_read
//       Access: Private, Static
//  Description: A callback to read a virtual file.
////////////////////////////////////////////////////////////////////
int FfmpegVirtualFile::
pandavfs_read(URLContext *h, unsigned char *buf, int size) {
  FfmpegVirtualFile *self = (FfmpegVirtualFile *)(h->priv_data);
  istream *in = self->_in;

  // Since we may be simulating a subset of the opened stream, don't
  // allow it to read past the "end".
  streampos remaining = self->_start + (streampos)self->_size - in->tellg();
  if (remaining < size) {
    if (remaining <= 0) {
      return 0;
    }

    size = (int)remaining;
  }

  in->read((char *)buf, size);
  int gc = in->gcount();
  in->clear();

  return gc;
}

////////////////////////////////////////////////////////////////////
//     Function: FfmpegVirtualFile::pandavfs_write
//       Access: Private, Static
//  Description: A callback to write a virtual file.  Unimplemented,
//               because we use ffmpeg for playback only, not for
//               encoding video streams.
////////////////////////////////////////////////////////////////////
int FfmpegVirtualFile::
pandavfs_write(URLContext *h, const unsigned char *buf, int size) {
  ffmpeg_cat.warning()
    << "ffmpeg is trying to write to the VFS.\n";
  return -1;
}

////////////////////////////////////////////////////////////////////
//     Function: FfmpegVirtualFile::pandavfs_seek
//       Access: Private, Static
//  Description: A callback to change the read position on an istream.
////////////////////////////////////////////////////////////////////
int64_t FfmpegVirtualFile::
pandavfs_seek(URLContext *h, int64_t pos, int whence) {
  FfmpegVirtualFile *self = (FfmpegVirtualFile *)(h->priv_data);
  istream *in = self->_in;

  switch(whence) {
  case SEEK_SET:
    in->seekg(self->_start + (streampos)pos, ios::beg);
    break;

  case SEEK_CUR:
    in->seekg(pos, ios::cur);
    break;

  case SEEK_END:
    // For seeks relative to the end, we actually compute the end
    // based on _start + _size, and then use ios::beg.
    in->seekg(self->_start + (streampos)self->_size + (streampos)pos, ios::beg);
    break;

  case AVSEEK_SIZE:
    return self->_size;

  default:
    ffmpeg_cat.error()
      << "Illegal parameter to seek in ffmpegVirtualFile\n";
    in->clear();
    return -1;
  }

  in->clear();
  return in->tellg() - self->_start;
}

////////////////////////////////////////////////////////////////////
//     Function: FfmpegVirtualFile::pandavfs_close
//       Access: Private, Static
//  Description: A hook to "close" a panda VFS file.  Actually it only
//               clears the associated pointer.
////////////////////////////////////////////////////////////////////
int FfmpegVirtualFile::
pandavfs_close(URLContext *h) {
  //FfmpegVirtualFile *self = (FfmpegVirtualFile *)(h->priv_data);
  h->priv_data = 0;
  return 0;
}

////////////////////////////////////////////////////////////////////
//     Function: FfmpegVirtualFile::log_callback
//       Access: Private, Static
//  Description: These callbacks are made when ffmpeg wants to write a
//               log entry; it redirects into Panda's notify.
////////////////////////////////////////////////////////////////////
void FfmpegVirtualFile::
log_callback(void *ptr, int level, const char *fmt, va_list v1) {
  NotifySeverity severity;
#ifdef AV_LOG_PANIC
  if (level <= AV_LOG_PANIC) {
    severity = NS_fatal;
  } else
#endif
  if (level <= AV_LOG_ERROR) {
    severity = NS_error;
#ifdef AV_LOG_WARNING
  } else if (level <= AV_LOG_WARNING) {
    severity = NS_warning;
#endif
  } else if (level <= AV_LOG_INFO) {
    severity = NS_info;
#ifdef AV_LOG_VERBOSE
  } else if (level <= AV_LOG_VERBOSE) {
    severity = NS_debug;
#endif
  } else /* level <= AV_LOG_DEBUG */ {
    severity = NS_spam;
  }

  if (ffmpeg_cat.is_on(severity)) {
    static const size_t buffer_size = 4096;
    char *buffer = (char *)alloca(buffer_size);
    vsnprintf(buffer, buffer_size, fmt, v1);
    nassertv(strlen(buffer) < buffer_size);
    ffmpeg_cat.out(severity, true)
      << buffer;
  }
}

#endif // HAVE_FFMPEG
<commit_msg>New ffmpeg function<commit_after>// Filename: ffmpegVirtualFile.cxx
// Created by: jyelon (02Jul07)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University.  All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license.  You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////

#include "pandabase.h"

#ifdef HAVE_FFMPEG

#include "config_movies.h"
#include "ffmpegVirtualFile.h"
#include "virtualFileSystem.h"

extern "C" {
  #include "libavcodec/avcodec.h"
  #include "libavformat/avformat.h"
}

#ifndef AVSEEK_SIZE
  #define AVSEEK_SIZE 0x10000
#endif

////////////////////////////////////////////////////////////////////
//     Function: FfmpegVirtualFile::Constructor
//       Access: Public
//  Description:
////////////////////////////////////////////////////////////////////
FfmpegVirtualFile::
FfmpegVirtualFile() :
  _format_context(NULL),
  _in(NULL),
  _owns_in(false)
{
}

////////////////////////////////////////////////////////////////////
//     Function: FfmpegVirtualFile::Destructor
//       Access: Public
//  Description:
////////////////////////////////////////////////////////////////////
FfmpegVirtualFile::
~FfmpegVirtualFile() {
  close();
}

////////////////////////////////////////////////////////////////////
//     Function: FfmpegVirtualFile::Copy Constructor
//       Access: Private
//  Description: These objects are not meant to be copied.
////////////////////////////////////////////////////////////////////
FfmpegVirtualFile::
FfmpegVirtualFile(const FfmpegVirtualFile &copy) {
  nassertv(false);
}

////////////////////////////////////////////////////////////////////
//     Function: FfmpegVirtualFile::Copy Assignment Operator
//       Access: Private
//  Description: These objects are not meant to be copied.
////////////////////////////////////////////////////////////////////
void FfmpegVirtualFile::
operator = (const FfmpegVirtualFile &copy) {
  nassertv(false);
}

////////////////////////////////////////////////////////////////////
//     Function: FfmpegVirtualFile::open_vfs
//       Access: Public
//  Description: Opens the movie file via Panda's VFS.  Returns true
//               on success, false on failure.  If successful, use
//               get_format_context() to get the open file handle.
////////////////////////////////////////////////////////////////////
bool FfmpegVirtualFile::
open_vfs(const Filename &filename) {
  close();

  if (ffmpeg_cat.is_debug()) {
    ffmpeg_cat.debug()
      << "ffmpeg open_vfs(" << filename << ")\n";
  }

  VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
  Filename fname = filename;
  fname.set_binary();
  PT(VirtualFile) vfile = vfs->get_file(fname);
  if (vfile == NULL) {
    return false;
  }

  _in = vfile->open_read_file(true);
  if (_in == NULL) {
    return false;
  }

  _owns_in = true;
  _start = 0;
  _size = vfile->get_file_size(_in);

  // I tried to use av_open_input_stream(), but it (a) required a lot
  // of low-level stream analysis calls that really should be
  // automatic (and are automatic in av_open_input_file()), and (b)
  // was broken on the ffmpeg build I happened to grab.  Screw it,
  // clearly av_open_input_file() is the preferred and more
  // heavily-exercised interface.  So we'll continue to use url
  // synthesis as a hacky hook into this interface.

  // Nowadays we synthesize a "url" that references this pointer.
  ostringstream strm;
  strm << "pandavfs://" << (void *)this;
  string url = strm.str();

  // Now we can open the stream.
  int result =
    avformat_open_input(&_format_context, url.c_str(), NULL, NULL);
  if (result < 0) {
    _format_context = NULL;
    close();
    return false;
  }

  return true;
}

////////////////////////////////////////////////////////////////////
//     Function: FfmpegVirtualFile::open_subfile
//       Access: Public
//  Description: Opens the movie file directly from a file on disk
//               (does not go through the VFS).  Returns true on
//               success, false on failure.  If successful, use
//               get_format_context() to get the open file handle.
////////////////////////////////////////////////////////////////////
bool FfmpegVirtualFile::
open_subfile(const SubfileInfo &info) {
  close();

  Filename fname = info.get_filename();
  fname.set_binary();
  if (!fname.open_read(_file_in)) {
    return false;
  }
  if (ffmpeg_cat.is_debug()) {
    ffmpeg_cat.debug()
      << "ffmpeg open_subfile(" << fname << ")\n";
  }

  _in = &_file_in;
  _owns_in = false;
  _start = info.get_start();
  _size = info.get_size();

  _in->seekg(_start);

  // I tried to use av_open_input_stream(), but it (a) required a lot
  // of low-level ffmpeg calls that really shouldn't be part of the
  // public API (and which aren't necessary with av_open_input_file()
  // because they happen implicitly there), and (b) was completely
  // broken on the ffmpeg build I happened to grab.  Screw it; clearly
  // av_open_input_file() is the preferred and more heavily-exercised
  // interface.  So we'll use it, even though it requires a bit of a
  // hack.

  // The hack is that we synthesize a "url" that references this
  // pointer, then open that url.  This calls pandavfs_open(), which
  // decodes the pointer and stores it for future callbacks.
  ostringstream strm;
  strm << "pandavfs://" << (void *)this;
  string url = strm.str();

  // Now we can open the stream.
  int result =
    avformat_open_input(&_format_context, url.c_str(), NULL, NULL);
  if (result < 0) {
    _format_context = NULL;
    close();
    return false;
  }

  return true;
}

////////////////////////////////////////////////////////////////////
//     Function: FfmpegVirtualFile::close
//       Access: Public
//  Description: Explicitly closes the opened file.  This is also
//               called implicitly by the destructor if necessary.
////////////////////////////////////////////////////////////////////
void FfmpegVirtualFile::
close() {
  if (_format_context != NULL) {
    av_close_input_file(_format_context);
    _format_context = NULL;
  }

  if (_owns_in) {
    nassertv(_in != NULL);
    VirtualFileSystem::close_read_file(_in);
    _owns_in = false;
  }
  _in = NULL;
}

////////////////////////////////////////////////////////////////////
//     Function: FfmpegVirtualFile::register_protocol
//       Access: Public, Static
//  Description: Should be called at startup to attach the appropriate
//               hooks between Panda and FFMpeg.
////////////////////////////////////////////////////////////////////
void FfmpegVirtualFile::
register_protocol() {
  static bool initialized = false;
  if (initialized) {
    return;
  }

  // Here's a good place to call this global ffmpeg initialization
  // function.
  av_register_all();

  // And this one.
#if LIBAVFORMAT_VERSION_INT >= 0x351400
  avformat_network_init();
#endif

  static URLProtocol protocol;
  protocol.name = "pandavfs";
  protocol.url_open  = pandavfs_open;
  protocol.url_read  = pandavfs_read;

#if LIBAVFORMAT_VERSION_INT < 3425280
  protocol.url_write = (int (*)(URLContext *, unsigned char *, int))pandavfs_write;
#else
  protocol.url_write = pandavfs_write;
#endif

  protocol.url_seek  = pandavfs_seek;
  protocol.url_close = pandavfs_close;
#if LIBAVFORMAT_VERSION_INT < 3415296
  ::register_protocol(&protocol);
#elif LIBAVFORMAT_VERSION_MAJOR < 53
  av_register_protocol(&protocol);
#else
  av_register_protocol2(&protocol, sizeof(protocol));
#endif

  // Let's also register the logging to Panda's notify callback.
  av_log_set_callback(&log_callback);
}

////////////////////////////////////////////////////////////////////
//     Function: FfmpegVirtualFile::pandavfs_open
//       Access: Private, Static
//  Description: A callback to "open" a virtual file.  Actually, all
//               this does is assign the pointer back to the
//               FfmpegVirtualFile instance.
////////////////////////////////////////////////////////////////////
int FfmpegVirtualFile::
pandavfs_open(URLContext *h, const char *filename, int flags) {
  filename += 11; // Skip over "pandavfs://"
  istringstream strm(filename);
  void *ptr = 0;
  strm >> ptr;

  FfmpegVirtualFile *self = (FfmpegVirtualFile *)ptr;
  h->priv_data = self;
  return 0;
}

////////////////////////////////////////////////////////////////////
//     Function: FfmpegVirtualFile::pandavfs_read
//       Access: Private, Static
//  Description: A callback to read a virtual file.
////////////////////////////////////////////////////////////////////
int FfmpegVirtualFile::
pandavfs_read(URLContext *h, unsigned char *buf, int size) {
  FfmpegVirtualFile *self = (FfmpegVirtualFile *)(h->priv_data);
  istream *in = self->_in;

  // Since we may be simulating a subset of the opened stream, don't
  // allow it to read past the "end".
  streampos remaining = self->_start + (streampos)self->_size - in->tellg();
  if (remaining < size) {
    if (remaining <= 0) {
      return 0;
    }

    size = (int)remaining;
  }

  in->read((char *)buf, size);
  int gc = in->gcount();
  in->clear();

  return gc;
}

////////////////////////////////////////////////////////////////////
//     Function: FfmpegVirtualFile::pandavfs_write
//       Access: Private, Static
//  Description: A callback to write a virtual file.  Unimplemented,
//               because we use ffmpeg for playback only, not for
//               encoding video streams.
////////////////////////////////////////////////////////////////////
int FfmpegVirtualFile::
pandavfs_write(URLContext *h, const unsigned char *buf, int size) {
  ffmpeg_cat.warning()
    << "ffmpeg is trying to write to the VFS.\n";
  return -1;
}

////////////////////////////////////////////////////////////////////
//     Function: FfmpegVirtualFile::pandavfs_seek
//       Access: Private, Static
//  Description: A callback to change the read position on an istream.
////////////////////////////////////////////////////////////////////
int64_t FfmpegVirtualFile::
pandavfs_seek(URLContext *h, int64_t pos, int whence) {
  FfmpegVirtualFile *self = (FfmpegVirtualFile *)(h->priv_data);
  istream *in = self->_in;

  switch(whence) {
  case SEEK_SET:
    in->seekg(self->_start + (streampos)pos, ios::beg);
    break;

  case SEEK_CUR:
    in->seekg(pos, ios::cur);
    break;

  case SEEK_END:
    // For seeks relative to the end, we actually compute the end
    // based on _start + _size, and then use ios::beg.
    in->seekg(self->_start + (streampos)self->_size + (streampos)pos, ios::beg);
    break;

  case AVSEEK_SIZE:
    return self->_size;

  default:
    ffmpeg_cat.error()
      << "Illegal parameter to seek in ffmpegVirtualFile\n";
    in->clear();
    return -1;
  }

  in->clear();
  return in->tellg() - self->_start;
}

////////////////////////////////////////////////////////////////////
//     Function: FfmpegVirtualFile::pandavfs_close
//       Access: Private, Static
//  Description: A hook to "close" a panda VFS file.  Actually it only
//               clears the associated pointer.
////////////////////////////////////////////////////////////////////
int FfmpegVirtualFile::
pandavfs_close(URLContext *h) {
  //FfmpegVirtualFile *self = (FfmpegVirtualFile *)(h->priv_data);
  h->priv_data = 0;
  return 0;
}

////////////////////////////////////////////////////////////////////
//     Function: FfmpegVirtualFile::log_callback
//       Access: Private, Static
//  Description: These callbacks are made when ffmpeg wants to write a
//               log entry; it redirects into Panda's notify.
////////////////////////////////////////////////////////////////////
void FfmpegVirtualFile::
log_callback(void *ptr, int level, const char *fmt, va_list v1) {
  NotifySeverity severity;
#ifdef AV_LOG_PANIC
  if (level <= AV_LOG_PANIC) {
    severity = NS_fatal;
  } else
#endif
  if (level <= AV_LOG_ERROR) {
    severity = NS_error;
#ifdef AV_LOG_WARNING
  } else if (level <= AV_LOG_WARNING) {
    severity = NS_warning;
#endif
  } else if (level <= AV_LOG_INFO) {
    severity = NS_info;
#ifdef AV_LOG_VERBOSE
  } else if (level <= AV_LOG_VERBOSE) {
    severity = NS_debug;
#endif
  } else /* level <= AV_LOG_DEBUG */ {
    severity = NS_spam;
  }

  if (ffmpeg_cat.is_on(severity)) {
    static const size_t buffer_size = 4096;
    char *buffer = (char *)alloca(buffer_size);
    vsnprintf(buffer, buffer_size, fmt, v1);
    nassertv(strlen(buffer) < buffer_size);
    ffmpeg_cat.out(severity, true)
      << buffer;
  }
}

#endif // HAVE_FFMPEG
<|endoftext|>


<commit_before>#include "datalayer.h"
#include "persons.h"
#include "sortings.h"

#include <string>
#include <vector>
#include <fstream>
#include <string>
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

DataLayer::DataLayer()
{
   // loadFromFile();
}
vector<Persons> DataLayer::getVector()
{
    return people;
}

void DataLayer::loadFromFile()
{

    Persons p;
    ifstream inStream;

    inStream.open("science.txt");

    if(!inStream.is_open())
    {
        cout << "We could not find the text file!." << endl;
    }
    if(inStream.is_open())
        cout << "Right" << endl;
    while(inStream >> p)
    {
     ///       cout << p;

        addPerson(p);

    }
    inStream.close();
 }

void DataLayer::saveToFile()
{
    fstream out;

    out.open("textFile.txt");

    for (size_t i = 0; i < people.size(); i++)
    {
        out << people[i] << endl;
    }

    out.close();
}

void DataLayer::addPerson(const Persons& p) {
    people.push_back(p);
}

void DataLayer::listPersons()
{

}

bool sortByName2(const Persons &lhs, const Persons &rhs) { return lhs.getName() < rhs.getName(); } //reyndi að nota klasaföll, en það vill þýðandinn ekki.
bool sortByGender2(const Persons &lhs, const Persons &rhs) { return lhs.getGender() < rhs.getGender(); }
bool sortByBirthYear2(const Persons &lhs, const Persons &rhs) { return lhs.getBirthYear() < rhs.getBirthYear(); }
bool sortByDeathYear2(const Persons &lhs, const Persons &rhs) { return lhs.getDeathYear() < rhs.getDeathYear(); }

void DataLayer::sortByName()
{
    sort(people.begin(), people.end(), sortByName2);
}

void DataLayer::sortByBirthYear()
{
    sort(people.begin(), people.end(), sortByBirthYear2);
}

void DataLayer::sortByDeathYear()
{
    sort(people.begin(), people.end(), sortByDeathYear2);
}

void DataLayer::sortByGender()
{
    sort(people.begin(), people.end(), sortByGender2);
}
<commit_msg>laga sma<commit_after>#include "datalayer.h"
#include "persons.h"
#include "sortings.h"

#include <string>
#include <vector>
#include <fstream>
#include <string>
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

DataLayer::DataLayer()
{
   // loadFromFile();
}
vector<Persons> DataLayer::getVector()
{
    return people;
}

void DataLayer::loadFromFile()
{

    Persons p;
    ifstream inStream;

    inStream.open("science.txt");

    if(!inStream.is_open())
    {
        cout << "We could not find the text file!." << endl;
    }

    while(inStream >> p)
    {
     ///       cout << p;

        addPerson(p);

    }
    inStream.close();
 }

void DataLayer::saveToFile()
{
    fstream out;

    out.open("textFile.txt");

    for (size_t i = 0; i < people.size(); i++)
    {
        out << people[i] << endl;
    }

    out.close();
}

void DataLayer::addPerson(const Persons& p) {
    people.push_back(p);
}

void DataLayer::listPersons()
{

}

bool sortByName2(const Persons &lhs, const Persons &rhs) { return lhs.getName() < rhs.getName(); } //reyndi að nota klasaföll, en það vill þýðandinn ekki.
bool sortByGender2(const Persons &lhs, const Persons &rhs) { return lhs.getGender() < rhs.getGender(); }
bool sortByBirthYear2(const Persons &lhs, const Persons &rhs) { return lhs.getBirthYear() < rhs.getBirthYear(); }
bool sortByDeathYear2(const Persons &lhs, const Persons &rhs) { return lhs.getDeathYear() < rhs.getDeathYear(); }

void DataLayer::sortByName()
{
    sort(people.begin(), people.end(), sortByName2);
}

void DataLayer::sortByBirthYear()
{
    sort(people.begin(), people.end(), sortByBirthYear2);
}

void DataLayer::sortByDeathYear()
{
    sort(people.begin(), people.end(), sortByDeathYear2);
}

void DataLayer::sortByGender()
{
    sort(people.begin(), people.end(), sortByGender2);
}
<|endoftext|>


<commit_before>/*
 * Copyright 2015 Cloudius Systems
 */

#include "commitlog.hh"
#include <db/commitlog/commitlog.hh>
#include "api/api-doc/commitlog.json.hh"
#include <vector>

namespace api {

void set_commitlog(http_context& ctx, routes& r) {
    httpd::commitlog_json::get_active_segment_names.set(r,
            [&ctx](std::unique_ptr<request> req) {
        auto res = make_shared<std::vector<sstring>>();
        return ctx.db.map_reduce([res](std::vector<sstring> names) {
            res->insert(res->end(), names.begin(), names.end());
        }, [](database& db) {
            if (db.commitlog() == nullptr) {
                return make_ready_future<std::vector<sstring>>(std::vector<sstring>());
            }
            return make_ready_future<std::vector<sstring>>(db.commitlog()->get_active_segment_names());
        }).then([res] {
            return make_ready_future<json::json_return_type>(*res.get());
        });
    });

    // We currently do not support archive segments
    httpd::commitlog_json::get_archiving_segment_names.set(r, [](const_req req) {
        std::vector<sstring> res;
        return res;
    });

    httpd::commitlog_json::get_completed_tasks.set(r, [](std::unique_ptr<request> req) {
        //TBD
        return make_ready_future<json::json_return_type>(0);
    });

    httpd::commitlog_json::get_pending_tasks.set(r, [](std::unique_ptr<request> req) {
        //TBD
        return make_ready_future<json::json_return_type>(0);
    });

    httpd::commitlog_json::get_total_commit_log_size.set(r, [](std::unique_ptr<request> req) {
        //TBD
        return make_ready_future<json::json_return_type>(0);
    });
}

}
<commit_msg>Commitlog API: Implement some more metrics accessors<commit_after>/*
 * Copyright 2015 Cloudius Systems
 */

#include "commitlog.hh"
#include <db/commitlog/commitlog.hh>
#include "api/api-doc/commitlog.json.hh"
#include <vector>

namespace api {

template<typename Func>
static auto acquire_cl_metric(http_context& ctx, Func&& func) {
    typedef std::result_of_t<Func(db::commitlog *)> ret_type;

    return ctx.db.map_reduce0([func = std::forward<Func>(func)](database& db) {
        if (db.commitlog() == nullptr) {
            return make_ready_future<ret_type>();
        }
        return make_ready_future<ret_type>(func(db.commitlog()));
    }, ret_type(), std::plus<ret_type>()).then([](ret_type res) {
        return make_ready_future<json::json_return_type>(res);
    });
}

void set_commitlog(http_context& ctx, routes& r) {
    httpd::commitlog_json::get_active_segment_names.set(r,
            [&ctx](std::unique_ptr<request> req) {
        auto res = make_shared<std::vector<sstring>>();
        return ctx.db.map_reduce([res](std::vector<sstring> names) {
            res->insert(res->end(), names.begin(), names.end());
        }, [](database& db) {
            if (db.commitlog() == nullptr) {
                return make_ready_future<std::vector<sstring>>(std::vector<sstring>());
            }
            return make_ready_future<std::vector<sstring>>(db.commitlog()->get_active_segment_names());
        }).then([res] {
            return make_ready_future<json::json_return_type>(*res.get());
        });
    });

    // We currently do not support archive segments
    httpd::commitlog_json::get_archiving_segment_names.set(r, [](const_req req) {
        std::vector<sstring> res;
        return res;
    });

    httpd::commitlog_json::get_completed_tasks.set(r, [&ctx](std::unique_ptr<request> req) {
        return acquire_cl_metric(ctx, std::bind(&db::commitlog::get_completed_tasks, std::placeholders::_1));
    });

    httpd::commitlog_json::get_pending_tasks.set(r, [&ctx](std::unique_ptr<request> req) {
        return acquire_cl_metric(ctx, std::bind(&db::commitlog::get_pending_tasks, std::placeholders::_1));
    });

    httpd::commitlog_json::get_total_commit_log_size.set(r, [&ctx](std::unique_ptr<request> req) {
        return acquire_cl_metric(ctx, std::bind(&db::commitlog::get_total_size, std::placeholders::_1));
    });
}

}
<|endoftext|>


<commit_before>// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.

#include "db/builder.h"

#include "db/filename.h"
#include "db/dbformat.h"
#include "db/table_cache.h"
#include "db/version_edit.h"
#include "leveldb/db.h"
#include "leveldb/env.h"
#include "leveldb/iterator.h"

namespace leveldb {

Status BuildTable(const std::string& dbname,
                  Env* env,
                  const Options& options,
                  TableCache* table_cache,
                  Iterator* iter,
                  FileMetaData* meta) {
  Status s;
  meta->file_size = 0;
  iter->SeekToFirst();

  std::string fname = TableFileName(dbname, meta->number);
  if (iter->Valid()) {
    WritableFile* file;
    s = env->NewWritableFile(fname, &file);
    if (!s.ok()) {
      return s;
    }

    TableBuilder* builder = new TableBuilder(options, file);
    meta->smallest.DecodeFrom(iter->key());
    for (; iter->Valid(); iter->Next()) {
      Slice key = iter->key();
      meta->largest.DecodeFrom(key);
      builder->Add(key, iter->value());
    }

    // Finish and check for builder errors
    if (s.ok()) {
      s = builder->Finish();
      if (s.ok()) {
        meta->file_size = builder->FileSize();
        assert(meta->file_size > 0);
      }
    } else {
      builder->Abandon();
    }
    delete builder;

    // Finish and check for file errors
    if (s.ok()) {
      s = file->Sync();
    }
    if (s.ok()) {
      s = file->Close();
    }
    delete file;
    file = NULL;

    if (s.ok()) {
      // Verify that the table is usable
      Iterator* it = table_cache->NewIterator(ReadOptions(),
                                              meta->number,
                                              meta->file_size);
      s = it->status();
      delete it;
    }
  }

  // Check for input iterator errors
  if (!iter->status().ok()) {
    s = iter->status();
  }

  if (s.ok() && meta->file_size > 0) {
    // Keep it
  } else {
    env->DeleteFile(fname);
  }
  return s;
}

}  // namespace leveldb
<commit_msg>Remove confusing and unnecessary if.<commit_after>// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.

#include "db/builder.h"

#include "db/filename.h"
#include "db/dbformat.h"
#include "db/table_cache.h"
#include "db/version_edit.h"
#include "leveldb/db.h"
#include "leveldb/env.h"
#include "leveldb/iterator.h"

namespace leveldb {

Status BuildTable(const std::string& dbname,
                  Env* env,
                  const Options& options,
                  TableCache* table_cache,
                  Iterator* iter,
                  FileMetaData* meta) {
  Status s;
  meta->file_size = 0;
  iter->SeekToFirst();

  std::string fname = TableFileName(dbname, meta->number);
  if (iter->Valid()) {
    WritableFile* file;
    s = env->NewWritableFile(fname, &file);
    if (!s.ok()) {
      return s;
    }

    TableBuilder* builder = new TableBuilder(options, file);
    meta->smallest.DecodeFrom(iter->key());
    for (; iter->Valid(); iter->Next()) {
      Slice key = iter->key();
      meta->largest.DecodeFrom(key);
      builder->Add(key, iter->value());
    }

    // Finish and check for builder errors
    s = builder->Finish();
    if (s.ok()) {
      meta->file_size = builder->FileSize();
      assert(meta->file_size > 0);
    }
    delete builder;

    // Finish and check for file errors
    if (s.ok()) {
      s = file->Sync();
    }
    if (s.ok()) {
      s = file->Close();
    }
    delete file;
    file = NULL;

    if (s.ok()) {
      // Verify that the table is usable
      Iterator* it = table_cache->NewIterator(ReadOptions(),
                                              meta->number,
                                              meta->file_size);
      s = it->status();
      delete it;
    }
  }

  // Check for input iterator errors
  if (!iter->status().ok()) {
    s = iter->status();
  }

  if (s.ok() && meta->file_size > 0) {
    // Keep it
  } else {
    env->DeleteFile(fname);
  }
  return s;
}

}  // namespace leveldb
<|endoftext|>