text:
/* CirKit: A circuit toolkit
 * Copyright (C) 2009-2015  University of Bremen
 * Copyright (C) 2015-2017  EPFL
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

/**
 * @file simulation_graph.hpp
 *
 * @brief Simulation graph
 *
 * @author Mathias Soeken
 * @since  2.0
 */

#ifndef SIMULATION_GRAPH_HPP
#define SIMULATION_GRAPH_HPP

#include <memory>
#include <unordered_map>
#include <vector>

#include <boost/dynamic_bitset.hpp>
#include <boost/format.hpp>
#include <boost/functional/hash.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/optional.hpp>
#include <boost/range/counting_range.hpp>

#include <core/properties.hpp>
#include <core/utils/bitset_utils.hpp>
#include <core/utils/graph_utils.hpp>
#include <core/utils/string_utils.hpp>
#include <classical/aig.hpp>
#include <classical/utils/unateness.hpp>

namespace boost
{

enum graph_meta_t { graph_meta };
BOOST_INSTALL_PROPERTY(graph, meta);

enum vertex_support_t { vertex_support };
BOOST_INSTALL_PROPERTY(vertex, support);

enum vertex_label_t { vertex_label };
BOOST_INSTALL_PROPERTY(vertex, label);

enum vertex_simulation_signature_t { vertex_simulation_signature };
BOOST_INSTALL_PROPERTY(vertex, simulation_signature);

enum vertex_simulation_vector_t { vertex_simulation_vector };
BOOST_INSTALL_PROPERTY(vertex, simulation_vector);

enum vertex_simulation_result_t { vertex_simulation_result };
BOOST_INSTALL_PROPERTY(vertex, simulation_result);

enum edge_label_t { edge_label };
BOOST_INSTALL_PROPERTY(edge, label);

enum edge_kind_t { edge_kind };
BOOST_INSTALL_PROPERTY(edge, kind);

}

namespace cirkit
{

using vertex_pair_t    = std::pair<unsigned, unsigned>;

namespace detail
{
  using simulation_graph_traits_t          = boost::adjacency_list_traits<boost::vecS, boost::vecS, boost::undirectedS>;
}

struct simulation_graph_meta_t
{
  unsigned num_inputs;
  unsigned num_vectors;
  unsigned num_outputs;

  std::unordered_map<aig_node, detail::simulation_graph_traits_t::vertex_descriptor> port_to_node;
};

using simulation_signature_t               = boost::optional<std::vector<unsigned>>;

/* In order to allow an O(1) lookup for edges in the graph, this
 * edge lookup table is added as a property to the simulation graph
 */
using simulation_graph_properties_t        = boost::property<boost::graph_meta_t, simulation_graph_meta_t>;

/* In order to allow an O(1) access to the vertex in- and out-degree,
 * they are stored additionally as property maps for the vertices.
 */
using simulation_graph_vertex_properties_t = boost::property<boost::vertex_in_degree_t, unsigned,
                                             boost::property<boost::vertex_out_degree_t, unsigned,
                                             boost::property<boost::vertex_support_t, boost::dynamic_bitset<>,
                                             boost::property<boost::vertex_label_t, unsigned,
                                             boost::property<boost::vertex_simulation_signature_t, simulation_signature_t,
                                             boost::property<boost::vertex_simulation_vector_t, boost::dynamic_bitset<>,
                                             boost::property<boost::vertex_simulation_result_t, boost::dynamic_bitset<>>>>>>>>;

using simulation_graph_edge_properties_t   = boost::property<boost::edge_label_t, unsigned,
                                             boost::property<boost::edge_kind_t, unate_kind>>;

using simulation_graph                     = graph_t<simulation_graph_vertex_properties_t,
                                                     simulation_graph_edge_properties_t,
                                                     simulation_graph_properties_t>;
using simulation_node                      = vertex_t<simulation_graph>;
using simulation_edge                      = edge_t<simulation_graph>;

/**
 * This function does not assign labels
 */
simulation_graph create_simulation_graph( const aig_graph& aig, const std::vector<boost::dynamic_bitset<>>& sim_vectors,
                                          const properties::ptr& settings = properties::ptr(),
                                          const properties::ptr& statistics = properties::ptr() );

/**
 * @param types The values in this array determine which k-cold and k-hot vectors should
 *              be generated.  Let j be an element in that vector, then k is obtained by
 *              k := j div 2 (where div is integer division) and the type is hot if and
 *              only if j % 2 == 1.  As an example, 2h = 5 and 1c = 2.
 * @param partition If not nullptr then the number of patterns for each selector is written into it.
 */
std::vector<boost::dynamic_bitset<>> create_simulation_vectors( unsigned width, const std::vector<unsigned>& types,
                                                                std::vector<unsigned>* partition = nullptr );

simulation_graph create_simulation_graph( const aig_graph& aig, const std::vector<unsigned>& types,
                                          const properties::ptr& settings = properties::ptr(),
                                          const properties::ptr& statistics = properties::ptr() );

std::vector<simulation_signature_t::value_type> compute_simulation_signatures( const aig_graph& aig, unsigned maxk = 2u );

/******************************************************************************
 * simulation_graph_wrapper                                                   *
 ******************************************************************************/
/**
 * If FAST_EDGE_ACCESS is defined, edge directions and edge labels are stored
 * in an adjacency matrix, which increases performance but also memory usage.
 */
//#define FAST_EDGE_ACCESS

class simulation_graph_wrapper
{
public:
  using vertex_range_t    = boost::iterator_range<boost::graph_traits<simulation_graph>::vertex_iterator>;
  using edge_range_t      = boost::iterator_range<boost::graph_traits<simulation_graph>::edge_iterator>;
  using adjacency_range_t = boost::iterator_range<boost::graph_traits<simulation_graph>::adjacency_iterator>;
  using out_edge_range_t  = boost::iterator_range<boost::graph_traits<simulation_graph>::out_edge_iterator>;
  using index_range_t     = boost::iterator_range<boost::counting_iterator<unsigned>>;

public:
  simulation_graph_wrapper( const aig_graph& g,
                            const std::vector<unsigned>& types,
                            bool support_edges,
                            const boost::optional<unsigned>& simulation_signatures );

  inline const simulation_graph& sim_graph() const                       { return graph; }

  inline unsigned num_inputs() const                                     { return boost::get_property( graph, boost::graph_meta ).num_inputs; }
  inline unsigned num_vectors() const                                    { return boost::get_property( graph, boost::graph_meta ).num_vectors; }
  inline unsigned num_outputs() const                                    { return boost::get_property( graph, boost::graph_meta ).num_outputs; }

  inline unsigned size() const                                           { return boost::num_vertices( graph ); }
  inline unsigned degree( unsigned u ) const                             { return boost::out_degree( u, graph ); }
  inline unsigned in_degree( unsigned u ) const                          { return vertex_in_degree[u]; }
  inline unsigned out_degree( unsigned u ) const                         { return vertex_out_degree[u]; }
  inline boost::dynamic_bitset<> support( unsigned u ) const             { return vertex_support[u]; }
  inline unsigned label( unsigned u ) const                              { return vertex_label[u]; }
  inline simulation_signature_t simulation_signature( unsigned u ) const { return vertex_simulation_signature[u]; }
  inline boost::dynamic_bitset<> simvector( unsigned u ) const           { return vertex_sim_vectors[u]; }
  inline std::string name( unsigned u ) const
  {
    if ( u < num_inputs() ) { return empty_default( info.node_names.at( info.inputs[u] ), boost::str( boost::format( "i%d" ) % u ) ); }
    if ( u < num_inputs() + num_vectors() ) { return to_string( vertex_sim_vectors[u] ); }

    u -= ( num_inputs() + num_vectors() );
    return empty_default( info.outputs[u].second, boost::str( boost::format( "o%d" ) % u ) );
  }

  inline unsigned port_to_node( const aig_node& port ) const             { return boost::get_property( graph, boost::graph_meta ).port_to_node.at( port ); }

  inline vertex_range_t    vertices() const              { return boost::make_iterator_range( boost::vertices( graph ) ); }
  inline edge_range_t      edges() const                 { return boost::make_iterator_range( boost::edges( graph ) ); }
  inline adjacency_range_t adjacent( unsigned u ) const  { return boost::make_iterator_range( boost::adjacent_vertices( u, graph ) ); }
  inline out_edge_range_t  out_edges( unsigned u ) const { return boost::make_iterator_range( boost::out_edges( u, graph ) ); }

  inline unsigned input_index( unsigned u )  const { return u; }
  inline unsigned vector_index( unsigned u ) const { return u - num_inputs(); }
  inline unsigned output_index( unsigned u ) const { return u - ( num_inputs() + num_vectors() ); }

  inline index_range_t input_indexes()  const { return boost::counting_range( 0u, num_inputs() ); }
  inline index_range_t vector_indexes() const { return boost::counting_range( num_inputs(), num_inputs() + num_vectors() ); }
  inline index_range_t output_indexes() const { return boost::counting_range( num_inputs() + num_vectors(), num_inputs() + num_vectors() + num_outputs() ); }

  inline simulation_node source( const simulation_edge& e ) const { return boost::source( e, graph ); }
  inline simulation_node target( const simulation_edge& e ) const { return boost::target( e, graph ); }

  void fill_neighbor_degree_sequence_out( unsigned u, std::vector<unsigned>& degrees ) const;
  void fill_neighbor_degree_sequence_all( unsigned u, std::vector<unsigned>& degrees ) const;

  void add_edge_kinds();

  inline bool is_input( unsigned u ) const  { return label( u ) == 0u; }
  inline bool is_vector( unsigned u ) const { return label( u ) > 1u;  }
  inline bool is_output( unsigned u ) const { return label( u ) == 1u; }

  inline unsigned edge_direction( unsigned u, unsigned v ) const
  {
#ifdef FAST_EDGE_ACCESS
    return vedge_direction[u][v];
#else
    const auto it = vedge_direction[u].find( v );
    return ( it == vedge_direction[u].end() ) ? 0u : it->second;
#endif
  }

  inline unsigned edge_label( unsigned u, unsigned v ) const
  {
#ifdef FAST_EDGE_ACCESS
    return vedge_label[u][v];
#else
    const auto it = vedge_label[u].find( v );
    return ( it == vedge_label[u].end() ) ? 0u : it->second;
#endif
  }

  inline unate_kind edge_kind( unsigned u, unsigned v ) const
  {
    const auto it = vedge_kind[u].find( v );
    return it->second;
  }

  void write_dot( const std::string& filename ) const;

protected:
  const aig_graph&      aig;
  const aig_graph_info& info;
  simulation_graph      graph;

  boost::property_map<simulation_graph, boost::vertex_label_t>::type                vertex_label;
  boost::property_map<simulation_graph, boost::vertex_in_degree_t>::type            vertex_in_degree;
  boost::property_map<simulation_graph, boost::vertex_out_degree_t>::type           vertex_out_degree;
  boost::property_map<simulation_graph, boost::vertex_support_t>::type              vertex_support;
  boost::property_map<simulation_graph, boost::vertex_simulation_signature_t>::type vertex_simulation_signature;
  boost::property_map<simulation_graph, boost::vertex_simulation_vector_t>::type    vertex_sim_vectors;
  boost::property_map<simulation_graph, boost::edge_label_t>::type                  medge_label;

#ifdef FAST_EDGE_ACCESS
  std::vector<std::vector<int>>                                                     vedge_label;
  std::vector<std::vector<int>>                                                     vedge_direction;
#else
  /* there is no other way right now to efficiently handle this */
  std::vector<std::unordered_map<unsigned, unsigned>>                               vedge_label;
  std::vector<std::unordered_map<unsigned, unsigned>>                               vedge_direction;
#endif
  std::vector<std::unordered_map<unsigned, unate_kind>>                             vedge_kind;
};

bool compatible_simulation_signatures( const simulation_graph_wrapper& pg, const simulation_graph_wrapper& tg,
                                       const simulation_node& u, const simulation_node& v,
                                       unsigned maxk );

}

#endif

// Local Variables:
// c-basic-offset: 2
// eval: (c-set-offset 'substatement-open 0)
// eval: (c-set-offset 'innamespace 0)
// End:

max_stars_repo_name: eletesta/cirkit

max_issues_repo_name: eletesta/cirkit

max_forks_repo_name: eletesta/cirkit


text:
#include "munin/solid_frame.hpp"
#include "munin/detail/adaptive_fill.hpp"
#include "munin/compass_layout.hpp"
#include "munin/render_surface.hpp"
#include "munin/view.hpp"
#include <boost/make_unique.hpp>

namespace munin {

// ==========================================================================
// SOLID_FRAME::IMPLEMENTATION STRUCTURE
// ==========================================================================
struct solid_frame::impl
{
    // ======================================================================
    // CONSTRUCTOR
    // ======================================================================
    explicit impl(solid_frame &self)
      : self(self)
    {
    }

    // ======================================================================
    // REDRAW_FRAME
    // ======================================================================
    void redraw_frame()
    {
        auto size = self.get_size();

        if (size.width_ > 2 && size.height_ > 2)
        {
            // Here we individually pick out the frame edges and redraw them.
            auto north_beam_region = terminalpp::rectangle{{0,0}, {size.width_, 1}};
            auto south_beam_region = terminalpp::rectangle{{0, size.height_ - 1}, {size.width_, 1}};
            auto west_beam_region  = terminalpp::rectangle{{0, 1}, {1, size.height_ - 2}};
            auto east_beam_region  = terminalpp::rectangle{{size.width_ - 1, 1}, {1, size.height_ - 2}};

            self.on_redraw({
                north_beam_region, south_beam_region, west_beam_region, east_beam_region
            });
        }
        else
        {
            // But if only our border is showing, then the redraw region is
            // the complete frame area.
            self.on_redraw({
                {{0, 0}, size}
            });
        }
    }

    solid_frame &self;
    terminalpp::attribute current_attribute;
};

// ==========================================================================
// CONSTRUCTOR
// ==========================================================================
solid_frame::solid_frame()
  : pimpl_(boost::make_unique<impl>(*this))
{
    auto &attr = pimpl_->current_attribute;

    auto north_beam = view(
        make_compass_layout(),
        detail::make_top_left_corner_fill(attr), compass_layout::heading::west,
        detail::make_horizontal_beam_fill(attr), compass_layout::heading::centre,
        detail::make_top_right_corner_fill(attr),  compass_layout::heading::east);

    auto south_beam = view(
        make_compass_layout(),
        detail::make_bottom_left_corner_fill(attr), compass_layout::heading::west,
        detail::make_horizontal_beam_fill(attr), compass_layout::heading::centre,
        detail::make_bottom_right_corner_fill(attr), compass_layout::heading::east);

    auto west_beam = detail::make_vertical_beam_fill(attr);
    auto east_beam = detail::make_vertical_beam_fill(attr);

    set_layout(make_compass_layout());

    add_component(north_beam, compass_layout::heading::north);
    add_component(south_beam, compass_layout::heading::south);
    add_component(west_beam, compass_layout::heading::west);
    add_component(east_beam, compass_layout::heading::east);
}

// ==========================================================================
// DESTRUCTOR
// ==========================================================================
solid_frame::~solid_frame()
{
}

// ==========================================================================
// NORTH_BORDER_HEIGHT
// ==========================================================================
terminalpp::coordinate_type solid_frame::north_border_height() const
{
    return 1;
}

// ==========================================================================
// SOUTH_BORDER_HEIGHT
// ==========================================================================
terminalpp::coordinate_type solid_frame::south_border_height() const
{
    return 1;
}

// ==========================================================================
// WEST_BORDER_WIDTH
// ==========================================================================
terminalpp::coordinate_type solid_frame::west_border_width() const
{
    return 1;
}

// ==========================================================================
// EAST_BORDER_WIDTH
// ==========================================================================
terminalpp::coordinate_type solid_frame::east_border_width() const
{
    return 1;
}

// ==========================================================================
// DO_TO_JSON
// ==========================================================================
nlohmann::json solid_frame::do_to_json() const
{
    nlohmann::json patch = R"([
        { "op": "replace", "path": "/type", "value": "solid_frame" }
    ])"_json;

    return composite_component::do_to_json().patch(patch);
}

// ==========================================================================
// DO_INNER_FOCUS_CHANGED
// ==========================================================================
void solid_frame::do_inner_focus_changed()
{
    pimpl_->current_attribute = get_focus_attribute();
    pimpl_->redraw_frame();
}

// ==========================================================================
// MAKE_SOLID_FRAME
// ==========================================================================
std::shared_ptr<solid_frame> make_solid_frame()
{
    return std::make_shared<solid_frame>();
}

// ==========================================================================
// MAKE_SOLID_FRAME
// ==========================================================================
std::shared_ptr<solid_frame> make_solid_frame(
    std::shared_ptr<component> const &associated_component)
{
    auto frame = make_solid_frame();
    frame->highlight_on_focus(associated_component);
    return frame;
}

}

ext: cpp

max_stars_repo_name: KazDragon/munin

max_issues_repo_name: KazDragon/munin

max_forks_repo_name: KazDragon/munin


text:
/*
 *  Copyright (c) 2015-present, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under the BSD-style license found in the
 *  LICENSE file in the root directory of this source tree. An additional grant
 *  of patent rights can be found in the PATENTS file in the same directory.
 *
 */
#include <folly/io/async/EventBase.h>
#include <folly/io/async/EventUtil.h>
#include <folly/io/async/test/MockTimeoutManager.h>
#include <folly/io/async/test/UndelayedDestruction.h>
#include <folly/io/async/test/Util.h>
#include <folly/portability/GTest.h>
#include <proxygen/lib/utils/AsyncTimeoutSet.h>
#include <boost/container/flat_map.hpp>
#include <vector>

using namespace proxygen;
using namespace testing;
using folly::AsyncTimeout;
using folly::test::MockTimeoutManager;
using std::chrono::milliseconds;

using StackTimeoutSet = folly::UndelayedDestruction<AsyncTimeoutSet>;

class MockTimeoutClock : public AsyncTimeoutSet::TimeoutClock {
 public:
  MockTimeoutClock() {
  }

  MOCK_METHOD0(millisecondsSinceEpoch, std::chrono::milliseconds());
};

class TestTimeout : public AsyncTimeoutSet::Callback {
 public:
  template<typename ...Args>
  explicit TestTimeout(Args&& ...args) {
    addTimeout(std::forward<Args>(args)...);
    _scheduleNext();
  }
  TestTimeout() {}

  void addTimeout(AsyncTimeoutSet* set) {
    nextSets_.push_back(set);
  }

  template<typename ...Args>
  void addTimeout(AsyncTimeoutSet* set, Args&& ...args) {
    addTimeout(set);
    addTimeout(std::forward<Args>(args)...);
  }

  void timeoutExpired() noexcept override {
    timestamps.emplace_back(clock_->millisecondsSinceEpoch());
    _scheduleNext();
    if (fn) {
      fn();
    }
  }

  void _scheduleNext() {
    if (nextSets_.empty()) {
      return;
    }
    AsyncTimeoutSet* nextSet = nextSets_.front();
    nextSets_.pop_front();
    nextSet->scheduleTimeout(this);
  }

  std::deque<milliseconds> timestamps;
  std::function<void()> fn;

  static void setTimeoutClock(MockTimeoutClock& clock) {
    clock_ = &clock;
  }

 private:
  static MockTimeoutClock* clock_;
  std::deque<AsyncTimeoutSet*> nextSets_;
};

MockTimeoutClock* TestTimeout::clock_ = nullptr;

class TimeoutTest : public testing::Test {
 public:

  void SetUp() override {
    TestTimeout::setTimeoutClock(timeoutClock_);
    setClock(milliseconds(0));

    EXPECT_CALL(timeoutManager_, attachTimeoutManager(_, _))
      .WillRepeatedly(Return());

    EXPECT_CALL(timeoutManager_, scheduleTimeout(_, _))
      .WillRepeatedly(Invoke([this] (AsyncTimeout* p, milliseconds t) {
            timeoutManager_.cancelTimeout(p);
            folly::event_ref_flags(p->getEvent()) |= EVLIST_TIMEOUT;
            timeouts_.emplace(t + timeoutClock_.millisecondsSinceEpoch(),
                             p);
            return true;
          }));

    EXPECT_CALL(timeoutManager_, cancelTimeout(_))
      .WillRepeatedly(Invoke([this] (AsyncTimeout* p) {
            for (auto it = timeouts_.begin(); it != timeouts_.end(); it++) {
              if (it->second == p) {
                timeouts_.erase(it);
                break;
              }
            }
          }));
  }

  void loop() {
    for (auto t = timeoutClock_.millisecondsSinceEpoch() + milliseconds(1);
         !timeouts_.empty(); t++) {
      setClock(t);
    }
  }

  void setClock(milliseconds ms) {
    EXPECT_CALL(timeoutClock_, millisecondsSinceEpoch())
      .WillRepeatedly(Return(ms));

    while (!timeouts_.empty() &&
           timeoutClock_.millisecondsSinceEpoch() >= timeouts_.begin()->first) {
      AsyncTimeout* timeout = timeouts_.begin()->second;
      timeouts_.erase(timeouts_.begin());
      folly::event_ref_flags(timeout->getEvent()) &= ~EVLIST_TIMEOUT;
      timeout->timeoutExpired();
    }
  }

 protected:
  MockTimeoutManager timeoutManager_;
  MockTimeoutClock timeoutClock_;
  boost::container::flat_multimap<milliseconds, AsyncTimeout*> timeouts_;
};

/*
 * Test firing some simple timeouts that are fired once and never rescheduled
 */
TEST_F(TimeoutTest, FireOnce) {
  StackTimeoutSet ts10(&timeoutManager_, milliseconds(10), milliseconds(0),
                       &timeoutClock_);
  StackTimeoutSet ts5(&timeoutManager_, milliseconds(5), milliseconds(0),
                      &timeoutClock_);

  const AsyncTimeoutSet::Callback* nullCallback = nullptr;
  ASSERT_EQ(ts10.front(), nullCallback);
  ASSERT_EQ(ts5.front(), nullCallback);

  TestTimeout t1;
  TestTimeout t2;
  TestTimeout t3;

  ts5.scheduleTimeout(&t1); // fires at time=5

  // tick forward to time=2 and schedule another 5ms (@7ms) and a
  // 10ms (12ms) timeout

  setClock(milliseconds(2));

  ts5.scheduleTimeout(&t2);
  ts10.scheduleTimeout(&t3);

  ASSERT_EQ(ts10.front(), &t3);
  ASSERT_EQ(ts5.front(), &t1);

  setClock(milliseconds(5));
  ASSERT_EQ(ts5.front(), &t2);

  setClock(milliseconds(7));
  ASSERT_EQ(ts5.front(), nullCallback);

  ASSERT_EQ(t1.timestamps.size(), 1);
  ASSERT_EQ(t2.timestamps.size(), 1);

  setClock(milliseconds(12));

  ASSERT_EQ(t3.timestamps.size(), 1);

  ASSERT_EQ(ts10.front(), nullCallback);

  ASSERT_EQ(t1.timestamps[0], milliseconds(5));
  ASSERT_EQ(t2.timestamps[0], milliseconds(7));
  ASSERT_EQ(t3.timestamps[0], milliseconds(12));
}

/*
 * Test some timeouts that are scheduled on one timeout set, then moved to
 * another timeout set.
 */
TEST_F(TimeoutTest, SwitchTimeoutSet) {
  StackTimeoutSet ts10(&timeoutManager_, milliseconds(10), milliseconds(0),
                       &timeoutClock_);
  StackTimeoutSet ts5(&timeoutManager_, milliseconds(5), milliseconds(0),
                      &timeoutClock_);

  TestTimeout t1(&ts5, &ts10, &ts5);
  TestTimeout t2(&ts10, &ts10, &ts5);
  TestTimeout t3(&ts5, &ts5, &ts10, &ts5);

  ts5.scheduleTimeout(&t1);

  loop();

  ASSERT_EQ(t1.timestamps.size(), 3);
  ASSERT_EQ(t2.timestamps.size(), 3);
  ASSERT_EQ(t3.timestamps.size(), 4);

  ASSERT_EQ(t1.timestamps[0], milliseconds(5));
  ASSERT_EQ(t1.timestamps[1] - t1.timestamps[0], milliseconds(10));
  ASSERT_EQ(t1.timestamps[2] - t1.timestamps[1], milliseconds(5));

  ASSERT_EQ(t2.timestamps[0], milliseconds(10));
  ASSERT_EQ(t2.timestamps[1] - t2.timestamps[0], milliseconds(10));
  ASSERT_EQ(t2.timestamps[2] - t2.timestamps[1], milliseconds(5));

  ASSERT_EQ(t3.timestamps[0], milliseconds(5));
  ASSERT_EQ(t3.timestamps[1] - t3.timestamps[0], milliseconds(5));
  ASSERT_EQ(t3.timestamps[2] - t3.timestamps[1], milliseconds(10));
  ASSERT_EQ(t3.timestamps[3] - t3.timestamps[2], milliseconds(5));
  ASSERT_EQ(timeoutClock_.millisecondsSinceEpoch(), milliseconds(25));
}

/*
 * Test cancelling a timeout when it is scheduled to be fired right away.
 */
TEST_F(TimeoutTest, CancelTimeout) {
  StackTimeoutSet ts5(&timeoutManager_, milliseconds(5), milliseconds(0),
                      &timeoutClock_);
  StackTimeoutSet ts10(&timeoutManager_, milliseconds(10), milliseconds(0),
                       &timeoutClock_);
  StackTimeoutSet ts20(&timeoutManager_, milliseconds(20), milliseconds(0),
                       &timeoutClock_);

  // Create several timeouts that will all fire in 5ms.
  TestTimeout t5_1(&ts5);
  TestTimeout t5_2(&ts5);
  TestTimeout t5_3(&ts5);
  TestTimeout t5_4(&ts5);
  TestTimeout t5_5(&ts5);

  // Also create a few timeouts to fire in 10ms
  TestTimeout t10_1(&ts10);
  TestTimeout t10_2(&ts10);
  TestTimeout t10_3(&ts10);

  TestTimeout t20_1(&ts20);
  TestTimeout t20_2(&ts20);

  // Have t5_1 cancel t5_2 and t5_4.
  //
  // Cancelling t5_2 will test cancelling a timeout that is at the head of the
  // list and ready to be fired.
  //
  // Cancelling t5_4 will test cancelling a timeout in the middle of the list
  t5_1.fn = [&] {
    t5_2.cancelTimeout();
    t5_4.cancelTimeout();
  };

  // Have t5_3 cancel t5_5.
  // This will test cancelling the last remaining timeout.
  //
  // Then have t5_3 reschedule itself.
  t5_3.fn = [&] {
    t5_5.cancelTimeout();
    // Reset our function so we won't continually reschedule ourself
    auto fn = std::move(t5_3.fn);
    ts5.scheduleTimeout(&t5_3);

    // Also test cancelling timeouts in another timeset that isn't ready to
    // fire yet.
    //
    // Cancel the middle timeout in ts10.
    t10_2.cancelTimeout();
    // Cancel both the timeouts in ts20.
    t20_1.cancelTimeout();
    t20_2.cancelTimeout();
  };

  loop();

  ASSERT_EQ(t5_1.timestamps.size(), 1);
  ASSERT_EQ(t5_1.timestamps[0], milliseconds(5));

  ASSERT_EQ(t5_3.timestamps.size(), 2);
  ASSERT_EQ(t5_3.timestamps[0], milliseconds(5));
  ASSERT_EQ(t5_3.timestamps[1] - t5_3.timestamps[0], milliseconds(5));

  ASSERT_EQ(t10_1.timestamps.size(), 1);
  ASSERT_EQ(t10_1.timestamps[0], milliseconds(10));

  ASSERT_EQ(t10_3.timestamps.size(), 1);
  ASSERT_EQ(t10_3.timestamps[0], milliseconds(10));

  // Cancelled timeouts
  ASSERT_EQ(t5_2.timestamps.size(), 0);
  ASSERT_EQ(t5_4.timestamps.size(), 0);
  ASSERT_EQ(t5_5.timestamps.size(), 0);
  ASSERT_EQ(t10_2.timestamps.size(), 0);
  ASSERT_EQ(t20_1.timestamps.size(), 0);
  ASSERT_EQ(t20_2.timestamps.size(), 0);
  ASSERT_EQ(timeoutClock_.millisecondsSinceEpoch(), milliseconds(10));
}

/*
 * Test destroying a AsyncTimeoutSet with timeouts outstanding
 */
TEST_F(TimeoutTest, DestroyTimeoutSet) {
  AsyncTimeoutSet::UniquePtr ts5(new AsyncTimeoutSet(
        &timeoutManager_, milliseconds(5), milliseconds(0), &timeoutClock_));
  AsyncTimeoutSet::UniquePtr ts10(new AsyncTimeoutSet(
        &timeoutManager_, milliseconds(10), milliseconds(0), &timeoutClock_));

  TestTimeout t5_1(ts5.get());
  TestTimeout t5_2(ts5.get());
  TestTimeout t5_3(ts5.get());

  TestTimeout t10_1(ts10.get());
  TestTimeout t10_2(ts10.get());

  // Have t5_1 destroy ts10
  t5_1.fn = [&] { ts10.reset(); };
  // Have t5_2 destroy ts5
  // Note that this will call destroy() on ts5 inside ts5's timeoutExpired()
  // method.
  t5_2.fn = [&] { ts5.reset(); };

  loop();

  ASSERT_EQ(t5_1.timestamps.size(), 1);
  ASSERT_EQ(t5_1.timestamps[0], milliseconds(5));
  ASSERT_EQ(t5_2.timestamps.size(), 1);
  ASSERT_EQ(t5_2.timestamps[0], milliseconds(5));

  ASSERT_EQ(t5_3.timestamps.size(), 0);
  ASSERT_EQ(t10_1.timestamps.size(), 0);
  ASSERT_EQ(t10_2.timestamps.size(), 0);
  ASSERT_EQ(timeoutClock_.millisecondsSinceEpoch(), milliseconds(5));
}

/*
 * Test the atMostEveryN parameter, to ensure that the timeout does not fire
 * too frequently.
 */
TEST_F(TimeoutTest, AtMostEveryN) {
  // Create a timeout set with a 25ms interval, to fire no more than once
  // every 6ms.
  milliseconds interval(25);
  milliseconds atMostEveryN(6);
  StackTimeoutSet ts25(&timeoutManager_, interval, atMostEveryN,
                       &timeoutClock_);

  // Create 60 timeouts to be added to ts25 at 1ms intervals.
  uint32_t numTimeouts = 60;
  std::vector<TestTimeout> timeouts(numTimeouts);

  // Create a scheduler timeout to add the timeouts 1ms apart.
  // Note, these will start firing partway through scheduling them
  for (uint32_t index = 0; index < numTimeouts; index++) {
    setClock(milliseconds(index));
    timeouts[index].timeoutExpired();
    ts25.scheduleTimeout(&timeouts[index]);
  }

  loop();

  // We scheduled timeouts 1ms apart, when the AsyncTimeoutSet is only allowed
  // to wake up at most once every 3ms.  It will therefore wake up every 3ms
  // and fire groups of approximately 3 timeouts at a time.
  //
  // This is "approximately 3" since it may get slightly behind and fire 4 in
  // one interval, etc.  CHECK_TIMEOUT normally allows a few milliseconds of
  // tolerance.  We have to add the same into our checking algorithm here.
  for (uint32_t idx = 0; idx < numTimeouts; ++idx) {
    ASSERT_EQ(timeouts[idx].timestamps.size(), 2);

    auto scheduledTime = timeouts[idx].timestamps[0] + interval;
    auto firedTime = timeouts[idx].timestamps[1];
    // Assert that the timeout fired at roughly the right time.
    // CHECK_TIMEOUT() normally has a tolerance of 5ms.  Allow an additional
    // atMostEveryN.
    milliseconds tolerance = atMostEveryN;
    ASSERT_GE(firedTime, scheduledTime);
    ASSERT_LT(firedTime, scheduledTime + tolerance);

    // Assert that the difference between the previous timeout and now was
    // either very small (fired in the same event loop), or larger than
    // atMostEveryN.
    if (idx == 0) {
      // no previous value
      continue;
    }
    auto prev = timeouts[idx - 1].timestamps[1];

    auto delta = firedTime - prev;
    if (delta >= milliseconds(1)) {
      ASSERT_GE(delta, atMostEveryN);
    }
  }
  ASSERT_LE(timeoutClock_.millisecondsSinceEpoch(),
            milliseconds(numTimeouts) + interval + atMostEveryN);
}

max_stars_repo_name: jiephe/proxygen

max_issues_repo_name: jiephe/proxygen

max_forks_repo_name: jiephe/proxygen


text:
/*
 * Copyright 2021 Assured Information Security, Inc.
 *
 * 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 "UNICODE_STRING_IMPL.hh"
#include "core/event/EventImpl.hh"

#include <introvirt/core/exception/BufferTooSmallException.hh>
#include <introvirt/windows/WindowsGuest.hh>
#include <introvirt/windows/kernel/nt/NtKernel.hh>

#include <boost/algorithm/string/predicate.hpp>
#include <boost/locale.hpp>

#include <utility>

namespace introvirt {
namespace windows {
namespace nt {

template <typename PtrType>
uint16_t UNICODE_STRING_IMPL<PtrType>::Length() const {
    return header_->Length;
}

template <typename PtrType>
void UNICODE_STRING_IMPL<PtrType>::Length(uint16_t Length) {
    buffer_.reset();
    header_->Length = Length;
    invalidate();
}

template <typename PtrType>
uint16_t UNICODE_STRING_IMPL<PtrType>::MaximumLength() const {
    return header_->MaximumLength;
}

template <typename PtrType>
void UNICODE_STRING_IMPL<PtrType>::MaximumLength(uint16_t MaximumLength) {
    header_->MaximumLength = MaximumLength;
    invalidate();
}

template <typename PtrType>
GuestVirtualAddress UNICODE_STRING_IMPL<PtrType>::BufferAddress() const {
    // The bottom bit in the Buffer address is a signal of some kind
    // We need to mask that off to map it correctly
    return gva_.create(header_->Buffer & 0xFFFFFFFFFFFFFFFELL);
}

template <typename PtrType>
void UNICODE_STRING_IMPL<PtrType>::BufferAddress(const GuestVirtualAddress& pBufferAddress) {
    buffer_.reset();
    header_->Buffer = pBufferAddress.virtual_address();
    invalidate();
}

template <typename PtrType>
const uint8_t* UNICODE_STRING_IMPL<PtrType>::Buffer() const {
    if (!buffer_.get() && BufferAddress() && Length()) {
        buffer_.reset(BufferAddress(), Length());
    }
    return buffer_.get();
}

template <typename PtrType>
GuestVirtualAddress UNICODE_STRING_IMPL<PtrType>::address() const {
    return gva_;
}

template <typename PtrType>
void UNICODE_STRING_IMPL<PtrType>::set(const std::u16string& value) {
    const size_t new_length = value.length() * sizeof(char16_t);

    // Does it fit into the UNICODE_STRING?
    if (unlikely(new_length > MaximumLength())) {
        throw BufferTooSmallException(new_length, MaximumLength());
    }

    // Does it fit into the current mapping?
    if (new_length > buffer_.length()) {
        // No, remap the buffer.
        buffer_.reset(BufferAddress(), new_length);
    }

    // Copy the data
    std::memcpy(buffer_.get(), value.data(), new_length);

    // Update the Length field
    Length(new_length);
}

// Guest virtual address constructor
template <typename PtrType>
UNICODE_STRING_IMPL<PtrType>::UNICODE_STRING_IMPL(const GuestVirtualAddress& gva)
    : gva_(gva), header_(gva) {}

template <typename PtrType>
Json::Value UNICODE_STRING_IMPL<PtrType>::json() const {
    Json::Value result(Utf16String::json());
    result["BufferAddress"] = BufferAddress().json();
    result["Length"] = Length();
    result["MaximumLength"] = MaximumLength();
    return result;
}

template <typename PtrType>
UNICODE_STRING_IMPL<PtrType>::~UNICODE_STRING_IMPL() = default;

std::unique_ptr<UNICODE_STRING> UNICODE_STRING::make_unique(const NtKernel& kernel,
                                                            const GuestVirtualAddress& gva) {

    if (kernel.x64())
        return std::make_unique<UNICODE_STRING_IMPL<uint64_t>>(gva);
    else
        return std::make_unique<UNICODE_STRING_IMPL<uint32_t>>(gva);
}

template class UNICODE_STRING_IMPL<uint32_t>;
template class UNICODE_STRING_IMPL<uint64_t>;

} /* namespace nt */
} /* namespace windows */

namespace inject {

GuestAllocation<windows::nt::UNICODE_STRING>::GuestAllocation(const std::string& value)
    : GuestAllocation(value, value.length() * sizeof(char16_t)) {}

GuestAllocation<windows::nt::UNICODE_STRING>::GuestAllocation(const std::string& value,
                                                              unsigned int MaximumLength) {

    using namespace windows::nt;

    auto& domain = Domain::thread_local_domain();
    auto* guest = static_cast<windows::WindowsGuest*>(domain.guest());
    assert(guest != nullptr);
    auto& kernel = guest->kernel();

    // Get the size required for the structure
    const size_t structure_size = (kernel.x64()) ? sizeof(structs::_UNICODE_STRING<uint64_t>)
                                                 : sizeof(structs::_UNICODE_STRING<uint32_t>);

    // Allocate memory for the size of the structure plus the size of the string
    buffer_.emplace(structure_size + MaximumLength);

    // Figure out the buffer address
    GuestVirtualAddress BufferAddress = buffer_->address() + structure_size;

    // Create the string
    value_ = UNICODE_STRING::make_unique(kernel, *buffer_);
    value_->Length(value.length());
    value_->MaximumLength(MaximumLength);
    value_->BufferAddress(BufferAddress);

    value_->set(value);
}

} /* namespace inject */
} /* namespace introvirt */

ext: cc

max_stars_repo_name: srpape/IntroVirt

max_issues_repo_name: srpape/IntroVirt

max_forks_repo_name: srpape/IntroVirt


text:
#pragma once

#include "BMP180.hpp"

#include <boost/endian/arithmetic.hpp>
#include <limits>

namespace icarus
{
    namespace registers::bmp180
    {
        struct Callibration
        {
            enum { address = 0xAA };

            boost::endian::big_int16_t ac1, ac2, ac3;
            boost::endian::big_uint16_t ac4, ac5, ac6;
            boost::endian::big_int16_t b1, b2, mb, mc, md;
        };

        enum class MeasurementControl : uint8_t
        {
            pressure = 0b10100,
            temperature = 0b01110,
        };

        enum class Oversampling : uint8_t
        {
            times1,
            times2,
            times4,
            times8,
        };

        struct Control
        {
            enum { address = 0xF4 };
            MeasurementControl measurementControl : 5;
            bool startOfConversion : 1;
            Oversampling oversampling : 2;
        };

        struct TemperatureReading
        {
            enum { address = 0xF6 };
            boost::endian::big_uint16_t temperature;
        };

        struct PressureReading
        {
            enum { address = 0xF6 };
            boost::endian::big_uint24_t pressure;
        };

        struct ChipId
        {
            enum { address = 0xD0 };
            uint8_t id;
        };
    }

    template<typename RegisterBank>
    BMP180<RegisterBank>::BMP180(RegisterBank * device) :
        mDevice(device),
        mPeriodsToTemperatureUpdate(0),
        mTemperature(std::numeric_limits<float>::quiet_NaN()),
        mPressure(std::numeric_limits<float>::quiet_NaN())
    {}

    template<typename RegisterBank>
    void BMP180<RegisterBank>::initialize()
    {
        using namespace registers::bmp180;

        mDevice->template read<ChipId>([](auto & reg){
            if (reg.id != 0x55) {
                throw std::runtime_error("Unrecognized bmp180 ID");
            }
        });

        mDevice->template read<Callibration>([this](auto const & cal) {
            mCallibration.ac1 = cal.ac1;
            mCallibration.ac2 = cal.ac2;
            mCallibration.ac3 = cal.ac3;
            mCallibration.ac4 = cal.ac4;
            mCallibration.ac5 = cal.ac5;
            mCallibration.ac6 = cal.ac6;
            mCallibration.b1 = cal.b1;
            mCallibration.b2 = cal.b2;
            mCallibration.mb = cal.mb;
            mCallibration.mc = cal.mc;
            mCallibration.md = cal.md;
        });

        startTemperatureRead();
    }

    template<typename RegisterBank>
    void BMP180<RegisterBank>::read()
    {
        if (mPeriodsToTemperatureUpdate == 0) {
            readTemperature();
            mPeriodsToTemperatureUpdate = 20;
        } else {
            readPressure();
        }

        --mPeriodsToTemperatureUpdate;

        if (mPeriodsToTemperatureUpdate == 0) {
            startTemperatureRead();
        } else {
            startPressureRead();
        }
    }

    template<typename RegisterBank>
    void BMP180<RegisterBank>::startTemperatureRead()
    {
        using namespace registers::bmp180;

        mDevice->template write<Control>([this](auto & reg) {
            reg.measurementControl = MeasurementControl::temperature;
            reg.oversampling = Oversampling::times1;
            reg.startOfConversion = true;
        });
    }

    template<typename RegisterBank>
    void BMP180<RegisterBank>::readTemperature()
    {
        mDevice->template read<registers::bmp180::TemperatureReading>([this](auto const & reg) {
            int32_t t = reg.temperature;
            int32_t x1 = ((t - int32_t(mCallibration.ac6)) * int32_t(mCallibration.ac5)) >> 15;
            int32_t x2 = (int32_t(mCallibration.mc) << 11) / (x1 + int32_t(mCallibration.md));
            mB5 = x1 + x2;
            mTemperature = float(mB5 + 8) / (10 << 4) + 273.15;
        });
    }

    template<typename RegisterBank>
    void BMP180<RegisterBank>::startPressureRead()
    {
        using namespace registers::bmp180;

        mDevice->template write<Control>([this](auto & reg) {
            reg.measurementControl = MeasurementControl::pressure;
            reg.oversampling = Oversampling::times2;
            reg.startOfConversion = true;
        });
    }

    template<typename RegisterBank>
    void BMP180<RegisterBank>::readPressure()
    {
        using namespace registers::bmp180;

        mDevice->template read<PressureReading>([this](auto const & reg) {
            // BEWARE!! Here be dragons
            // The following piece of code is based on BMP180 datasheet
            constexpr uint32_t oss = 1;
            uint32_t up = uint32_t(reg.pressure) >> (8 - oss);
            int32_t b6 = mB5 - 4000;
            int32_t x1 = (int32_t(mCallibration.b2) * ((b6 * b6) >> 12)) >> 11;
            int32_t x2 = (int32_t(mCallibration.ac2) * b6) >> 11;
            int32_t x3 = x1 + x1;
            int32_t b3 = (((int32_t(mCallibration.ac1) * 4 + x3) << oss) + 2) / 4;
            x1 = (int32_t(mCallibration.ac3) * b6) >> 13;
            x2 = (int32_t(mCallibration.b1) * ((b6 *b6) >> 12)) >> 16;
            x3 = ((x1 + x2) + 2) >> 2;
            uint32_t b4 = (uint32_t(mCallibration.ac4) * uint32_t(x3 + 32768)) >> 15;
            uint32_t b7 = (up - uint32_t(b3)) * (50000 >> oss);
            uint32_t p = (b7 / b4) * 2;
            x1 = (p >> 8) * (p >> 8);
            x1 = (x1 * 3038) >> 16;
            x2 = (-7357 * int32_t(p)) >> 16;
            p = p + ((x1 + x2 + 3791) >> 4);
            mPressure = float(p);
        });
    }
}

ext: hpp

max_stars_repo_name: Icarus-Quadro/Icarus

max_issues_repo_name: Icarus-Quadro/Icarus

max_forks_repo_name: Icarus-Quadro/Icarus


text:
#include <omni/core/model/variable_expression.hpp>
#include <omni/core/model/meta_info.hpp>

#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_SUITE (variableExpressionTests)

BOOST_AUTO_TEST_CASE (metaInfo)
{
    using namespace omni::core::model;

    meta_info & meta = variable_expression::getStaticMetaInfo ();
    BOOST_CHECK_EQUAL (meta.getName (), "variable_expression");
    BOOST_CHECK_EQUAL (meta.getParent (), & pure_expression::getStaticMetaInfo ());
    BOOST_CHECK_EQUAL (meta.getChildCount (), 0u);
}

BOOST_AUTO_TEST_SUITE_END ();

max_stars_repo_name: daniel-kun/omni

max_issues_repo_name: daniel-kun/omni

max_forks_repo_name: daniel-kun/omni


text:
/*

Copyright (c) 2008-2013, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/
#include "setup_transfer.hpp"
#include "libtorrent/alert_types.hpp"
#include "libtorrent/session.hpp"
#include "libtorrent/hasher.hpp"
#include "libtorrent/file_pool.hpp"
#include "libtorrent/file.hpp"
#include "libtorrent/storage.hpp"
#include "libtorrent/bencode.hpp"
#include "libtorrent/create_torrent.hpp"
#include "libtorrent/thread.hpp"
#include "libtorrent/alert_types.hpp"
#include "libtorrent/file.hpp"
#include <boost/tuple/tuple.hpp>

#include "setup_transfer.hpp"

#include <iostream>

using namespace libtorrent;

int peer_disconnects = 0;

bool on_alert(alert* a)
{
	if (alert_cast<peer_disconnected_alert>(a))
		++peer_disconnects;
	else if (alert_cast<peer_error_alert>(a))
		++peer_disconnects;

	return false;
}

const int num_pieces = 9;

static sha1_hash file_hash(std::string const& name)
{
	std::vector<char> buf;
	error_code ec;
	load_file(name, buf, ec);
	if (buf.empty()) return sha1_hash(0);
	hasher h(&buf[0], buf.size());
	return h.final();
}

static char const* proxy_name[] = {"", "_socks4", "_socks5", "_socks5_pw", "_http", "_http_pw", "_i2p"};

// proxy: 0=none, 1=socks4, 2=socks5, 3=socks5_pw 4=http 5=http_pw
static void test_transfer(session& ses, boost::intrusive_ptr<torrent_info> torrent_file
	, int proxy, int port, char const* protocol, bool url_seed
	, bool chunked_encoding, bool test_ban, bool keepalive)
{
	using namespace libtorrent;

	std::string save_path = "tmp2_web_seed";
	save_path += proxy_name[proxy];

	error_code ec;
	remove_all(save_path, ec);

	static char const* test_name[] = {"no", "SOCKS4", "SOCKS5", "SOCKS5 password", "HTTP", "HTTP password"};

	fprintf(stderr, "\n\n  ==== TESTING === proxy: %s ==== protocol: %s "
		"==== seed: %s === transfer-encoding: %s === corruption: %s "
		"==== keepalive: %s\n\n\n"
		, test_name[proxy], protocol, url_seed ? "URL seed" : "HTTP seed"
		, chunked_encoding ? "chunked": "none", test_ban ? "yes" : "no"
		, keepalive ? "yes" : "no");

	proxy_settings ps;

	if (proxy)
	{
		ps.port = start_proxy(proxy);
		ps.hostname = "127.0.0.1";
		ps.username = "testuser";
		ps.password = "testpass";
		ps.type = (proxy_settings::proxy_type)proxy;
		ses.set_proxy(ps);
	}
	else
	{
		ps.port = 0;
		ps.hostname.clear();
		ps.username.clear();
		ps.password.clear();
		ps.type = proxy_settings::none;
		ses.set_proxy(ps);
	}

	add_torrent_params p;
	p.flags &= ~add_torrent_params::flag_paused;
	p.flags &= ~add_torrent_params::flag_auto_managed;
	p.ti = torrent_file;
	p.save_path = save_path;
#ifndef TORRENT_NO_DEPRECATE
	p.storage_mode = storage_mode_compact;
#endif
	torrent_handle th = ses.add_torrent(p, ec);

	std::vector<announce_entry> empty;
	th.replace_trackers(empty);

	const size_type total_size = torrent_file->total_size();

	float rate_sum = 0.f;
	float ses_rate_sum = 0.f;

	cache_status cs;

	file_storage const& fs = torrent_file->files();
	int pad_file_size = 0;
	for (int i = 0; i < fs.num_files(); ++i)
	{
		file_entry f = fs.at(i);
		if (f.pad_file) pad_file_size += f.size;
	}

	peer_disconnects = 0;

	for (int i = 0; i < 40; ++i)
	{
		torrent_status s = th.status();
		session_status ss = ses.status();
		rate_sum += s.download_payload_rate;
		ses_rate_sum += ss.payload_download_rate;

		cs = ses.get_cache_status();
		if (cs.blocks_read < 1) cs.blocks_read = 1;
		if (cs.blocks_written < 1) cs.blocks_written = 1;

		print_ses_rate(i / 10.f, &s, NULL);

		print_alerts(ses, "  >>  ses", test_ban, false, false, &on_alert);

		if (test_ban && th.url_seeds().empty() && th.http_seeds().empty())
		{
			// when we don't have any web seeds left, we know we successfully banned it
			break;
		}

		// if the web seed connection is disconnected, we're going to fail
		// the test. make sure to do so quickly
		if (keepalive && peer_disconnects >= 1) break;

		if (s.is_seeding /* && ss.download_rate == 0.f*/)
		{
			TEST_EQUAL(s.total_payload_download - s.total_redundant_bytes, total_size - pad_file_size);
			break;
		}
		test_sleep(100);
	}

	// for test_ban tests, make sure we removed
	// the url seed (i.e. banned it)
	TEST_CHECK(!test_ban || (th.url_seeds().empty() && th.http_seeds().empty()));

	if (!test_ban)
	{
		torrent_status st = th.status();
		TEST_EQUAL(st.is_seeding, true);

		if (st.is_seeding)
		{
			for (int i = 0; i < 50; ++i)
			{
				cs = ses.get_cache_status();
				if (cs.read_cache_size == 0 && cs.total_used_buffers == 0)
					break;
				fprintf(stderr, "cache_size: %d/%d\n", int(cs.read_cache_size), int(cs.total_used_buffers));
				test_sleep(100);
			}
			TEST_EQUAL(cs.read_cache_size, 0);
			TEST_EQUAL(cs.total_used_buffers, 0);
		}
	}

	std::cerr << "total_size: " << total_size
		<< " rate_sum: " << rate_sum
		<< " session_rate_sum: " << ses_rate_sum
		<< " session total download: " << ses.status().total_payload_download
		<< " torrent total download: " << th.status().total_payload_download
		<< " redundant: " << th.status().total_redundant_bytes
		<< std::endl;

	// the rates for each second should sum up to the total, with a 10% error margin
//	TEST_CHECK(fabs(rate_sum - total_size) < total_size * .1f);
//	TEST_CHECK(fabs(ses_rate_sum - total_size) < total_size * .1f);

	// if test_ban is true, we're not supposed to have completed the download
	// otherwise, we are supposed to have
	TEST_CHECK(th.status().is_seeding == !test_ban);

	if (proxy) stop_proxy(ps.port);

	ses.remove_torrent(th);

	// call this to synchronize with the network thread
	ses.status();

	print_alerts(ses, "  >>  ses", true, true, false, &on_alert, true);

	TEST_CHECK(exists(combine_path(save_path, torrent_file->files().file_path(0))) || test_ban);
	remove_all(save_path, ec);
}

// proxy: 0=none, 1=socks4, 2=socks5, 3=socks5_pw 4=http 5=http_pw
// protocol: "http" or "https"
// test_url_seed determines whether to use url-seed or http-seed
int EXPORT run_http_suite(int proxy, char const* protocol, bool test_url_seed
	, bool chunked_encoding, bool test_ban, bool keepalive, bool test_rename)
{
	using namespace libtorrent;

	std::string save_path = "web_seed";
	save_path += proxy_name[proxy];

	error_code ec;
	create_directories(combine_path(save_path, "torrent_dir"), ec);
	if (ec)
	{
		fprintf(stderr, "FAILED TO CREATE DIRECTORY: (%d) %s\n"
			, ec.value(), ec.message().c_str());
		TEST_CHECK(!ec);
		return 1;
	}

	file_storage fs;
	std::srand(10);
	int piece_size = 0x4000;
	static const int file_sizes[] =
	{ 5, 16 - 5, 16000, 17, 10, 8000, 8000, 1,1,1,1,1,100,1,1,1,1,100,1,1,1,1,1,1
		,1,1,1,1,1,1,13,65000,34,75,2,30,400,500,23000,900,43000,400,4300,6, 4};

	if (test_url_seed)
	{
		create_random_files(combine_path(save_path, "torrent_dir"), file_sizes, sizeof(file_sizes)/sizeof(file_sizes[0]));
		add_files(fs, combine_path(save_path, "torrent_dir"));
	}
	else
	{
		piece_size = 64 * 1024;
		char* random_data = (char*)malloc(64 * 1024 * num_pieces);
		std::generate(random_data, random_data + 64 * 1024 * num_pieces, random_byte);
		std::string seed_filename = combine_path(save_path, "seed");
		save_file(seed_filename.c_str(), random_data, 64 * 1024 * num_pieces);
		fs.add_file("seed", 64 * 1024 * num_pieces);
		free(random_data);
	}

	int port = start_web_server(strcmp(protocol, "https") == 0, chunked_encoding, keepalive);

	// generate a torrent with pad files to make sure they
	// are not requested web seeds
	libtorrent::create_torrent t(fs, piece_size, 0x4000, libtorrent::create_torrent::optimize
		| libtorrent::create_torrent::calculate_file_hashes);

	char tmp[512];
	if (test_url_seed)
	{
		snprintf(tmp, sizeof(tmp), ("%s://127.0.0.1:%d/" + save_path).c_str(), protocol, port);
		t.add_url_seed(tmp);
	}
	else
	{
		snprintf(tmp, sizeof(tmp), "%s://127.0.0.1:%d/%s/seed", protocol, port, save_path.c_str());
		t.add_http_seed(tmp);
	}
	fprintf(stderr, "testing: %s\n", tmp);

	for (int i = 0; i < fs.num_files(); ++i)
	{
		file_entry f = fs.at(i);
		fprintf(stderr, "  %04x: %d %s\n", int(f.offset), f.pad_file, f.path.c_str());
	}

	// calculate the hash for all pieces
	set_piece_hashes(t, save_path, ec);

	if (ec)
	{
		fprintf(stderr, "error creating hashes for test torrent: %s\n"
			, ec.message().c_str());
		TEST_CHECK(false);
		return 0;
	}

	if (test_ban)
	{
		// corrupt the files now, so that the web seed will be banned
		if (test_url_seed)
		{
			create_random_files(combine_path(save_path, "torrent_dir"), file_sizes, sizeof(file_sizes)/sizeof(file_sizes[0]));
		}
		else
		{
			piece_size = 64 * 1024;
			char* random_data = (char*)malloc(64 * 1024 * num_pieces);
			std::generate(random_data, random_data + 64 * 1024 * num_pieces, random_byte);
			save_file(combine_path(save_path, "seed").c_str(), random_data, 64 * 1024 * num_pieces);
			free(random_data);
		}
	}

	std::vector<char> buf;
	bencode(std::back_inserter(buf), t.generate());
	boost::intrusive_ptr<torrent_info> torrent_file(new torrent_info(&buf[0], buf.size(), ec));

	// no point in testing the hashes since we know the data is corrupt
	if (!test_ban)
	{
		// verify that the file hashes are correct
		for (int i = 0; i < torrent_file->num_files(); ++i)
		{
			sha1_hash h1 = torrent_file->file_at(i).filehash;
			sha1_hash h2 = file_hash(combine_path(save_path
				, torrent_file->file_at(i).path));
//			fprintf(stderr, "%s: %s == %s\n"
//				, torrent_file->file_at(i).path.c_str()
//				, to_hex(h1.to_string()).c_str(), to_hex(h2.to_string()).c_str());
			TEST_EQUAL(h1, h2);
		}
	}

	{
		session ses(fingerprint("  ", 0,0,0,0), 0);
		session_settings settings;
		settings.max_queued_disk_bytes = 256 * 1024;
		ses.set_settings(settings);
		ses.set_alert_mask(~(alert::progress_notification | alert::stats_notification));
		error_code ec;
		ses.listen_on(std::make_pair(51000, 52000), ec);
		if (ec) fprintf(stderr, "listen_on failed: %s\n", ec.message().c_str());

		test_transfer(ses, torrent_file, proxy, port, protocol, test_url_seed
			, chunked_encoding, test_ban, keepalive);

		if (test_url_seed && test_rename)
		{
			torrent_file->rename_file(0, combine_path(save_path, combine_path("torrent_dir", "renamed_test1")));
			test_transfer(ses, torrent_file, 0, port, protocol, test_url_seed
				, chunked_encoding, test_ban, keepalive);
		}
	}

	stop_web_server();
	remove_all(save_path, ec);
	return 0;
}

max_stars_repo_name: officialrafsan/POPCORNtime

max_issues_repo_name: officialrafsan/POPCORNtime

max_forks_repo_name: officialrafsan/POPCORNtime


text:
/*
 * FlipEnumerator.hpp
 *
 *  Created on: Aug 26, 2009
 *      Author: stewie
 */

#ifndef PERTURBATIONENUMERATOR_HPP_
#define PERTURBATIONENUMERATOR_HPP_

#include <cassert>
#include <cstddef>
#include <vector>
#include <algorithm>

#include <boost/type_traits/is_convertible.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/range/iterator.hpp>
#include <boost/range/iterator_range.hpp>

namespace bn {

namespace gen {

namespace detail {

template<class StateIt> class PerturbationIterator;

template<class StateIt> struct PerturbationIteratorBase {
	typedef typename boost::iterator_value<StateIt>::type value_type;
	typedef boost::iterator_adaptor<PerturbationIterator<StateIt> , StateIt,
			value_type, boost::use_default, const value_type> base;
};

/**
 * ForwardTraversal Readable Iterator.
 */
template<class StateIt> class PerturbationIterator : public PerturbationIteratorBase<
		StateIt>::base {
private:
	friend class boost::iterator_core_access;

	typedef typename PerturbationIteratorBase<StateIt>::value_type value_t;

	StateIt end;
	value_t current;
	std::vector<bool> sitesToFlip;

	value_t dereference() const {
		value_t res(current);
		typename value_t::size_type i = 0;
		for (std::vector<bool>::const_iterator it = sitesToFlip.begin(), end =
				sitesToFlip.end(); it != end; ++it, ++i) {
			if (*it)
				res.flip(i);
		}
		return res;
	}

	bool equal(const PerturbationIterator& other) const {
		return this->base_reference() == other.base_reference();
	}

	void increment() {
		if (!std::next_permutation(sitesToFlip.begin(), sitesToFlip.end()))
			ensureNotEmpty();
	}

	void ensureNotEmpty() {
		if (++this->base_reference() != end) {
			current = *(this->base_reference());
			assert(current.size() == sitesToFlip.size());
		}
	}

public:

	PerturbationIterator() {
	}

	PerturbationIterator(const StateIt first, const StateIt last, size_t h) :
		PerturbationIterator::iterator_adaptor_(first), end(last) {
		if (this->base_reference() != end) {
			current = *(this->base_reference());
			sitesToFlip.resize(current.size(), false);
			for (std::vector<bool>::reverse_iterator it = sitesToFlip.rbegin(),
					end = sitesToFlip.rend(); it != end && h > 0; ++it, --h) {
				*it = true;
			}
		}
	}
};

}

/**
 * @ingroup generator
 *
 * Forward Traversal Readable range.
 */
template<class SinglePassRange> class PerturbationEnumerator : public boost::iterator_range<
		detail::PerturbationIterator<typename boost::range_iterator<
				SinglePassRange>::type> > {
private:
	typedef detail::PerturbationIterator<typename boost::range_iterator<
			SinglePassRange>::type> iter;
	typedef boost::iterator_range<iter> base;

public:

	PerturbationEnumerator() {
	}

	PerturbationEnumerator(SinglePassRange& gen, const size_t n) :
		base(iter(boost::begin(gen), boost::end(gen), n), iter(boost::end(gen),
				boost::end(gen), n)) {
	}

	template<class OtherRange> PerturbationEnumerator(
			const PerturbationEnumerator<OtherRange>& other) :
		base(other) {
	}
};

namespace tag {

struct enumerate_perturbations {

	template<class SinglePassRange> struct apply {
		typedef PerturbationEnumerator<SinglePassRange> type;
	};
};

} // namespace tag

struct enumerate_perturbations {
	const size_t n;

	enumerate_perturbations(const size_t n) :
		n(n) {
	}
};

template<class SinglePassRange> PerturbationEnumerator<SinglePassRange> operator|(
		SinglePassRange& sr, const enumerate_perturbations ep) {
	return PerturbationEnumerator<SinglePassRange> (sr, ep.n);
}

template<class SinglePassRange> PerturbationEnumerator<const SinglePassRange> operator|(
		const SinglePassRange& sr, const enumerate_perturbations ep) {
	return PerturbationEnumerator<const SinglePassRange> (sr, ep.n);
}

} // namespace gen

} // namespace bn

#endif /* PERTURBATIONENUMERATOR_HPP_ */

max_stars_repo_name: Markfrancisrogers/BooleanNetwork

max_issues_repo_name: Markfrancisrogers/BooleanNetwork

max_forks_repo_name: Markfrancisrogers/BooleanNetwork


text:
/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * 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 <boost/algorithm/string/join.hpp>
#include "velox/exec/tests/utils/PlanBuilder.h"
#include "velox/functions/prestosql/aggregates/tests/AggregationTestBase.h"
#include "velox/functions/prestosql/types/TimestampWithTimeZoneType.h"

using facebook::velox::exec::test::PlanBuilder;

namespace facebook::velox::aggregate::test {

class ChecksumAggregateTest : public AggregationTestBase {
 protected:
  template <typename T>
  void assertSingleGroupChecksum(
      const std::vector<std::optional<T>>& data,
      const std::string& checksum) {
    auto inputVector = makeNullableFlatVector<T>(data);
    assertChecksum(inputVector, checksum);
  }

  void assertChecksum(
      VectorPtr inputVector,
      const std::string& expectedChecksum) {
    auto rowVectors = std::vector{makeRowVector({inputVector})};

    // DuckDB doesnt have checksum aggregation, so we will just pass in
    // expected values to compare.
    {
      auto agg = PlanBuilder()
                     .values(rowVectors)
                     .partialAggregation({}, {"checksum(c0)"})
                     .finalAggregation()
                     .project({"to_base64(a0) as c0"})
                     .planNode();
      assertQuery(
          agg,
          fmt::format("VALUES (CAST(\'{}\' AS VARCHAR))", expectedChecksum));
    }

    {
      auto agg = PlanBuilder()
                     .values(rowVectors)
                     .singleAggregation({}, {"checksum(c0)"})
                     .project({"to_base64(a0) as c0"})
                     .planNode();
      assertQuery(
          agg,
          fmt::format("VALUES (CAST(\'{}\' AS VARCHAR))", expectedChecksum));
    }

    {
      auto agg = PlanBuilder()
                     .values(rowVectors)
                     .partialAggregation({}, {"checksum(c0)"})
                     .intermediateAggregation()
                     .finalAggregation()
                     .project({"to_base64(a0) as c0"})
                     .planNode();
      assertQuery(
          agg,
          fmt::format("VALUES (CAST(\'{}\' AS VARCHAR))", expectedChecksum));
    }
  }

  template <typename G, typename T>
  void assertGroupingChecksum(
      const std::vector<std::optional<G>>& groups,
      const std::vector<std::optional<T>>& data,
      const std::vector<std::string>& expectedChecksums) {
    auto groupVector = makeNullableFlatVector<G>(groups);
    auto dataVector = makeNullableFlatVector<T>(data);
    auto rowVectors = std::vector{makeRowVector({groupVector, dataVector})};

    auto expectedResults = std::vector<std::string>();
    expectedResults.reserve(expectedChecksums.size());
    for (auto& str : expectedChecksums) {
      expectedResults.push_back(fmt::format("(\'{}\')", str));
    }
    auto joinedResults = boost::algorithm::join(expectedResults, ",");

    auto agg = PlanBuilder()
                   .values(rowVectors)
                   .partialAggregation({0}, {"checksum(c1)"})
                   .finalAggregation()
                   .project({"to_base64(a0) AS c0"})
                   .planNode();
    assertQuery(
        agg,
        fmt::format(
            "SELECT cast(x as VARCHAR) "
            "FROM (values {}) t(x);",
            joinedResults));
  }

  template <typename T>
  void testIntegrals() {
    assertSingleGroupChecksum<T>({1}, "vmaSXOnPGBc=");
    assertSingleGroupChecksum<T>({0}, "AAAAAAAAAAA=");
    assertSingleGroupChecksum<T>({{}}, "h8rrhbF5N54=");
    assertSingleGroupChecksum<T>({1, 2, 3}, "1g6VH0bvnP4=");

    // Test grouping aggregation.
    assertGroupingChecksum<int8_t, T>(
        {'a', 'b', 'a'}, {1, 2, 3}, {"Ke5cLMBy4qc=", "rSA484V8ulY="});

    assertGroupingChecksum<int8_t, T>(
        {'a', 'b', 'a', 'a'}, {1, 2, 3, {}}, {"sLhIsnHsGUY=", "rSA484V8ulY="});
  }
};

TEST_F(ChecksumAggregateTest, longs) {
  testIntegrals<int64_t>();
}

TEST_F(ChecksumAggregateTest, ints) {
  testIntegrals<int32_t>();
}

TEST_F(ChecksumAggregateTest, smallints) {
  testIntegrals<int16_t>();
}

TEST_F(ChecksumAggregateTest, tinyints) {
  testIntegrals<int8_t>();
}

TEST_F(ChecksumAggregateTest, doubles) {
  assertSingleGroupChecksum<double>({1}, "AAAIJ+Q63dI=");
  assertSingleGroupChecksum<double>({{}}, "h8rrhbF5N54=");
  assertSingleGroupChecksum<double>({99.9}, "iVY+6I1lKyo=");
  assertSingleGroupChecksum<double>({1, 2, 3}, "AACEg9cR14o=");

  assertGroupingChecksum<int8_t, double>(
      {'a', 'b', 'a'}, {1, 2, 3}, {"AACEI6XSDyU=", "AAAAYDI/x2U="});

  assertGroupingChecksum<int8_t, double>(
      {'a', 'b', 'a', 'a'}, {1, 2, 3, {}}, {"AAAAYDI/x2U=", "h8pvqVZMR8M="});
}

TEST_F(ChecksumAggregateTest, reals) {
  assertSingleGroupChecksum<float>({1}, "/23UDiDdm9A=");
  assertSingleGroupChecksum<float>({{}}, "h8rrhbF5N54=");
  assertSingleGroupChecksum<float>({99.9}, "IX/UyPhj6MY=");
  assertSingleGroupChecksum<float>({1, 2, 3}, "b/j7Q4YtV+g=");

  assertGroupingChecksum<int8_t, float>(
      {'a', 'b', 'a'}, {1, 2, 3}, {"Vswv9sY4wxY=", "GSzMTb/0k9E="});

  assertGroupingChecksum<int8_t, float>(
      {'a', 'b', 'a', 'a'}, {1, 2, 3, {}}, {"3ZYbfHiy+rQ=", "GSzMTb/0k9E="});
}

TEST_F(ChecksumAggregateTest, dates) {
  assertSingleGroupChecksum<Date>({Date(0)}, "AAAAAAAAAAA=");
  assertSingleGroupChecksum<Date>({Date(1)}, "vmaSXOnPGBc=");
  assertSingleGroupChecksum<Date>({{}}, "h8rrhbF5N54=");
}

TEST_F(ChecksumAggregateTest, timestamps) {
  assertSingleGroupChecksum<Timestamp>({Timestamp(0, 0)}, "AAAAAAAAAAA=");
  assertSingleGroupChecksum<Timestamp>({Timestamp(1000, 0)}, "RPn4MJ+k+O4=");
  assertSingleGroupChecksum<Timestamp>({{}}, "h8rrhbF5N54=");
}

TEST_F(ChecksumAggregateTest, bools) {
  assertSingleGroupChecksum<bool>({true}, "Kd/S+KIswsw=");
  assertSingleGroupChecksum<bool>({false}, "U55ZHMwGD4I=");
}

TEST_F(ChecksumAggregateTest, varchars) {
  assertSingleGroupChecksum<StringView>({{}}, "h8rrhbF5N54=");
  assertSingleGroupChecksum<StringView>({"abcd"_sv}, "lGFxgnIYgPw=");
  assertSingleGroupChecksum<StringView>(
      {u8"Thanks \u0020\u007F"_sv}, "oEh7YyEV+dM=");
}

TEST_F(ChecksumAggregateTest, arrays) {
  auto arrayVector = makeVectorWithNullArrays<int64_t>({
      {{1, 2}},
      {{3, 4}},
  });

  assertChecksum(arrayVector, "/jjpuD6xkXs=");

  arrayVector = makeVectorWithNullArrays<int64_t>({{{12, std::nullopt}}});
  assertChecksum(arrayVector, "sr3HNuzc+7Y=");
  arrayVector = makeVectorWithNullArrays<int64_t>({{{1, 2}}, std::nullopt});
  assertChecksum(arrayVector, "Nlzernkj88A=");
  arrayVector =
      makeVectorWithNullArrays<int64_t>({{{1, 2}}, std::nullopt, {{}}});
  assertChecksum(arrayVector, "Nlzernkj88A=");

  // Array of arrays.
  auto baseArrayVector = makeVectorWithNullArrays<int64_t>(
      {{{1, 2}}, {{3, 4}}, {{4, std::nullopt}}, {{}}});
  auto arrayOfArrayVector = makeArrayVector({0, 2}, baseArrayVector);
  assertChecksum(arrayOfArrayVector, "Wp67EOfWZPA=");
}

TEST_F(ChecksumAggregateTest, maps) {
  auto mapVector = makeMapVector<int64_t, double>(
      {{{1, 17.0}, {2, 36.0}, {3, 8.0}, {4, 28.0}, {5, 24.0}, {6, 32.0}}});

  assertChecksum(mapVector, "T9pb6QUB4xM=");

  auto mapOfArrays = createMapOfArraysVector<int64_t, int64_t>(
      {{{1, {{1, 2, 3}}}}, {{2, {{4, 5, 6}}}}, {{3, {{7, 8, 9}}}}});

  assertChecksum(mapOfArrays, "GGEqhJQZMa4=");

  // Map with nulls.
  auto mapWithNullArrays = createMapOfArraysVector<int64_t, int64_t>(
      {{{1, std::nullopt}}, {{2, {{4, 5, std::nullopt}}}}, {{3, {{7, 8, 9}}}}});

  assertChecksum(mapWithNullArrays, "gwfQ1dI2P68=");
}

TEST_F(ChecksumAggregateTest, rows) {
  auto row = makeRowVector(
      {makeFlatVector<int64_t>({1, 3}), makeFlatVector<int64_t>({2, 4})});

  assertChecksum(row, "jMIvLQ5YEVg=");

  row = makeRowVector(
      {makeNullableFlatVector<int64_t>({1, std::nullopt}),
       makeNullableFlatVector<int64_t>({std::nullopt, 4})});

  assertChecksum(row, "6jtxEIUj7Hg=");
}

TEST_F(ChecksumAggregateTest, globalAggregationNoData) {
  auto row = std::vector{makeRowVector({makeFlatVector<int64_t>(0)})};
  auto agg = PlanBuilder()
                 .values(row)
                 .singleAggregation({}, {"checksum(c0)"})
                 .planNode();
  assertQuery(agg, "VALUES (CAST(NULL AS VARCHAR))");

  agg = PlanBuilder()
            .values(row)
            .partialAggregation({}, {"checksum(c0)"})
            .intermediateAggregation()
            .finalAggregation()
            .planNode();
  assertQuery(agg, "VALUES (CAST(NULL AS VARCHAR))");
}

TEST_F(ChecksumAggregateTest, timestampWithTimezone) {
  auto timestamp =
      makeFlatVector<int64_t>(5, [](auto row) { return 1639426440000; });
  auto timezone = makeFlatVector<int16_t>(5, [](auto row) { return 0; });

  auto timestampWithTzVector = std::make_shared<RowVector>(
      pool_.get(),
      TIMESTAMP_WITH_TIME_ZONE(),
      BufferPtr(nullptr),
      5,
      std::vector<VectorPtr>{timestamp, timezone});

  assertChecksum(timestampWithTzVector, "jwqENA0VLZY=");
}
} // namespace facebook::velox::aggregate::test

max_stars_repo_name: sanumandla/velox

max_issues_repo_name: plahera/velox

max_forks_repo_name: plahera/velox


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

#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP
#define BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP

#ifndef BOOST_CONFIG_HPP
#  include <boost/config.hpp>
#endif

#if defined(BOOST_HAS_PRAGMA_ONCE)
#  pragma once
#endif

#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/move/detail/type_traits.hpp>
#include <boost/intrusive/detail/mpl.hpp>

#include <cstddef>

namespace boost {
namespace container {
namespace dtl {

using boost::move_detail::integral_constant;
using boost::move_detail::true_type;
using boost::move_detail::false_type;
using boost::move_detail::enable_if_c;
using boost::move_detail::enable_if;
using boost::move_detail::enable_if_convertible;
using boost::move_detail::disable_if_c;
using boost::move_detail::disable_if;
using boost::move_detail::disable_if_convertible;
using boost::move_detail::is_convertible;
using boost::move_detail::if_c;
using boost::move_detail::if_;
using boost::move_detail::identity;
using boost::move_detail::bool_;
using boost::move_detail::true_;
using boost::move_detail::false_;
using boost::move_detail::yes_type;
using boost::move_detail::no_type;
using boost::move_detail::bool_;
using boost::move_detail::true_;
using boost::move_detail::false_;
using boost::move_detail::unvoid_ref;
using boost::move_detail::and_;
using boost::move_detail::or_;
using boost::move_detail::not_;
using boost::move_detail::enable_if_and;
using boost::move_detail::disable_if_and;
using boost::move_detail::enable_if_or;
using boost::move_detail::disable_if_or;

template <class FirstType>
struct select1st
{
   typedef FirstType type;

   template<class T>
   const type& operator()(const T& x) const
   {  return x.first;   }

   template<class T>
   type& operator()(T& x)
   {  return const_cast<type&>(x.first);   }
};

}  //namespace dtl {
}  //namespace container {
}  //namespace boost {

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

#endif   //#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP