text:
/**********************************************************************
*  Copyright (c) 2008-2014, Alliance for Sustainable Energy.
*  All rights reserved.
*
*  This library is free software; you can redistribute it and/or
*  modify it under the terms of the GNU Lesser General Public
*  License as published by the Free Software Foundation; either
*  version 2.1 of the License, or (at your option) any later version.
*
*  This library is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*  Lesser General Public License for more details.
*
*  You should have received a copy of the GNU Lesser General Public
*  License along with this library; if not, write to the Free Software
*  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
**********************************************************************/

#include <openstudio_lib/OSCollapsibleItemList.hpp>
#include <openstudio_lib/OSItem.hpp>
#include <openstudio_lib/OSItemList.hpp>
#include <openstudio_lib/OSCollapsibleItem.hpp>
#include <openstudio_lib/OSCollapsibleItemHeader.hpp>

#include <utilities/core/Assert.hpp>

#include <boost/foreach.hpp>

#include <QHBoxLayout>
#include <QPainter>
#include <QPushButton>
#include <QResizeEvent>
#include <QScrollArea>
#include <QStyleOption>
#include <QVBoxLayout>

namespace openstudio {

OSCollapsibleItemList::OSCollapsibleItemList(bool addScrollArea, QWidget * parent)
  : OSItemSelector(parent),
  m_vLayout(NULL),
  m_contentLayout(NULL),
  m_selectedCollapsibleItem(NULL),
  m_itemsDraggable(false),
  m_itemsRemoveable(false),
  m_showFilterLayout(false),
  m_itemsType(OSItem::LIST_ITEM)
{
  this->setObjectName("GrayWidget");

  QVBoxLayout* outerVLayout = new QVBoxLayout();
  outerVLayout->setContentsMargins(0,0,0,0);
  this->setLayout(outerVLayout);

  QWidget* outerWidget = new QWidget();

  if (addScrollArea){
    QScrollArea* scrollArea = new QScrollArea();
    scrollArea->setFrameStyle(QFrame::NoFrame);
    scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
    scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    outerVLayout->addWidget(scrollArea);
    scrollArea->setWidget(outerWidget);
    scrollArea->setWidgetResizable(true);
  }else{
    outerVLayout->addWidget(outerWidget);
  }

  m_vLayout = new QVBoxLayout();
  outerWidget->setLayout(m_vLayout);
  m_vLayout->setContentsMargins(0,0,0,0);
  m_vLayout->setSpacing(0);
  m_vLayout->addStretch(10);
}

OSCollapsibleItem* OSCollapsibleItemList::selectedCollapsibleItem() const
{
  return m_selectedCollapsibleItem;
}

OSItem* OSCollapsibleItemList::selectedItem() const
{
  OSItem* result = NULL;
  if (m_selectedCollapsibleItem){
    result = m_selectedCollapsibleItem->itemList()->selectedItem();
  }
  return result;
}

bool OSCollapsibleItemList::itemsDraggable() const
{
  return m_itemsDraggable;
}

void OSCollapsibleItemList::setItemsDraggable(bool itemsDraggable)
{
  m_itemsDraggable = itemsDraggable;
  BOOST_FOREACH(OSCollapsibleItem* collapsibleItem, m_collapsibleItems){
    collapsibleItem->setItemsDraggable(itemsDraggable);
  }
}

bool OSCollapsibleItemList::itemsRemoveable() const
{
  return m_itemsRemoveable;
}

void OSCollapsibleItemList::setItemsRemoveable(bool itemsRemoveable)
{
  m_itemsRemoveable = itemsRemoveable;
  BOOST_FOREACH(OSCollapsibleItem* collapsibleItem, m_collapsibleItems){
    collapsibleItem->setItemsRemoveable(itemsRemoveable);
  }
}

OSItem::Type OSCollapsibleItemList::itemsType() const
{
  return m_itemsType;
}

void OSCollapsibleItemList::setItemsType(OSItem::Type type)
{
  m_itemsType = type;
  BOOST_FOREACH(OSCollapsibleItem* collapsibleItem, m_collapsibleItems){
    collapsibleItem->setItemsType(type);
  }
}

bool OSCollapsibleItemList::showFilterLayout() const
{
  return m_showFilterLayout;
}

void OSCollapsibleItemList::setShowFilterLayout(const bool showFilterLayout)
{
  m_showFilterLayout = showFilterLayout;
  BOOST_FOREACH(OSCollapsibleItem* collapsibleItem, m_collapsibleItems){
    collapsibleItem->setShowFilterLayout(showFilterLayout);
  }
}

void OSCollapsibleItemList::addCollapsibleItem(OSCollapsibleItem * collapsibleItem)
{
  OS_ASSERT(collapsibleItem);

  collapsibleItem->setItemsDraggable(m_itemsDraggable);

  collapsibleItem->setItemsRemoveable(m_itemsRemoveable);

  collapsibleItem->setShowFilterLayout(m_showFilterLayout);

  collapsibleItem->setItemsType(m_itemsType);

  m_vLayout->insertWidget(0, collapsibleItem);

  QString style;
  style.append( "QWidget#OSCollapsibleItemList {" );
  style.append( "background: #F2F2F2; ");
  style.append( "border-bottom: 1px solid black; " );
  style.append( "}" );
  style.append( "QWidget#SideBar {background: #EEDEDE;}" );

  collapsibleItem->setStyleSheet(style);

  bool isConnected = false;

  isConnected = connect(collapsibleItem, SIGNAL(collapsableItemSelected(OSCollapsibleItem *)),
                        this, SLOT(onCollapsableItemSelected(OSCollapsibleItem *)));
  OS_ASSERT(isConnected);

  isConnected = connect(collapsibleItem, SIGNAL(itemSelected(OSItem*)),
                        this, SLOT(onItemSelected(OSItem*)));
  OS_ASSERT(isConnected);

  isConnected = connect(collapsibleItem, SIGNAL(itemSelected(OSItem*)),
                        this, SIGNAL(itemSelected(OSItem*)));
  OS_ASSERT(isConnected);

  isConnected = connect(collapsibleItem, SIGNAL(itemReplacementDropped(OSItem*, const OSItemId&)),
                        this, SIGNAL(itemReplacementDropped(OSItem*, const OSItemId&)));
  OS_ASSERT(isConnected);

  isConnected = connect(collapsibleItem, SIGNAL(itemRemoveClicked(OSItem*)),
                        this, SIGNAL(itemRemoveClicked(OSItem*)));
  OS_ASSERT(isConnected);

  isConnected = connect(collapsibleItem, SIGNAL(selectionCleared()),
                        this, SIGNAL(selectionCleared()));
  OS_ASSERT(isConnected);

  isConnected = connect(collapsibleItem,SIGNAL(openLibDlgClicked()),
                        this,SIGNAL(openLibDlgClicked()));
  OS_ASSERT(isConnected);

  if (!selectedItem()){
    collapsibleItem->itemList()->selectItem(collapsibleItem->itemList()->firstItem());
  }

  collapsibleItem->setSelected(true);
}

void OSCollapsibleItemList::onCollapsableItemSelected(OSCollapsibleItem* selectedItem)
{
  QLayoutItem * layoutItem = NULL;
  OSCollapsibleItem* collapsibleItem = NULL;
  OSItem* newSelectedItem = NULL;

  for (int i = 0; i < m_vLayout->count(); ++i){

    layoutItem = m_vLayout->itemAt(i);
    QWidget * widget = layoutItem->widget();

    collapsibleItem = qobject_cast<OSCollapsibleItem*>(widget);
    if (collapsibleItem){
      if (collapsibleItem == selectedItem){

        if (m_selectedCollapsibleItem != collapsibleItem){
          // select new item
          m_selectedCollapsibleItem = collapsibleItem;
          m_selectedCollapsibleItem->setExpanded(true);
          newSelectedItem = m_selectedCollapsibleItem->itemList()->firstItem();
          m_selectedCollapsibleItem->itemList()->selectItem(newSelectedItem);
        }

      }else{
        // deselect
        collapsibleItem->setSelected(false);
        collapsibleItem->setExpanded(false);
        collapsibleItem->itemList()->clearSelection();
      }
    }
  }
}

void OSCollapsibleItemList::onItemSelected(OSItem* item)
{
  QLayoutItem * layoutItem = NULL;
  OSCollapsibleItem* collapsibleItem = NULL;

  for (int i = 0; i < m_vLayout->count(); ++i){

    layoutItem = m_vLayout->itemAt(i);
    QWidget * widget = layoutItem->widget();

    collapsibleItem = qobject_cast<OSCollapsibleItem*>(widget);
    if (collapsibleItem){
      std::vector<OSItem*> items = collapsibleItem->itemList()->items();
      if (std::find(items.begin(), items.end(), item) != items.end()){

        // select item
        m_selectedCollapsibleItem = collapsibleItem;
        m_selectedCollapsibleItem->setSelected(true);

      }else{
        // deselect
        collapsibleItem->setSelected(false);
        collapsibleItem->itemList()->clearSelection();
      }
    }
  }
}

void OSCollapsibleItemList::paintEvent(QPaintEvent * event)
{
  QStyleOption opt;
  opt.init(this);
  QPainter p(this);
  style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}

} // openstudio

max_stars_repo_name: ORNL-BTRIC/OpenStudio

max_issues_repo_name: ORNL-BTRIC/OpenStudio

max_forks_repo_name: ORNL-BTRIC/OpenStudio


text:
//==============================================================================
//         Copyright 2003 - 2012   LASMEA UMR 6602 CNRS/Univ. Clermont II
//         Copyright 2009 - 2012   LRI    UMR 8623 CNRS/Univ Paris Sud XI
//         Copyright 2011 - 2012   MetaScale SAS
//
//          Distributed under the Boost Software License, Version 1.0.
//                 See accompanying file LICENSE.txt or copy at
//                     http://www.boost.org/LICENSE_1_0.txt
//==============================================================================
#ifndef NT2_CORE_FUNCTIONS_WHEREIJ_HPP_INCLUDED
#define NT2_CORE_FUNCTIONS_WHEREIJ_HPP_INCLUDED

/*!
  @file
  @brief Defines and implements the whereij function
 **/

#include <nt2/include/functor.hpp>
#include <nt2/core/container/dsl/size.hpp>
#include <nt2/core/container/dsl/value_type.hpp>
#include <nt2/include/functions/isscalar.hpp>
#include <boost/assert.hpp>

namespace nt2
{
  namespace tag
  {
    /*!
      @brief Tag for whereij functor
     **/
    struct whereij_ : ext::elementwise_<whereij_>
    {
      typedef ext::elementwise_<whereij_> parent;
    };
  }

  /*!
    @brief Act as : for i for j r(i, j) = f(i, j) ? a(i, j) : b(i, j)
    @param f Binary Polymorphic Function object to apply to 0 based indices
    @param a First expression to process
    @param b Second expression to process
  **/
  template<class Functor, class A0, class A1> BOOST_FORCEINLINE
  typename meta::call<tag::whereij_(Functor const&, A0 const&, A1 const&)>::type
  whereij(Functor const& f, A0 const& a, A1 const& b)
  {
    return typename make_functor<tag::whereij_, A0>::type()(f,a,b);
  }
}

namespace nt2 { namespace ext
{
  template<class Domain, int N, class Expr>
  struct  size_of<nt2::tag::whereij_,Domain,N,Expr>
  {
    // TODO dual static of_size case to handle
    typedef typename boost::proto::result_of::child_c<Expr&,0>::value_type  c0_t;
    typedef typename boost::proto::result_of::child_c<Expr&,1>::value_type  c1_t;
    typedef typename c0_t::extent_type                                      e1_t;
    typedef typename c1_t::extent_type                                      e2_t;
    typedef typename make_size< !(e1_t::static_size <= e2_t::static_size)
                                ? e1_t::static_size
                                : e2_t::static_size
                              >::type                               result_type;

    BOOST_FORCEINLINE result_type operator()(Expr& e) const
    {
      result_type s1 = boost::proto::child_c<0>(e).extent();
      result_type s2 = boost::proto::child_c<1>(e).extent();
      BOOST_ASSERT_MSG(s1 == s2 ||
                       nt2::isscalar(boost::proto::child_c<0>(e)) ||
                       nt2::isscalar(boost::proto::child_c<1>(e)), "incompatible sizes using whereij");
      return s1;
    }
  };

  template<class Domain, int N, class Expr>
  struct  value_type<nt2::tag::whereij_,Domain,N,Expr>
  {
    typedef typename  boost::proto::result_of
                  ::child_c<Expr&,0>::value_type::value_type  type;
  };
} }

#endif

ext: hpp


text:
#include <stdio.h>
#include <iostream>
#include "dbscan.h"

#include <dlib/clustering.h>
#include <dlib/matrix.h>
#include "plot.h"
#include <experimental/filesystem>
#include <utility>
#include <unordered_map>
namespace fs = std::experimental::filesystem;

const std::vector<std::string> data_names{
    "dataset0.csv"
    //, "dataset1.csv",
    //"dataset2.csv", "dataset3.csv",
    //"dataset4.csv", "dataset5.csv"
};

const std::vector<std::string> colors{"black", "red", "blue", "green",
                "cyan", "yellow", "brown", "magenta", "gray", "chartreuse", "honeydew"};

using DataType = double;
using Coords = std::vector<DataType>;
using PointCoords = std::pair<Coords, Coords>;
using Clusters = std::unordered_map<int, PointCoords>;

void PlotClusters(const Clusters& clusters,
                 const std::string& name,
                 const std::string& file_name) {

    plotcpp::Plot plt;
    plt.SetTerminal("png");
    plt.SetOutput(file_name);
    plt.SetTitle(name);
    plt.SetXLabel("x");
    plt.SetYLabel("y");
    plt.SetAutoscale();
    plt.GnuplotCommand("set grid");
    auto draw_state = plt.StartDraw2D<Coords::const_iterator>();
    for (const auto& cluster : clusters) {
        std::stringstream params;
        if(cluster.first == -1) continue;
        params << "lc rgb '" << colors[cluster.first] << "'pt 7";
        plt.AddDrawing(draw_state,
                        plotcpp::Points(
                        cluster.second.first.cbegin(), cluster.second.first.cend(),
                        cluster.second.second.cbegin(),
                        std::to_string(static_cast<size_t>(cluster.first)) + " cls", params.str()));

    }

    plt.EndDraw2D(draw_state);
    plt.Flush();
}

//For debug here:
/*
void printResults(vector<Point>& points, int num_points)
{
    int i = 0;
    printf("Number of points: %u\n"
        " x     y   cluster_id\n"
        "-----------------------------\n"
        , num_points);
    while (i < num_points)
    {
          printf("%5.2lf %5.2lf %d\n",
                 points[i].x,
                 points[i].y,
                 points[i].clusterID);
          ++i;
    }
}
*/

int main(int argc, char** argv)
{
    if(argc > 3){
    auto base_dir = fs::path(argv[1]);
    const double epsilon = atof(argv[2]);
    const double minimum_points = atoi(argv[3]);
    for(auto & dataset : data_names ) {
        auto dataset_name = base_dir / dataset;

        if (fs::exists(dataset_name)){
        std::ifstream file(dataset_name);
        dlib::matrix<DataType> data;
        file >> data;
        vector<Point> points;
        for ( int i = 0; i < data.nr(); i++){
            points.emplace_back(data(i, 1), data(i, 2), UNCLASSIFIED);
        }

        Clusters clusters;
        DBSCAN ds(minimum_points, epsilon, points);
        ds.run();

        for (const auto& point : ds.m_points){

            clusters[point.clusterID].first.push_back(point.x);
            clusters[point.clusterID].second.push_back(point.y);
            //For debug here:
            //std::cout << point.clusterID << point.x << point.y << std::endl;
         }

        //std::cout << " file name is: "<< dataset_name << "\n\n\n";
        //printResults(ds.m_points, ds.getTotalPointSize());  //for debug here
        //std::cout << "\n\n\n";
        //std::cout <<__LINE__ << std::endl << std::endl;
        PlotClusters(clusters, "DBSCAN clustering", "../results/" +  dataset + "-dbscans.png");
       }
      else{
        std::cerr << "Dataset file " << dataset_name << "missed. Please provide in the correct form.\n";
      }
     }
    }
    else {
        std::cerr <<" Please provide the data's folder!!!\n\n";
    }
    return 0;
}

ext: cpp


text: #include <boost/fusion/include/vector_fwd.hpp>

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
#ifndef MESSAGE_DELAY_MESSAGE_DELAY_HPP
#define MESSAGE_DELAY_MESSAGE_DELAY_HPP

#include <nodelet/nodelet.h>
#include <ros/duration.h>
#include <ros/node_handle.h>
#include <ros/publisher.h>
#include <ros/subscriber.h>
#include <ros/timer.h>
#include <topic_tools/shape_shifter.h>

#include <boost/asio/deadline_timer.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/bind.hpp>
#include <boost/thread/thread.hpp>

namespace message_delay {

class MessageDelay : public nodelet::Nodelet {
public:
  MessageDelay() : guard_timer_(timer_service_) {
    // run timer service in background.
    // the guard timer keeps the service running.
    // the guard timer is preferred than io_service::work
    // because io_service::work is deprecated in recent versions of boost.
    guard_timer_.async_wait(boost::bind(doNothing));
    timer_thread_ = boost::thread(boost::bind(&boost::asio::io_service::run, &timer_service_));
  }
  virtual ~MessageDelay() {
    // stop the timer serivce
    timer_service_.stop();
    if (timer_thread_.joinable()) {
      timer_thread_.join();
    }
  }

private:
  virtual void onInit() {
    // get node handles
    ros::NodeHandle &nh(getNodeHandle());
    ros::NodeHandle &pnh(getPrivateNodeHandle());

    // load parameters
    const bool unreliable(pnh.param("unreliable", false));
    delay_.fromSec(pnh.param("delay", 1.));

    // subscribe the input topic
    ros::TransportHints transport_hints;
    if (unreliable) {
      // prefer unreliable connection than reliable connection
      transport_hints.unreliable().reliable();
    }
    subscriber_ =
        nh.subscribe("topic_in", 10, &MessageDelay::onMessageReceived, this, transport_hints);
  }

private:
  void onMessageReceived(const topic_tools::ShapeShifter::ConstPtr &msg) {
    // get node handle
    ros::NodeHandle &nh(getNodeHandle());

    // advertise the output topic if never
    if (!publisher_) {
      publisher_ = msg->advertise(nh, "topic_out", 10);
    }

    // schedule delayed publishment.
    // ros::Timer can do the same thing
    // but boost::asio::deadline_timer is 50% lighter on my test environment.
    boost::asio::deadline_timer *const timer(new boost::asio::deadline_timer(timer_service_));
    timer->expires_from_now(delay_.toBoost());
    timer->async_wait(boost::bind(&MessageDelay::onTimerExpired, this, msg, timer));
  }

  void onTimerExpired(const topic_tools::ShapeShifter::ConstPtr &msg,
                      const boost::asio::deadline_timer *const timer) {
    // publish if the publisher is valid
    if (publisher_) {
      publisher_.publish(msg);
    }

    // remove this expired timer
    delete timer;
  }

  // for the guard timer
  static void doNothing() {}

private:
  // parameters
  ros::Duration delay_;

  // ros workers
  ros::Subscriber subscriber_;
  ros::Publisher publisher_;

  // timer contexts
  boost::asio::io_service timer_service_;
  boost::asio::deadline_timer guard_timer_;
  boost::thread timer_thread_;
};
} // namespace message_delay

#endif // MESSAGE_DELAY_MESSAGE_DELAY_HPP


text:
#include <iostream>
#include <cmath>
using namespace std;

#include <Eigen/Core>
#include <Eigen/Geometry> //Eigen Geometry module

//----------------------------use Eigen Geometry module-------------------------
// Eigen/Geometry 提供了各种旋转和平移的表示

int main(int argc, char const *argv[])
{
   // set a 3x3 indentity matrix
   Eigen::Matrix3d R = Eigen::Matrix3d::Identity();

   //-------------------get Rotation Matrix given theta,n-----------------------
   // 创建rotation动作
   //   rot(theta,n) rot 45 degree about z-axis
   //   类型 Eigen::AngleAxisd rot(),
   //     括号里面可以是（theta, n）, 也可以是quaternion q，应该还能是很多其他类型的
   //   旋转向量使用 AngleAxis, 它底层不直接是Matrix，但运算可以当作矩阵（因为重载了运算符）
   Eigen::AngleAxisd rot(M_PI / 4, Eigen::Vector3d(0, 0, 1));
   //   Eigen::AngleAxisd rot_2(q); //q在下面定义这里用不了
   // two ways to see the rotation matrix from rot，都可以返回一个matrix
   // 1. rot.matrix()
   // 2. rot.toRotationMatrix()
   R = rot.matrix();           //等价
   R = rot.toRotationMatrix(); //等价
   cout << "rotation matrix =\n" << R << "\n" << endl;

   // 坐标转换
   // 初始vector p
   Eigen::Vector3d p(1, 0, 0);        //这里用了括号初始化，没有赋值操作
   // p' = rot * p -> p在旋转后的坐标里面的值
   Eigen::Vector3d p_prime = rot * p; //rot.matrix()*p, rot可以直接进行运算（因为重载了运算符）
                                      //也可以用 p_prime = R * p   line23
   cout << "vector p (1,0,0) after rotation = " << p_prime.transpose() << "\n" << endl;

   //-----------------------------Euler Angle-----------------------------------
   // 可以将旋转矩阵直接转换成欧拉角，欧拉角用3个量表示3个自由度
   // 欧拉角将一个一次性的rotation matrix分解成三次旋转，返回每次旋转对应的角度
   // 所有3维matrix都可以使用.eulerAngles(0,1,2)，类型为AngleAxisd的，比如rot不能使用(line19)
   Eigen::Vector3d euler_angles // 返回一个3x1的向量
      = R.eulerAngles(2, 1, 0); // ZYX顺序，即roll pitch yaw顺序
   cout << "yaw pitch roll = " << euler_angles.transpose() << "\n" << endl;

   //------------------------Transformation Matrix------------------------------
   // T = | R | t |
   //     | 0 | 1 |
   // given R，t，create transformation matrix（欧式变换矩阵）
   Eigen::Vector3d   t(1, 2, 4);                        //初始化t，没有赋值操作
   Eigen::Isometry3d T = Eigen::Isometry3d::Identity(); //虽然是3d，但是是4x4的矩阵
   T.rotate(R);                                         //把 R 放到 T 里面
   T.pretranslate(t);                                   //把 t 放到 T 里面
   cout << "Transform matrix = \n" << T.matrix() << "\n" << endl;

   // 坐标转换
   p_prime = T * p; //这里T是4x4，而p是3x1。实际操作是 p'=Rp+t
   cout << "p' after transformation matrix is "
        << p_prime.transpose() << "\n" << endl;

   //-------------------------------Quaternion---------------------------------
   // 将 rotation matrix R 转变为 Quaternion q
   // 用Eigen::Quaternion()
   // 括号里的参数类型可以是Matrix3d,比如R，也可以是AngleAxisd，比如rot
   Eigen::Quaterniond q = Eigen::Quaterniond(rot);
   // 请注意coeffs的顺序是(x,y,z,w),w为实部，前三者为虚部
   cout << "quaternion = \n" << q.coeffs() << "\n" << endl;

   // 坐标转换
   p_prime = q * p; //这里的实际操作是 p'=qpq^(-1)
   cout << "p' after Quaternion transformation is "
        << p_prime.transpose() << "\n" << endl;

   //----对于仿射和射影变换，使用 Eigen::Affine3d 和 Eigen::Projective3d 即可，略-----

   return 0;
}

max_stars_repo_name: Qilko/VisualSLAM

max_issues_repo_name: Qilko/VisualSLAM

max_forks_repo_name: Qilko/VisualSLAM


text:
#include "framework/ui.h"
#include "meta/project.h"
#include <GL/glew.h>
#include <pugl/gl.h>
#include <pugl/pugl.h>
#include <boost/scope_exit.hpp>
#include <stdexcept>
#include <iostream>

struct UI::Impl {
  static constexpr unsigned width = 600;
  static constexpr unsigned height = 400;
  PuglView *view {};
  PuglNativeWindow parent = 0;
  PuglNativeWindow widget = 0;
  bool exposed = false;
  bool initialized_gl = false;
  bool ok_gl = false;
  void create_widget();
  void handle_event(const PuglEvent *event);
  void init_gl();
  void draw_gl();
};

//==============================================================================
UI::UI(void *parent, LV2_URID_Map *map, LV2_URID_Unmap *unmap,
       const char *bundle_path)
    : P(new Impl) {
  P->parent = PuglNativeWindow(parent);
}

UI::~UI() {
  if (P->view)
    puglDestroy(P->view);
}

void UI::option(const LV2_Options_Option &o) {
}

LV2UI_Widget UI::widget() const {
  if (!P->widget)
    P->create_widget();
  return LV2UI_Widget(P->widget);
}

unsigned UI::width() {
  return Impl::width;
}

unsigned UI::height() {
  return Impl::height;
}

void UI::port_event(
    uint32_t port_index, uint32_t buffer_size, uint32_t format, const void *buffer) {
}

bool UI::needs_idle_callback() {
  return true;
}

bool UI::idle() {
  PuglView *view = P->view;
  if (!view)
    return false;

  puglProcessEvents(view);

  if (!P->initialized_gl) {
    puglEnterContext(view);
    P->init_gl();
    P->initialized_gl = true;
    puglLeaveContext(view, false);
  }

  if (!P->ok_gl)
    return false;

  puglEnterContext(view);
  P->draw_gl();
  puglLeaveContext(view, true);

  return P->exposed;
}

//==============================================================================
void UI::Impl::create_widget() {
  bool success = false;

  int pugl_argc = 1;
  char pugl_arg0[] = "pugl";
  char *pugl_argv[] = {pugl_arg0, nullptr};

  PuglView *view = puglInit(&pugl_argc, pugl_argv);
  if (!view)
    throw std::runtime_error("error creating a Pugl view");

  BOOST_SCOPE_EXIT(&success, view) {
    if (!success)
      puglDestroy(view);
  } BOOST_SCOPE_EXIT_END;

  puglSetHandle(view, this);
  puglSetEventFunc(view, [](PuglView *view, const PuglEvent *event) {
    reinterpret_cast<UI::Impl *>(puglGetHandle(view))->handle_event(event); });

  puglInitWindowParent(view, this->parent);
  puglInitWindowSize(view, Impl::width, Impl::height);
  puglInitResizable(view, false);
  puglInitContextType(view, PUGL_GL);

  if (puglCreateWindow(view, PROJECT_DISPLAY_NAME) != 0)
    throw std::runtime_error("error creating a Pugl window");

  puglShowWindow(view);
  puglProcessEvents(view);

  this->view = view;
  this->widget = puglGetNativeWindow(view);
  success = true;
}

void UI::Impl::handle_event(const PuglEvent *event) {
  switch (event->type) {
    case PUGL_EXPOSE: this->exposed = true; break;
    case PUGL_CLOSE: this->exposed = false; break;
    // handle other events here
    default: break;
  }
}

void UI::Impl::init_gl() {
  if (glewInit() != GLEW_OK) {
    std::cerr << "error initializing GLEW\n";
    return;
  }

  glClearColor(0, 0, 0, 0);
  glViewport(0, 0, Impl::width, Impl::height);

  this->ok_gl = true;
}

void UI::Impl::draw_gl() {
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(0, Impl::width, Impl::height, 0, -10, 10);

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  glClear(GL_COLOR_BUFFER_BIT);

  glBegin(GL_TRIANGLES);
  {
    glColor3f(0, 0, 1);
    glVertex2f(Impl::width / 2, 0);
    glColor3f(0, 1, 0);
    glVertex2f(0, Impl::height - 1);
    glColor3f(1, 0, 0);
    glVertex2f(Impl::width - 1, Impl::height - 1);
  }
  glEnd();
}

ext: cc


text:
#include <Backups/RestoreUtils.h>
#include <Backups/BackupUtils.h>
#include <Backups/RestoreSettings.h>
#include <Backups/DDLCompareUtils.h>
#include <Backups/DDLRenamingVisitor.h>
#include <Backups/IBackup.h>
#include <Backups/IBackupEntry.h>
#include <Backups/IRestoreTask.h>
#include <Backups/RestoreCoordinationDistributed.h>
#include <Backups/formatTableNameOrTemporaryTableName.h>
#include <Common/escapeForFileName.h>
#include <Databases/IDatabase.h>
#include <Databases/DatabaseReplicated.h>
#include <IO/ReadHelpers.h>
#include <Interpreters/Context.h>
#include <Interpreters/InterpreterCreateQuery.h>
#include <Parsers/ASTCreateQuery.h>
#include <Parsers/ASTFunction.h>
#include <Parsers/ParserCreateQuery.h>
#include <Parsers/formatAST.h>
#include <Parsers/parseQuery.h>
#include <Storages/IStorage.h>
#include <base/chrono_io.h>
#include <base/insertAtEnd.h>
#include <base/sleep.h>
#include <boost/range/adaptor/reversed.hpp>
#include <boost/range/algorithm_ext/erase.hpp>
#include <filesystem>

namespace DB
{
namespace ErrorCodes
{
    extern const int CANNOT_RESTORE_TABLE;
    extern const int CANNOT_RESTORE_DATABASE;
    extern const int BACKUP_ENTRY_NOT_FOUND;
}

namespace
{
    class PathsInBackup
    {
    public:
        explicit PathsInBackup(const IBackup & backup_) : backup(backup_) {}

        std::vector<size_t> getShards() const
        {
            std::vector<size_t> res;
            for (const String & shard_index : backup.listFiles("shards/"))
                res.push_back(parse<UInt64>(shard_index));
            if (res.empty())
                res.push_back(1);
            return res;
        }

        std::vector<size_t> getReplicas(size_t shard_index) const
        {
            std::vector<size_t> res;
            for (const String & replica_index : backup.listFiles(fmt::format("shards/{}/replicas/", shard_index)))
                res.push_back(parse<UInt64>(replica_index));
            if (res.empty())
                res.push_back(1);
            return res;
        }

        std::vector<String> getDatabases(size_t shard_index, size_t replica_index) const
        {
            std::vector<String> res;

            insertAtEnd(res, backup.listFiles(fmt::format("shards/{}/replicas/{}/metadata/", shard_index, replica_index)));
            insertAtEnd(res, backup.listFiles(fmt::format("shards/{}/metadata/", shard_index)));
            insertAtEnd(res, backup.listFiles(fmt::format("metadata/")));

            boost::range::remove_erase_if(
                res,
                [](String & str)
                {
                    if (str.ends_with(".sql"))
                    {
                        str.resize(str.length() - strlen(".sql"));
                        str = unescapeForFileName(str);
                        return false;
                    }
                    return true;
                });

            std::sort(res.begin(), res.end());
            res.erase(std::unique(res.begin(), res.end()), res.end());
            return res;
        }

        std::vector<String> getTables(const String & database_name, size_t shard_index, size_t replica_index) const
        {
            std::vector<String> res;

            String escaped_database_name = escapeForFileName(database_name);
            insertAtEnd(res, backup.listFiles(fmt::format("shards/{}/replicas/{}/metadata/{}/", shard_index, replica_index, escaped_database_name)));
            insertAtEnd(res, backup.listFiles(fmt::format("shards/{}/metadata/{}/", shard_index, escaped_database_name)));
            insertAtEnd(res, backup.listFiles(fmt::format("metadata/{}/", escaped_database_name)));

            boost::range::remove_erase_if(
                res,
                [](String & str)
                {
                    if (str.ends_with(".sql"))
                    {
                        str.resize(str.length() - strlen(".sql"));
                        str = unescapeForFileName(str);
                        return false;
                    }
                    return true;
                });

            std::sort(res.begin(), res.end());
            res.erase(std::unique(res.begin(), res.end()), res.end());
            return res;
        }

        /// Returns the path to metadata in backup.
        String getMetadataPath(const DatabaseAndTableName & table_name, size_t shard_index, size_t replica_index) const
        {
            String escaped_table_name = escapeForFileName(table_name.first) + "/" + escapeForFileName(table_name.second);
            String path1 = fmt::format("shards/{}/replicas/{}/metadata/{}.sql", shard_index, replica_index, escaped_table_name);
            if (backup.fileExists(path1))
                return path1;
            String path2 = fmt::format("shards/{}/metadata/{}.sql", shard_index, escaped_table_name);
            if (backup.fileExists(path2))
                return path2;
            String path3 = fmt::format("metadata/{}.sql", escaped_table_name);
            return path3;
        }

        String getMetadataPath(const String & database_name, size_t shard_index, size_t replica_index) const
        {
            String escaped_database_name = escapeForFileName(database_name);
            String path1 = fmt::format("shards/{}/replicas/{}/metadata/{}.sql", shard_index, replica_index, escaped_database_name);
            if (backup.fileExists(path1))
                return path1;
            String path2 = fmt::format("shards/{}/metadata/{}.sql", shard_index, escaped_database_name);
            if (backup.fileExists(path2))
                return path2;
            String path3 = fmt::format("metadata/{}.sql", escaped_database_name);
            return path3;
        }

        String getDataPath(const DatabaseAndTableName & table_name, size_t shard_index, size_t replica_index) const
        {
            String escaped_table_name = escapeForFileName(table_name.first) + "/" + escapeForFileName(table_name.second);
            if (backup.fileExists(fmt::format("shards/{}/replicas/{}/metadata/{}.sql", shard_index, replica_index, escaped_table_name)))
                return fmt::format("shards/{}/replicas/{}/data/{}/", shard_index, replica_index, escaped_table_name);
            if (backup.fileExists(fmt::format("shards/{}/metadata/{}.sql", shard_index, escaped_table_name)))
                return fmt::format("shards/{}/data/{}/", shard_index, escaped_table_name);
            return fmt::format("data/{}/", escaped_table_name);
        }

    private:
        const IBackup & backup;
    };

    using Kind = ASTBackupQuery::Kind;
    using Element = ASTBackupQuery::Element;
    using Elements = ASTBackupQuery::Elements;
    using ElementType = ASTBackupQuery::ElementType;
    using RestoreSettingsPtr = std::shared_ptr<const RestoreSettings>;

    /// Restores a database (without tables inside), should be executed before executing
    /// RestoreTableTask.
    class RestoreDatabaseTask : public IRestoreTask
    {
    public:
        RestoreDatabaseTask(
            ContextMutablePtr context_,
            const ASTPtr & create_query_,
            const RestoreSettingsPtr & restore_settings_)
            : context(context_)
            , create_query(typeid_cast<std::shared_ptr<ASTCreateQuery>>(create_query_))
            , restore_settings(restore_settings_)
        {
        }

        RestoreTasks run() override
        {
            createDatabase();
            getDatabase();
            checkDatabaseCreateQuery();
            return {};
        }

        bool isSequential() const override { return true; }

    private:
        void createDatabase()
        {
            if (restore_settings->create_database == RestoreDatabaseCreationMode::kMustExist)
                return;

            auto cloned_create_query = typeid_cast<std::shared_ptr<ASTCreateQuery>>(create_query->clone());
            cloned_create_query->if_not_exists = (restore_settings->create_database == RestoreDatabaseCreationMode::kCreateIfNotExists);
            InterpreterCreateQuery create_interpreter{cloned_create_query, context};
            create_interpreter.execute();
        }

        DatabasePtr getDatabase()
        {
            if (!database)
                database = DatabaseCatalog::instance().getDatabase(create_query->getDatabase());
            return database;
        }

        ASTPtr getDatabaseCreateQuery()
        {
            if (!database_create_query)
                database_create_query = getDatabase()->getCreateDatabaseQuery();
            return database_create_query;
        }

        void checkDatabaseCreateQuery()
        {
            if (restore_settings->allow_different_database_def)
                return;

            getDatabaseCreateQuery();
            if (areDatabaseDefinitionsSame(*create_query, *database_create_query))
                return;

            throw Exception(
                ErrorCodes::CANNOT_RESTORE_DATABASE,
                "The database {} already exists but has a different definition: {}, "
                "compare to its definition in the backup: {}",
                backQuoteIfNeed(create_query->getDatabase()),
                serializeAST(*database_create_query),
                serializeAST(*create_query));
        }

        ContextMutablePtr context;
        std::shared_ptr<ASTCreateQuery> create_query;
        RestoreSettingsPtr restore_settings;
        DatabasePtr database;
        ASTPtr database_create_query;
    };

    /// Restores a table and fills it with data.
    class RestoreTableTask : public IRestoreTask
    {
    public:
        RestoreTableTask(
            ContextMutablePtr context_,
            const ASTPtr & create_query_,
            const ASTs & partitions_,
            const BackupPtr & backup_,
            const DatabaseAndTableName & table_name_in_backup_,
            const RestoreSettingsPtr & restore_settings_,
            const std::shared_ptr<IRestoreCoordination> & restore_coordination_)
            : context(context_), create_query(typeid_cast<std::shared_ptr<ASTCreateQuery>>(create_query_)),
              partitions(partitions_), backup(backup_), table_name_in_backup(table_name_in_backup_),
              restore_settings(restore_settings_), restore_coordination(restore_coordination_)
        {
            table_name = DatabaseAndTableName{create_query->getDatabase(), create_query->getTable()};
            if (create_query->temporary)
                table_name.first = DatabaseCatalog::TEMPORARY_DATABASE;
        }

        RestoreTasks run() override
        {
            if (acquireTableCreation())
            {
                try
                {
                    createStorage();
                    getStorage();
                    checkStorageCreateQuery();
                    setTableCreationResult(IRestoreCoordination::Result::SUCCEEDED);
                }
                catch (...)
                {
                    setTableCreationResult(IRestoreCoordination::Result::FAILED);
                    throw;
                }
            }
            else
            {
                waitForTableCreation();
                getStorage();
                checkStorageCreateQuery();
            }

            RestoreTasks tasks;
            if (auto task = insertData())
                tasks.push_back(std::move(task));
            return tasks;
        }

        bool isSequential() const override { return true; }

    private:
        bool acquireTableCreation()
        {
            if (restore_settings->create_table == RestoreTableCreationMode::kMustExist)
                return true;

            auto replicated_db
                = typeid_cast<std::shared_ptr<const DatabaseReplicated>>(DatabaseCatalog::instance().getDatabase(table_name.first));
            if (!replicated_db)
                return true;

            use_coordination_for_table_creation = true;
            replicated_database_zookeeper_path = replicated_db->getZooKeeperPath();
            return restore_coordination->acquireZkPathAndName(replicated_database_zookeeper_path, table_name.second);
        }

        void setTableCreationResult(IRestoreCoordination::Result res)
        {
            if (use_coordination_for_table_creation)
                restore_coordination->setResultForZkPathAndName(replicated_database_zookeeper_path, table_name.second, res);
        }

        void waitForTableCreation()
        {
            if (!use_coordination_for_table_creation)
                return;

            IRestoreCoordination::Result res;
            const auto & config = context->getConfigRef();
            auto timeout = std::chrono::seconds(config.getUInt("backups.create_table_in_replicated_db_timeout", 10));
            auto start_time = std::chrono::steady_clock::now();

            if (!restore_coordination->getResultForZkPathAndName(replicated_database_zookeeper_path, table_name.second, res, timeout))
                throw Exception(
                    ErrorCodes::CANNOT_RESTORE_TABLE,
                    "Waited too long ({}) for creating of {} on another replica",
                    to_string(timeout),
                    formatTableNameOrTemporaryTableName(table_name));

            if (res == IRestoreCoordination::Result::FAILED)
                throw Exception(
                    ErrorCodes::CANNOT_RESTORE_TABLE,
                    "Failed creating of {} on another replica",
                    formatTableNameOrTemporaryTableName(table_name));

            while (std::chrono::steady_clock::now() - start_time < timeout)
            {
                if (DatabaseCatalog::instance().tryGetDatabaseAndTable({table_name.first, table_name.second}, context).second)
                    return;
                sleepForMilliseconds(50);
            }

            throw Exception(
                ErrorCodes::CANNOT_RESTORE_TABLE,
                "Waited too long ({}) for creating of {} on another replica",
                to_string(timeout),
                formatTableNameOrTemporaryTableName(table_name));
        }

        void createStorage()
        {
            if (restore_settings->create_table == RestoreTableCreationMode::kMustExist)
                return;

            auto cloned_create_query = typeid_cast<std::shared_ptr<ASTCreateQuery>>(create_query->clone());
            cloned_create_query->if_not_exists = (restore_settings->create_table == RestoreTableCreationMode::kCreateIfNotExists);
            InterpreterCreateQuery create_interpreter{cloned_create_query, context};
            create_interpreter.setInternal(true);
            create_interpreter.execute();
        }

        StoragePtr getStorage()
        {
            if (!storage)
                std::tie(database, storage) = DatabaseCatalog::instance().getDatabaseAndTable({table_name.first, table_name.second}, context);
            return storage;
        }

        ASTPtr getStorageCreateQuery()
        {
            if (!storage_create_query)
            {
                getStorage();
                storage_create_query = database->getCreateTableQuery(table_name.second, context);
            }
            return storage_create_query;
        }

        void checkStorageCreateQuery()
        {
            if (restore_settings->allow_different_table_def)
                return;

            getStorageCreateQuery();
            if (areTableDefinitionsSame(*create_query, *storage_create_query))
                return;

            throw Exception(
                ErrorCodes::CANNOT_RESTORE_TABLE,
                "The {} already exists but has a different definition: {}, "
                "compare to its definition in the backup: {}",
                formatTableNameOrTemporaryTableName(table_name),
                serializeAST(*storage_create_query),
                serializeAST(*create_query));
        }

        bool hasData()
        {
            if (has_data)
                return *has_data;

            has_data = false;
            if (restore_settings->structure_only)
                return false;

            data_path_in_backup = PathsInBackup{*backup}.getDataPath(table_name_in_backup, restore_settings->shard_num_in_backup, restore_settings->replica_num_in_backup);
            if (backup->listFiles(data_path_in_backup).empty())
                return false;

            getStorageCreateQuery();
            if (!areTableDataCompatible(*create_query, *storage_create_query))
                throw Exception(
                    ErrorCodes::CANNOT_RESTORE_TABLE,
                    "Cannot attach data of the {} in the backup to the existing {} because of they are not compatible. "
                    "Here is the definition of the {} in the backup: {}, and here is the definition of the existing {}: {}",
                    formatTableNameOrTemporaryTableName(table_name_in_backup),
                    formatTableNameOrTemporaryTableName(table_name),
                    formatTableNameOrTemporaryTableName(table_name_in_backup),
                    serializeAST(*create_query),
                    formatTableNameOrTemporaryTableName(table_name),
                    serializeAST(*storage_create_query));

            /// We check for INSERT privilege only if we're going to write into table.
            context->checkAccess(AccessType::INSERT, table_name.first, table_name.second);

            has_data = true;
            return true;
        }

        RestoreTaskPtr insertData()
        {
            if (!hasData())
                return {};

            return storage->restoreData(context, partitions, backup, data_path_in_backup, *restore_settings, restore_coordination);
        }

        ContextMutablePtr context;
        std::shared_ptr<ASTCreateQuery> create_query;
        DatabaseAndTableName table_name;
        ASTs partitions;
        BackupPtr backup;
        DatabaseAndTableName table_name_in_backup;
        RestoreSettingsPtr restore_settings;
        std::shared_ptr<IRestoreCoordination> restore_coordination;
        bool use_coordination_for_table_creation = false;
        String replicated_database_zookeeper_path;
        DatabasePtr database;
        StoragePtr storage;
        ASTPtr storage_create_query;
        std::optional<bool> has_data;
        String data_path_in_backup;
    };

    /// Makes tasks for restoring databases and tables according to the elements of ASTBackupQuery.
    /// Keep this class consistent with BackupEntriesBuilder.
    class RestoreTasksBuilder
    {
    public:
        RestoreTasksBuilder(ContextMutablePtr context_, const BackupPtr & backup_, const RestoreSettings & restore_settings_)
            : context(context_), backup(backup_), restore_settings(restore_settings_)
        {
            if (!restore_settings.coordination_zk_path.empty())
                restore_coordination = std::make_shared<RestoreCoordinationDistributed>(restore_settings.coordination_zk_path, [context=context] { return context->getZooKeeper(); });
        }

        /// Prepares internal structures for making tasks for restoring.
        void prepare(const ASTBackupQuery::Elements & elements)
        {
            adjustIndicesOfSourceShardAndReplicaInBackup();

            String current_database = context->getCurrentDatabase();
            renaming_settings.setFromBackupQuery(elements, current_database);

            for (const auto & element : elements)
            {
                switch (element.type)
                {
                    case ElementType::TABLE:
                    {
                        const String & table_name = element.name.second;
                        String database_name = element.name.first;
                        if (database_name.empty())
                            database_name = current_database;
                        prepareToRestoreTable(DatabaseAndTableName{database_name, table_name}, element.partitions);
                        break;
                    }

                    case ElementType::DATABASE:
                    {
                        const String & database_name = element.name.first;
                        prepareToRestoreDatabase(database_name, element.except_list);
                        break;
                    }

                    case ElementType::ALL_DATABASES:
                    {
                        prepareToRestoreAllDatabases(element.except_list);
                        break;
                    }
                }
            }
        }

        /// Makes tasks for restoring, should be called after prepare().
        RestoreTasks makeTasks() const
        {
            auto restore_settings_ptr = std::make_shared<const RestoreSettings>(restore_settings);

            RestoreTasks res;
            for (const auto & info : databases | boost::adaptors::map_values)
                res.push_back(std::make_unique<RestoreDatabaseTask>(context, info.create_query, restore_settings_ptr));

            /// TODO: We need to restore tables according to their dependencies.
            for (const auto & info : tables | boost::adaptors::map_values)
                res.push_back(std::make_unique<RestoreTableTask>(context, info.create_query, info.partitions, backup, info.name_in_backup, restore_settings_ptr, restore_coordination));

            return res;
        }

    private:
        void adjustIndicesOfSourceShardAndReplicaInBackup()
        {
            auto shards_in_backup = PathsInBackup{*backup}.getShards();
            if (!restore_settings.shard_num_in_backup)
            {
                if (shards_in_backup.size() == 1)
                    restore_settings.shard_num_in_backup = shards_in_backup[0];
                else
                    restore_settings.shard_num_in_backup = restore_settings.shard_num;
            }

            if (std::find(shards_in_backup.begin(), shards_in_backup.end(), restore_settings.shard_num_in_backup) == shards_in_backup.end())
                throw Exception(ErrorCodes::BACKUP_ENTRY_NOT_FOUND, "No shard #{} in backup", restore_settings.shard_num_in_backup);

            auto replicas_in_backup = PathsInBackup{*backup}.getReplicas(restore_settings.shard_num_in_backup);
            if (!restore_settings.replica_num_in_backup)
            {
                if (replicas_in_backup.size() == 1)
                    restore_settings.replica_num_in_backup = replicas_in_backup[0];
                else
                    restore_settings.replica_num_in_backup = restore_settings.replica_num;
            }

            if (std::find(replicas_in_backup.begin(), replicas_in_backup.end(), restore_settings.replica_num_in_backup) == replicas_in_backup.end())
                throw Exception(ErrorCodes::BACKUP_ENTRY_NOT_FOUND, "No replica #{} in backup", restore_settings.replica_num_in_backup);
        }

        /// Prepares to restore a single table and probably its database's definition.
        void prepareToRestoreTable(const DatabaseAndTableName & table_name_, const ASTs & partitions_)
        {
            /// Check that we are not trying to restore the same table again.
            DatabaseAndTableName new_table_name = renaming_settings.getNewTableName(table_name_);
            if (tables.contains(new_table_name))
                throw Exception(ErrorCodes::CANNOT_RESTORE_TABLE, "Cannot restore the {} twice", formatTableNameOrTemporaryTableName(new_table_name));

            /// Make a create query for this table.
            auto create_query = renameInCreateQuery(readCreateQueryFromBackup(table_name_));

            CreateTableInfo info;
            info.create_query = create_query;
            info.name_in_backup = table_name_;
            info.partitions = partitions_;
            tables[new_table_name] = std::move(info);
        }

        /// Prepares to restore a database and all tables in it.
        void prepareToRestoreDatabase(const String & database_name_, const std::set<String> & except_list_)
        {
            /// Check that we are not trying to restore the same database again.
            String new_database_name = renaming_settings.getNewDatabaseName(database_name_);
            if (databases.contains(new_database_name))
                throw Exception(ErrorCodes::CANNOT_RESTORE_DATABASE, "Cannot restore the database {} twice", backQuoteIfNeed(new_database_name));

            Strings table_names = PathsInBackup{*backup}.getTables(database_name_, restore_settings.shard_num_in_backup, restore_settings.replica_num_in_backup);
            bool has_tables_in_backup = !table_names.empty();
            bool has_create_query_in_backup = hasCreateQueryInBackup(database_name_);

            if (!has_create_query_in_backup && !has_tables_in_backup)
                throw Exception(ErrorCodes::CANNOT_RESTORE_DATABASE, "Cannot restore the database {} because there is no such database in the backup", backQuoteIfNeed(database_name_));

            /// Of course we're not going to restore the definition of the system or the temporary database.
            if (!isSystemOrTemporaryDatabase(new_database_name))
            {
                /// Make a create query for this database.
                std::shared_ptr<ASTCreateQuery> create_query;
                if (has_create_query_in_backup)
                {
                    create_query = renameInCreateQuery(readCreateQueryFromBackup(database_name_));
                }
                else
                {
                    create_query = std::make_shared<ASTCreateQuery>();
                    create_query->setDatabase(database_name_);
                }

                CreateDatabaseInfo info;
                info.create_query = create_query;
                databases[new_database_name] = std::move(info);
            }

            /// Restore tables in this database.
            for (const String & table_name : table_names)
            {
                if (except_list_.contains(table_name))
                    continue;
                prepareToRestoreTable(DatabaseAndTableName{database_name_, table_name}, ASTs{});
            }
        }

        /// Prepares to restore all the databases contained in the backup.
        void prepareToRestoreAllDatabases(const std::set<String> & except_list_)
        {
            for (const String & database_name : PathsInBackup{*backup}.getDatabases(restore_settings.shard_num_in_backup, restore_settings.replica_num_in_backup))
            {
                if (except_list_.contains(database_name))
                    continue;
                prepareToRestoreDatabase(database_name, std::set<String>{});
            }
        }

        /// Reads a create query for creating a specified table from the backup.
        std::shared_ptr<ASTCreateQuery> readCreateQueryFromBackup(const DatabaseAndTableName & table_name) const
        {
            String create_query_path = PathsInBackup{*backup}.getMetadataPath(table_name, restore_settings.shard_num_in_backup, restore_settings.replica_num_in_backup);
            if (!backup->fileExists(create_query_path))
                throw Exception(ErrorCodes::CANNOT_RESTORE_TABLE, "Cannot restore the {} because there is no such table in the backup",
                                formatTableNameOrTemporaryTableName(table_name));
            auto read_buffer = backup->readFile(create_query_path)->getReadBuffer();
            String create_query_str;
            readStringUntilEOF(create_query_str, *read_buffer);
            read_buffer.reset();
            ParserCreateQuery create_parser;
            return typeid_cast<std::shared_ptr<ASTCreateQuery>>(parseQuery(create_parser, create_query_str, 0, DBMS_DEFAULT_MAX_PARSER_DEPTH));
        }

        /// Reads a create query for creating a specified database from the backup.
        std::shared_ptr<ASTCreateQuery> readCreateQueryFromBackup(const String & database_name) const
        {
            String create_query_path = PathsInBackup{*backup}.getMetadataPath(database_name, restore_settings.shard_num_in_backup, restore_settings.replica_num_in_backup);
            if (!backup->fileExists(create_query_path))
                throw Exception(ErrorCodes::CANNOT_RESTORE_DATABASE, "Cannot restore the database {} because there is no such database in the backup", backQuoteIfNeed(database_name));
            auto read_buffer = backup->readFile(create_query_path)->getReadBuffer();
            String create_query_str;
            readStringUntilEOF(create_query_str, *read_buffer);
            read_buffer.reset();
            ParserCreateQuery create_parser;
            return typeid_cast<std::shared_ptr<ASTCreateQuery>>(parseQuery(create_parser, create_query_str, 0, DBMS_DEFAULT_MAX_PARSER_DEPTH));
        }

        /// Whether there is a create query for creating a specified database in the backup.
        bool hasCreateQueryInBackup(const String & database_name) const
        {
            String create_query_path = PathsInBackup{*backup}.getMetadataPath(database_name, restore_settings.shard_num_in_backup, restore_settings.replica_num_in_backup);
            return backup->fileExists(create_query_path);
        }

        /// Do renaming in the create query according to the renaming config.
        std::shared_ptr<ASTCreateQuery> renameInCreateQuery(const ASTPtr & ast) const
        {
            ASTPtr query = ast;
            ::DB::renameInCreateQuery(query, context, renaming_settings);
            auto create_query = typeid_cast<std::shared_ptr<ASTCreateQuery>>(query);
            return create_query;
        }

        static bool isSystemOrTemporaryDatabase(const String & database_name)
        {
            return (database_name == DatabaseCatalog::SYSTEM_DATABASE) || (database_name == DatabaseCatalog::TEMPORARY_DATABASE);
        }

        /// Information which is used to make an instance of RestoreTableTask.
        struct CreateTableInfo
        {
            ASTPtr create_query;
            DatabaseAndTableName name_in_backup;
            ASTs partitions;
        };

        /// Information which is used to make an instance of RestoreDatabaseTask.
        struct CreateDatabaseInfo
        {
            ASTPtr create_query;
        };

        ContextMutablePtr context;
        BackupPtr backup;
        RestoreSettings restore_settings;
        std::shared_ptr<IRestoreCoordination> restore_coordination;
        DDLRenamingSettings renaming_settings;
        std::map<String /* new_db_name */, CreateDatabaseInfo> databases;
        std::map<DatabaseAndTableName /* new_table_name */, CreateTableInfo> tables;
    };

    /// Reverts completed restore tasks (in reversed order).
    void rollbackRestoreTasks(RestoreTasks && restore_tasks)
    {
        for (auto & restore_task : restore_tasks | boost::adaptors::reversed)
        {
            try
            {
                std::move(restore_task)->rollback();
            }
            catch (...)
            {
                tryLogCurrentException("Restore", "Couldn't rollback changes after failed RESTORE");
            }
        }
    }
}

RestoreTasks makeRestoreTasks(ContextMutablePtr context, const BackupPtr & backup, const Elements & elements, const RestoreSettings & restore_settings)
{
    RestoreTasksBuilder builder{context, backup, restore_settings};
    builder.prepare(elements);
    return builder.makeTasks();
}

void executeRestoreTasks(RestoreTasks && restore_tasks, size_t num_threads)
{
    if (!num_threads)
        num_threads = 1;

    RestoreTasks completed_tasks;
    bool need_rollback_completed_tasks = true;

    SCOPE_EXIT({
        if (need_rollback_completed_tasks)
            rollbackRestoreTasks(std::move(completed_tasks));
    });

    std::deque<std::unique_ptr<IRestoreTask>> sequential_tasks;
    std::deque<std::unique_ptr<IRestoreTask>> enqueued_tasks;

    /// There are two kinds of restore tasks: sequential and non-sequential ones.
    /// Sequential tasks are executed first and always in one thread.
    for (auto & task : restore_tasks)
    {
        if (task->isSequential())
            sequential_tasks.push_back(std::move(task));
        else
            enqueued_tasks.push_back(std::move(task));
    }

    /// Sequential tasks.
    while (!sequential_tasks.empty())
    {
        auto current_task = std::move(sequential_tasks.front());
        sequential_tasks.pop_front();

        RestoreTasks new_tasks = current_task->run();

        completed_tasks.push_back(std::move(current_task));
        for (auto & task : new_tasks)
        {
            if (task->isSequential())
                sequential_tasks.push_back(std::move(task));
            else
                enqueued_tasks.push_back(std::move(task));
        }
    }

    /// Non-sequential tasks.
    std::unordered_map<IRestoreTask *, std::unique_ptr<IRestoreTask>> running_tasks;
    std::vector<ThreadFromGlobalPool> threads;
    std::mutex mutex;
    std::condition_variable cond;
    std::exception_ptr exception;

    while (true)
    {
        IRestoreTask * current_task = nullptr;
        {
            std::unique_lock lock{mutex};
            cond.wait(lock, [&]
            {
                if (exception)
                    return true;
                if (enqueued_tasks.empty())
                    return running_tasks.empty();
                return (running_tasks.size() < num_threads);
            });

            if (exception || enqueued_tasks.empty())
                break;

            auto current_task_ptr = std::move(enqueued_tasks.front());
            current_task = current_task_ptr.get();
            enqueued_tasks.pop_front();
            running_tasks[current_task] = std::move(current_task_ptr);
        }

        assert(current_task);
        threads.emplace_back([current_task, &mutex, &cond, &enqueued_tasks, &running_tasks, &completed_tasks, &exception]() mutable
        {
            {
                std::lock_guard lock{mutex};
                if (exception)
                    return;
            }

            RestoreTasks new_tasks;
            std::exception_ptr new_exception;
            try
            {
                new_tasks = current_task->run();
            }
            catch (...)
            {
                new_exception = std::current_exception();
            }

            {
                std::lock_guard lock{mutex};
                auto current_task_it = running_tasks.find(current_task);
                auto current_task_ptr = std::move(current_task_it->second);
                running_tasks.erase(current_task_it);

                if (!new_exception)
                {
                    completed_tasks.push_back(std::move(current_task_ptr));
                    enqueued_tasks.insert(
                        enqueued_tasks.end(), std::make_move_iterator(new_tasks.begin()), std::make_move_iterator(new_tasks.end()));
                }

                if (!exception)
                    exception = new_exception;

                cond.notify_all();
            }
        });
    }

    for (auto & thread : threads)
        thread.join();

    if (exception)
        std::rethrow_exception(exception);
    else
        need_rollback_completed_tasks = false;
}

size_t getMinCountOfReplicas(const IBackup & backup)
{
    size_t min_count_of_replicas = static_cast<size_t>(-1);
    for (size_t shard_index : PathsInBackup(backup).getShards())
    {
        size_t count_of_replicas = PathsInBackup(backup).getReplicas(shard_index).size();
        min_count_of_replicas = std::min(min_count_of_replicas, count_of_replicas);
    }
    return min_count_of_replicas;
}

}


text:
#include <boost/asio.hpp>
#include <iostream>
#include <memory>
#include <utility>
#include <vector>
#include <ctime>

using boost::asio::ip::tcp;

class shared_const_buffer
{
public:
	explicit shared_const_buffer(const std::string& data) :
		data_(new std::vector<char>(data.begin(), data.end())),
		buffer_(boost::asio::buffer(*data_))
	{}
	using value_type = boost::asio::const_buffer;
	using const_iterator = const boost::asio::const_buffer*;
	const boost::asio::const_buffer* begin() const { return &buffer_; }
	const boost::asio::const_buffer* end() const { return &buffer_ + 1; }

private:
	std::shared_ptr<std::vector<char> > data_;
	boost::asio::const_buffer buffer_;
};

class session : public std::enable_shared_from_this<session>
{
private:
	// The socket used to communicate with the client.
	tcp::socket socket_;

public:
	session(tcp::socket socket)
		: socket_(std::move(socket))
	{}

	void start()
	{
		do_write();
	}

private:
	void do_write()
	{
		std::time_t now = std::time(0);
		shared_const_buffer buffer(std::ctime(&now));

		auto self(shared_from_this());
		boost::asio::async_write(socket_, buffer,
			[self](boost::system::error_code /*ec*/, std::size_t /*length*/)
			{
			});
	}
};

class server
{
public:
	server(boost::asio::io_context& io_context, short port)
		: acceptor_(io_context, tcp::endpoint(tcp::v4(), port))
	{
		do_accept();
	}

private:
	void do_accept()
	{
		acceptor_.async_accept(
			[this](boost::system::error_code ec, tcp::socket socket)
			{
				if (!ec)
				{
					std::make_shared<session>(std::move(socket))->start();
				}

				do_accept();
			});
	}

	tcp::acceptor acceptor_;
};

int main()
{
	try {
		boost::asio::io_context io_context;
		server s(io_context, 3333);
		io_context.run();
	}
	catch (const std::exception& ex) {
		std::cerr << ex.what() << std::endl;
	}
	return EXIT_SUCCESS;
}

max_stars_repo_name: pvthuyet/books

max_issues_repo_name: pvthuyet/books

max_forks_repo_name: pvthuyet/books


text:
// [===========================================================================]
// [                                M o n e t a                                ]
// [---------------------------------------------------------------------------]
// [                                                                           ]
// [                          Copyright (C) 2005-2015                          ]
// [                      Rodrigo Madera <madera@acm.org>                      ]
// [                                                                           ]
// [---------------------------------------------------------------------------]
// [         Distributed under the Boost Software License, Version 1.0         ]
// [ Read accompanying LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt ]
// [===========================================================================]

#pragma once
#include <boost/function.hpp>
#include <boost/lexical_cast.hpp>
#include <iterator>
#include "write_string.hxx"

namespace moneta { namespace codec { namespace io {

	template <class OutputIterator>
	struct ostringstream {
		typedef ostringstream this_type;

		bool _good;
		size_t _total_written;

		OutputIterator _begin;
		OutputIterator  _end;

		ostringstream(OutputIterator begin, OutputIterator end)
		 : _good(true), _total_written(0), _begin(begin), _end(end) {}

		this_type& operator<<(boost::function<int (OutputIterator, OutputIterator)> callable) {
			if (_good) {
				int result = callable(_begin, _end);
				if (result > 0) {
					_begin += result;
					_total_written += result;
				} else if (result == 0) {
				} else if (result < 0) {
					_good = false;
					_total_written = result;
				}
			}

			return *this;
		}

		this_type& operator<<(const char* string) {
			if (_good) {
				int result = io::write(_begin, _end, string, false);
				if (result > 0) {
					_begin += result;
					_total_written += result;
				} else if (result == 0) {
				} else if (result < 0) {
					_good = false;
					_total_written = result;
				}
			}

			return *this;
		}

		this_type& operator<<(const char c) {
			if (_good) {
				if (_begin != _end) {
					*_begin++ = c;
					++_total_written;
				} else {
					_good = false;
					_total_written = -1;
				}
			}

			return *this;
		}

		this_type& operator<<(const std::string& string) {
			if (_good) {
				int result = io::write(_begin, _end, string.c_str(), false);
				if (result > 0) {
					_begin += result;
					_total_written += result;
				} else if (result == 0) {
				} else if (result < 0) {
					_good = false;
					_total_written = result;
				}
			}

			return *this;
		}

		this_type& operator<<(const std::vector<std::string>& string_vector) {
			std::vector<std::string>::const_iterator itr = string_vector.begin();
			for (; itr != string_vector.end(); ++itr) {
				if (_good) {
					*this << *itr;

					if (itr + 1 != string_vector.end()) {
						*this << ',';
					}
				}
			}

			return *this;
		}

		template <class T>
		typename boost::enable_if<boost::is_pod<T>, this_type&>::type
		operator<<(const T& value) {
			*this << boost::lexical_cast<std::string>(value);
			return *this;
		}

		operator int() const {
			return _total_written;
		}
	};

	template <class OutputOutputIterator>
	ostringstream<OutputOutputIterator> make_ostringstream(OutputOutputIterator begin, OutputOutputIterator end) {
		return ostringstream<OutputOutputIterator>(begin, end);
	}

}}}

ext: hxx

max_stars_repo_name: madera/Moneta

max_issues_repo_name: madera/Moneta

max_forks_repo_name: madera/Moneta


text:
//==============================================================================
//         Copyright 2003 - 2012   LASMEA UMR 6602 CNRS/Univ. Clermont II
//         Copyright 2009 - 2012   LRI    UMR 8623 CNRS/Univ Paris Sud XI
//
//          Distributed under the Boost Software License, Version 1.0.
//                 See accompanying file LICENSE.txt or copy at
//                     http://www.boost.org/LICENSE_1_0.txt
//==============================================================================
#define NT2_UNIT_MODULE "nt2::sub2sub function"

#include <nt2/include/functions/sub2sub.hpp>
#include <boost/array.hpp>
#include <boost/fusion/include/make_vector.hpp>
#include <nt2/sdk/unit/module.hpp>
#include <nt2/sdk/unit/tests/basic.hpp>
#include <nt2/sdk/unit/tests/relation.hpp>

NT2_TEST_CASE( sub2sub_1Dto1D )
{
    using boost::fusion::make_vector;

    boost::array<int, 1> a = nt2::sub2sub( make_vector(3), make_vector(2), make_vector(3) );
    boost::array<int, 1> b = {{2}};
    for(int i=0;i<1;++i) NT2_TEST_EQUAL( a[i], b[i] );
}

NT2_TEST_CASE( sub2sub_2Dto2Did )
{
    using boost::fusion::make_vector;

    boost::array<int, 2> a = nt2::sub2sub( make_vector(3,4), make_vector(2,3), make_vector(3,4) );
    boost::array<int, 2> b = {{2,3}};
    for(int i=0;i<2;++i) NT2_TEST_EQUAL( a[i], b[i] );
}

NT2_TEST_CASE( sub2sub_2Dto2D )
{
    using boost::fusion::make_vector;

    boost::array<int, 2> a = nt2::sub2sub( make_vector(3,4), make_vector(2,4), make_vector(4,3) );
    boost::array<int, 2> b = {{3,3}};
    for(int i=0;i<2;++i) NT2_TEST_EQUAL( a[i], b[i] );
}

NT2_TEST_CASE( sub2sub_1Dto2D )
{
    using boost::fusion::make_vector;

    boost::array<int, 2> a = nt2::sub2sub( make_vector(8), make_vector(3), make_vector(2,4) );
    boost::array<int, 2> b = {{1,2}};
    for(int i=0;i<2;++i) NT2_TEST_EQUAL( a[i], b[i] );
}

NT2_TEST_CASE( sub2sub_2Dto1D )
{
    using boost::fusion::make_vector;

    boost::array<int, 1> a = nt2::sub2sub( make_vector(4,2), make_vector(4,1), make_vector(8) );
    boost::array<int, 1> b = {{4}};
    for(int i=0;i<1;++i) NT2_TEST_EQUAL( a[i], b[i] );
}

NT2_TEST_CASE( sub2sub_3Dto3Did )
{
    using boost::fusion::make_vector;

    boost::array<int, 3> a = nt2::sub2sub( make_vector(3,4,5), make_vector(2,3,4), make_vector(3,4,5) );
    boost::array<int, 3> b = {{2,3,4}};
    for(int i=0;i<3;++i) NT2_TEST_EQUAL( a[i], b[i] );
}

NT2_TEST_CASE( sub2sub_3Dto3D )
{
    using boost::fusion::make_vector;

    boost::array<int, 3> a = nt2::sub2sub( make_vector(3,4,5), make_vector(2,3,4), make_vector(5,4,3) );
    boost::array<int, 3> b = {{4,1,3}};
    for(int i=0;i<3;++i) NT2_TEST_EQUAL( a[i], b[i] );
}

NT2_TEST_CASE( sub2sub_3Dto2D )
{
    using boost::fusion::make_vector;

    boost::array<int, 2> a = nt2::sub2sub(  make_vector(2,2,2), make_vector(1,1,2), make_vector(3,4) );
    boost::array<int, 2> b = {{2,2}};
    for(int i=0;i<2;++i) NT2_TEST_EQUAL( a[i], b[i] );
}

NT2_TEST_CASE( sub2sub_2Dto3D )
{
  using boost::fusion::make_vector;

  boost::array<int, 3> a = nt2::sub2sub( make_vector(3,4), make_vector(2,2), make_vector(2,2,2) );
  boost::array<int, 3> b = {{1,1,2}};
  for(int i=0;i<3;++i) NT2_TEST_EQUAL( a[i], b[i] );
}

NT2_TEST_CASE( sub2sub_1Dto3D )
{
    using boost::fusion::make_vector;

    boost::array<int, 3> a = nt2::sub2sub(  make_vector(24), make_vector(14), make_vector(2,3,4) );
    boost::array<int, 3> b = {{2,1,3}};
    for(int i=0;i<2;++i) NT2_TEST_EQUAL( a[i], b[i] );
}

NT2_TEST_CASE( sub2sub_3Dto1D )
{
    using boost::fusion::make_vector;

    boost::array<int, 1> a = nt2::sub2sub(  make_vector(2,3,4), make_vector(2,1,3), make_vector(24) );
    boost::array<int, 1> b = {{14}};
    for(int i=0;i<1;++i) NT2_TEST_EQUAL( a[i], b[i] );
}