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

/**
 * @file
 * @brief: Implementation of PiecewiseLinearConstraint class
 **/

#include "modules/planning/math/smoothing_spline/piecewise_linear_constraint.h"

#include <limits>

namespace apollo {
namespace planning {

namespace {

Eigen::MatrixXd MergeMaxtrices(const std::vector<Eigen::MatrixXd> matrices) {
  int32_t d = 0;
  for (const auto& mat : matrices) {
    d += mat.rows();
  }
  int32_t col = matrices.front().cols();
  Eigen::MatrixXd res = Eigen::MatrixXd::Zero(d, col);
  int32_t index = 0;
  for (const auto& mat : matrices) {
    res.block(index, 0, mat.rows(), mat.cols()) = mat;
    index += mat.rows();
  }
  return res;
}
}

PiecewiseLinearConstraint::PiecewiseLinearConstraint(const uint32_t dimension)
    : dimension_(dimension) {}

Eigen::MatrixXd PiecewiseLinearConstraint::inequality_constraint_matrix()
    const {
  return MergeMaxtrices(inequality_matrices_);
}

Eigen::MatrixXd PiecewiseLinearConstraint::inequality_constraint_boundary()
    const {
  return MergeMaxtrices(inequality_boundaries_);
}

Eigen::MatrixXd PiecewiseLinearConstraint::equality_constraint_matrix() const {
  return MergeMaxtrices(equality_matrices_);
}

Eigen::MatrixXd PiecewiseLinearConstraint::equality_constraint_boundary()
    const {
  return MergeMaxtrices(equality_boundaries_);
}

bool PiecewiseLinearConstraint::AddBoundary(
    const std::vector<uint32_t>& index_list,
    const std::vector<double>& lower_bound,
    const std::vector<double>& upper_bound) {
  // TODO(Liangliang): implement this function
  return true;
}

bool PiecewiseLinearConstraint::AddDerivativeBoundary(
    const std::vector<uint32_t>& index_list,
    const std::vector<double>& lower_bound,
    const std::vector<double>& upper_bound) {
  // TODO(Liangliang): implement this function
  return true;
}

bool PiecewiseLinearConstraint::AddSecondDerivativeBoundary(
    const std::vector<uint32_t>& index_list,
    const std::vector<double>& lower_bound,
    const std::vector<double>& upper_bound) {
  // TODO(Liangliang): implement this function
  return true;
}

bool PiecewiseLinearConstraint::AddThirdDerivativeBoundary(
    const std::vector<uint32_t>& index_list,
    const std::vector<double>& lower_bound,
    const std::vector<double>& upper_bound) {
  // TODO(Liangliang): implement this function
  return true;
}

bool PiecewiseLinearConstraint::AddPointConstraint(const double x,
                                                   const double fx) {
  // TODO(Liangliang): implement this function
  return true;
}

bool PiecewiseLinearConstraint::AddPointDerivativeConstraint(const double x,
                                                             const double dfx) {
  // TODO(Liangliang): implement this function
  return true;
}

bool PiecewiseLinearConstraint::AddPointSecondDerivativeConstraint(
    const double x, const double ddfx) {
  // TODO(Liangliang): implement this function
  return true;
}

bool PiecewiseLinearConstraint::AddPointThirdDerivativeConstraint(
    const double x, const double dddfx) {
  // TODO(Liangliang): implement this function
  return true;
}

bool PiecewiseLinearConstraint::AddMonotoneInequalityConstraint() {
  // TODO(Liangliang): implement this function
  Eigen::MatrixXd inequality_matrix =
      Eigen::MatrixXd::Zero(dimension_ - 1, dimension_ - 1);
  Eigen::MatrixXd inequality_boundary =
      Eigen::MatrixXd::Zero(dimension_ - 1, 1);

  for (uint32_t i = 1; i < dimension_; ++i) {
    inequality_matrix(i, i - 1) = -1.0;
    inequality_matrix(i, i) = 1.0;
  }
  inequality_matrices_.push_back(inequality_matrix);
  inequality_boundaries_.push_back(inequality_boundary);

  return true;
}

}  // namespace planning
}  // namespace apollo
<commit_msg>Planning: added boundary constraint implementation in piecewise linear constraint.<commit_after>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

/**
 * @file
 * @brief: Implementation of PiecewiseLinearConstraint class
 **/

#include "modules/planning/math/smoothing_spline/piecewise_linear_constraint.h"

#include <limits>

namespace apollo {
namespace planning {

namespace {

Eigen::MatrixXd MergeMaxtrices(const std::vector<Eigen::MatrixXd> matrices) {
  int32_t d = 0;
  for (const auto& mat : matrices) {
    d += mat.rows();
  }
  int32_t col = matrices.front().cols();
  Eigen::MatrixXd res = Eigen::MatrixXd::Zero(d, col);
  int32_t index = 0;
  for (const auto& mat : matrices) {
    res.block(index, 0, mat.rows(), mat.cols()) = mat;
    index += mat.rows();
  }
  return res;
}
}

PiecewiseLinearConstraint::PiecewiseLinearConstraint(const uint32_t dimension)
    : dimension_(dimension) {}

Eigen::MatrixXd PiecewiseLinearConstraint::inequality_constraint_matrix()
    const {
  return MergeMaxtrices(inequality_matrices_);
}

Eigen::MatrixXd PiecewiseLinearConstraint::inequality_constraint_boundary()
    const {
  return MergeMaxtrices(inequality_boundaries_);
}

Eigen::MatrixXd PiecewiseLinearConstraint::equality_constraint_matrix() const {
  return MergeMaxtrices(equality_matrices_);
}

Eigen::MatrixXd PiecewiseLinearConstraint::equality_constraint_boundary()
    const {
  return MergeMaxtrices(equality_boundaries_);
}

bool PiecewiseLinearConstraint::AddBoundary(
    const std::vector<uint32_t>& index_list,
    const std::vector<double>& lower_bound,
    const std::vector<double>& upper_bound) {
  if (index_list.size() != lower_bound.size() ||
      index_list.size() != upper_bound.size()) {
    return false;
  }
  Eigen::MatrixXd inequality_matrix =
      Eigen::MatrixXd::Zero(2 * index_list.size(), dimension_);
  Eigen::MatrixXd inequality_boundary =
      Eigen::MatrixXd::Zero(2 * index_list.size(), 1);

  for (uint32_t i = 0; i < index_list.size(); ++i) {
    uint32_t index = index_list[i];
    inequality_matrix(i, index) = -1.0;
    inequality_boundary(i, 0) = -upper_bound[i];
    inequality_matrix(i + 1, index) = 1.0;
    inequality_boundary(i + 1, 0) = lower_bound[i];
  }
  return true;
}

bool PiecewiseLinearConstraint::AddDerivativeBoundary(
    const std::vector<uint32_t>& index_list,
    const std::vector<double>& lower_bound,
    const std::vector<double>& upper_bound) {
  // TODO(Liangliang): implement this function
  return true;
}

bool PiecewiseLinearConstraint::AddSecondDerivativeBoundary(
    const std::vector<uint32_t>& index_list,
    const std::vector<double>& lower_bound,
    const std::vector<double>& upper_bound) {
  // TODO(Liangliang): implement this function
  return true;
}

bool PiecewiseLinearConstraint::AddThirdDerivativeBoundary(
    const std::vector<uint32_t>& index_list,
    const std::vector<double>& lower_bound,
    const std::vector<double>& upper_bound) {
  // TODO(Liangliang): implement this function
  return true;
}

bool PiecewiseLinearConstraint::AddPointConstraint(const double x,
                                                   const double fx) {
  // TODO(Liangliang): implement this function
  return true;
}

bool PiecewiseLinearConstraint::AddPointDerivativeConstraint(const double x,
                                                             const double dfx) {
  // TODO(Liangliang): implement this function
  return true;
}

bool PiecewiseLinearConstraint::AddPointSecondDerivativeConstraint(
    const double x, const double ddfx) {
  // TODO(Liangliang): implement this function
  return true;
}

bool PiecewiseLinearConstraint::AddPointThirdDerivativeConstraint(
    const double x, const double dddfx) {
  // TODO(Liangliang): implement this function
  return true;
}

bool PiecewiseLinearConstraint::AddMonotoneInequalityConstraint() {
  Eigen::MatrixXd inequality_matrix =
      Eigen::MatrixXd::Zero(dimension_ - 1, dimension_ - 1);
  Eigen::MatrixXd inequality_boundary =
      Eigen::MatrixXd::Zero(dimension_ - 1, 1);

  for (uint32_t i = 1; i < dimension_; ++i) {
    inequality_matrix(i, i - 1) = -1.0;
    inequality_matrix(i, i) = 1.0;
  }
  inequality_matrices_.push_back(inequality_matrix);
  inequality_boundaries_.push_back(inequality_boundary);

  return true;
}

}  // namespace planning
}  // namespace apollo
<|endoftext|>


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

/**
 * @file qp_spline_path_generator.cc
 **/
#include <algorithm>
#include <utility>
#include <vector>

#include "modules/planning/optimizer/qp_spline_path/qp_spline_path_generator.h"

#include "modules/common/proto/pnc_point.pb.h"

#include "modules/common/log.h"
#include "modules/common/macro.h"
#include "modules/common/util/file.h"
#include "modules/common/util/util.h"
#include "modules/planning/common/planning_gflags.h"
#include "modules/planning/math/sl_analytic_transformation.h"
#include "modules/planning/optimizer/qp_spline_path/qp_spline_path_sampler.h"

namespace apollo {
namespace planning {

bool QpSplinePathGenerator::Init(const std::string& config_file) {
  if (!common::util::GetProtoFromFile(config_file, &_qp_spline_path_config)) {
    AERROR << "Failed to load config file " << config_file;
    return false;
  }
  return true;
}

bool QpSplinePathGenerator::generate(const ReferenceLine& reference_line,
                                     const DecisionData& decision_data,
                                     const SpeedData& speed_data,
                                     const common::TrajectoryPoint& init_point,
                                     PathData* const path_data) {
  if (!calculate_sl_point(reference_line, init_point, &_init_point)) {
    AERROR << "Fail to map init point: " << init_point.ShortDebugString();
    return false;
  }
  double start_s = _init_point.s();
  double end_s = std::min(reference_line.length(),
                          _init_point.s() + FLAGS_planning_distance);

  QpFrenetFrame qp_frenet_frame(reference_line, decision_data, speed_data,
                                _init_point, start_s, end_s,
                                _qp_spline_path_config.time_resolution());
  if (!qp_frenet_frame.Init(_qp_spline_path_config.num_output())) {
    AERROR << "Fail to initialize qp frenet frame";
    return false;
  }

  if (!init_coord_range(qp_frenet_frame, &start_s, &end_s)) {
    AERROR << "Measure natural coord system with s range failed!";
    return false;
  }

  AINFO << "pss path start with " << start_s << ", end with " << end_s;
  if (!init_smoothing_spline(reference_line, start_s, end_s)) {
    AERROR << "Init smoothing spline failed with (" << start_s << ",  end_s "
           << end_s;
    return false;
  }

  if (!setup_constraint(qp_frenet_frame)) {
    AERROR << "Fail to setup pss path constraint.";
    return false;
  }
  if (!setup_kernel()) {
    AERROR << "Fail to setup pss path kernel.";
    return false;
  }
  if (!solve()) {
    AERROR << "Fail to solve the qp problem.";
    return false;
  }

  AINFO << common::util::StrCat("Spline dl:", _init_point.dl(), ", ddl:",
                                _init_point.ddl());

  // extract data
  const Spline1d& spline = _spline_generator->spline();
  double s_resolution =
      (end_s - _init_point.s()) / _qp_spline_path_config.num_output();
  std::vector<common::PathPoint> path_points;

  double start_l = spline(_init_point.s());
  ReferencePoint ref_point =
      reference_line.get_reference_point(_init_point.s());
  common::math::Vec2d xy_point = SLAnalyticTransformation::calculate_xypoint(
      ref_point.heading(), common::math::Vec2d(ref_point.x(), ref_point.y()),
      start_l);

  double x_diff = xy_point.x() - init_point.path_point().x();
  double y_diff = xy_point.y() - init_point.path_point().y();

  double s = _init_point.s();
  for (std::uint32_t i = 0;
       i <= _qp_spline_path_config.num_output() && s <= end_s; ++i) {
    double l = spline(s);
    double dl = spline.derivative(s);
    double ddl = spline.second_order_derivative(s);
    ReferencePoint ref_point = reference_line.get_reference_point(s);
    common::math::Vec2d xy_point = SLAnalyticTransformation::calculate_xypoint(
        ref_point.heading(), common::math::Vec2d(ref_point.x(), ref_point.y()),
        l);
    xy_point.set_x(xy_point.x() - x_diff);
    xy_point.set_y(xy_point.y() - y_diff);
    double theta = SLAnalyticTransformation::calculate_theta(
        ref_point.heading(), ref_point.kappa(), l, dl);
    double kappa = SLAnalyticTransformation::calculate_kappa(
        ref_point.kappa(), ref_point.dkappa(), l, dl, ddl);
    common::PathPoint path_point = common::util::MakePathPoint(
        xy_point.x(), xy_point.y(), 0.0, theta, kappa, 0.0, 0.0);
    if (path_points.size() != 0) {
      double distance =
          common::util::Distance2D(path_points.back(), path_point);
      path_point.set_s(path_points.back().s() + distance);
    }
    path_points.push_back(std::move(path_point));
    s = _init_point.s() + (i + 1) * s_resolution;
  }
  path_data->set_discretized_path(path_points);
  return true;
}

bool QpSplinePathGenerator::calculate_sl_point(
    const ReferenceLine& reference_line,
    const common::TrajectoryPoint& traj_point,
    common::FrenetFramePoint* const frenet_frame_point) {
  common::SLPoint sl_point;
  if (!reference_line.get_point_in_frenet_frame(
          {traj_point.path_point().x(), traj_point.path_point().y()},
          &sl_point)) {
    return false;
  }
  frenet_frame_point->set_s(sl_point.s());
  frenet_frame_point->set_l(sl_point.l());
  const double theta = traj_point.path_point().theta();
  const double kappa = traj_point.path_point().kappa();
  const double l = frenet_frame_point->l();

  ReferencePoint ref_point =
      reference_line.get_reference_point(frenet_frame_point->s());

  const double theta_ref = ref_point.heading();
  const double kappa_ref = ref_point.kappa();
  const double dkappa_ref = ref_point.dkappa();

  const double dl = SLAnalyticTransformation::calculate_lateral_derivative(
      theta_ref, theta, l, kappa_ref);
  const double ddl =
      SLAnalyticTransformation::calculate_second_order_lateral_derivative(
          theta_ref, theta, kappa_ref, kappa, dkappa_ref, l);
  frenet_frame_point->set_dl(dl);
  frenet_frame_point->set_ddl(ddl);
  return true;
}

bool QpSplinePathGenerator::init_coord_range(
    const QpFrenetFrame& qp_frenet_frame, double* const start_s,
    double* const end_s) {
  // TODO(all): step 1 get current sl coordinate - with init coordinate point
  double start_point = std::max(_init_point.s() - 5.0, 0.0);

  const ReferenceLine& reference_line = qp_frenet_frame.GetReferenceLine();

  double end_point =
      std::min(reference_line.length(), *start_s + FLAGS_planning_distance);

  end_point =
      std::min(qp_frenet_frame.feasible_longitudinal_upper_bound(), end_point);
  *start_s = start_point;
  *end_s = end_point;
  return true;
}

bool QpSplinePathGenerator::init_smoothing_spline(
    const ReferenceLine& reference_line, const double start_s,
    const double end_s) {
  QpSplinePathSampler sampler(_qp_spline_path_config);

  // TODO(all): refine here, add end_s tolorence here
  std::vector<double> sampling_point;
  if (!sampler.Sample(_init_point, reference_line, start_s, end_s - 0.1,
                      &sampling_point)) {
    AERROR << "Qp spline sampler failed!";
    return false;
  }

  _spline_generator.reset(new Spline1dGenerator(
      sampling_point, _qp_spline_path_config.spline_order()));
  return true;
}

bool QpSplinePathGenerator::setup_constraint(
    const QpFrenetFrame& qp_frenet_frame) {
  Spline1dConstraint* spline_constraint =
      _spline_generator->mutable_spline_constraint();
  // add init status constraint
  spline_constraint->add_point_fx_constraint(_init_point.s(), _init_point.l());
  spline_constraint->add_point_derivative_constraint(_init_point.s(),
                                                     _init_point.dl());
  spline_constraint->add_point_second_derivative_constraint(_init_point.s(),
                                                            _init_point.ddl());

  AINFO << "init frenet point: " << _init_point.ShortDebugString();

  // add end point constraint
  const std::vector<double> spline_knots =
      _spline_generator->spline().x_knots();
  if (spline_knots.size() < 2) {
    AERROR << common::util::StrCat("Smoothing spline knot size(",
                                   spline_knots.size(), ") < 2");
    return false;
  }
  double s_length = spline_knots.back() - spline_knots.front();
  if (s_length <= 0) {
    AERROR << common::util::StrCat("Smoothing spline knot length(", s_length,
                                   ") <= 0");
    return false;
  }

  std::pair<double, double> boundary = std::make_pair(0.0, 0.0);
  double end_ref_l = (boundary.first + boundary.second) / 2.0;
  spline_constraint->add_point_fx_constraint(spline_knots.back(), end_ref_l);
  spline_constraint->add_point_derivative_constraint(spline_knots.back(), 0.0);
  spline_constraint->add_point_second_derivative_constraint(spline_knots.back(),
                                                            0.0);
  AINFO << "end frenet point:" << s_length << ", " << end_ref_l
        << ", 0.0, 0.0.";
  const std::vector<double> sampling_knots = spline_knots;

  if (sampling_knots.size() <= 2) {
    return false;
  }

  std::uint32_t num_fx_bound =
      _qp_spline_path_config.number_of_fx_constraint_knots();
  std::vector<double> boundary_low;
  std::vector<double> boundary_high;
  std::vector<double> fx_knots;

  if (num_fx_bound > 1) {
    double ds = (sampling_knots.back() - sampling_knots.front()) / num_fx_bound;
    double s = sampling_knots.front();

    for (std::uint32_t i = 0; i < num_fx_bound + 1; ++i) {
      fx_knots.push_back(s);
      std::pair<double, double> boundary = std::make_pair(0.0, 0.0);
      qp_frenet_frame.get_map_bound(s, &boundary);
      boundary_low.push_back(boundary.first);
      boundary_high.push_back(boundary.second);
      s += ds;
      // calculate boundary here
    }

    if (!spline_constraint->add_fx_boundary(fx_knots, boundary_low,
                                            boundary_high)) {
      AERROR << "Add boundary constraint failed";
      return false;
    }
  }
  // add smooth jointness constraint
  if (!spline_constraint->add_third_derivative_smooth_constraint()) {
    AERROR << "Add spline jointness constraint failed!";
    return false;
  }

  return true;
}

bool QpSplinePathGenerator::setup_kernel() {
  Spline1dKernel* spline_kernel = _spline_generator->mutable_spline_kernel();

  if (_qp_spline_path_config.regularization_weight() > 0) {
    spline_kernel->add_regularization(
        _qp_spline_path_config.regularization_weight());
  }

  if (_qp_spline_path_config.derivative_weight() > 0) {
    spline_kernel->add_derivative_kernel_matrix(
        _qp_spline_path_config.derivative_weight());
  }

  if (_qp_spline_path_config.second_derivative_weight() > 0) {
    spline_kernel->add_second_order_derivative_matrix(
        _qp_spline_path_config.second_derivative_weight());
  }

  if (_qp_spline_path_config.third_derivative_weight() > 0) {
    spline_kernel->add_third_order_derivative_matrix(
        _qp_spline_path_config.third_derivative_weight());
  }

  // TODO(all): Add reference line kernel here
  return true;
}

bool QpSplinePathGenerator::solve() {
  if (!_spline_generator->solve()) {
    AERROR << "Could not solve the qp problem in spline path generator.";
    return false;
  }
  return true;
}

}  // namespace planning
}  // namespace apollo
<commit_msg>fixed a bug which can cause path length exceed reference line.<commit_after>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

/**
 * @file qp_spline_path_generator.cc
 **/
#include <algorithm>
#include <utility>
#include <vector>

#include "modules/planning/optimizer/qp_spline_path/qp_spline_path_generator.h"

#include "modules/common/proto/pnc_point.pb.h"

#include "modules/common/log.h"
#include "modules/common/macro.h"
#include "modules/common/util/file.h"
#include "modules/common/util/util.h"
#include "modules/planning/common/planning_gflags.h"
#include "modules/planning/math/double.h"
#include "modules/planning/math/sl_analytic_transformation.h"
#include "modules/planning/optimizer/qp_spline_path/qp_spline_path_sampler.h"

namespace apollo {
namespace planning {

bool QpSplinePathGenerator::Init(const std::string& config_file) {
  if (!common::util::GetProtoFromFile(config_file, &_qp_spline_path_config)) {
    AERROR << "Failed to load config file " << config_file;
    return false;
  }
  return true;
}

bool QpSplinePathGenerator::generate(const ReferenceLine& reference_line,
                                     const DecisionData& decision_data,
                                     const SpeedData& speed_data,
                                     const common::TrajectoryPoint& init_point,
                                     PathData* const path_data) {
  if (!calculate_sl_point(reference_line, init_point, &_init_point)) {
    AERROR << "Fail to map init point: " << init_point.ShortDebugString();
    return false;
  }
  double start_s = _init_point.s();
  double end_s = std::min(reference_line.length(),
                          _init_point.s() + FLAGS_planning_distance);

  QpFrenetFrame qp_frenet_frame(reference_line, decision_data, speed_data,
                                _init_point, start_s, end_s,
                                _qp_spline_path_config.time_resolution());
  if (!qp_frenet_frame.Init(_qp_spline_path_config.num_output())) {
    AERROR << "Fail to initialize qp frenet frame";
    return false;
  }

  if (!init_coord_range(qp_frenet_frame, &start_s, &end_s)) {
    AERROR << "Measure natural coord system with s range failed!";
    return false;
  }

  AINFO << "pss path start with " << start_s << ", end with " << end_s;
  if (!init_smoothing_spline(reference_line, start_s, end_s)) {
    AERROR << "Init smoothing spline failed with (" << start_s << ",  end_s "
           << end_s;
    return false;
  }

  if (!setup_constraint(qp_frenet_frame)) {
    AERROR << "Fail to setup pss path constraint.";
    return false;
  }
  if (!setup_kernel()) {
    AERROR << "Fail to setup pss path kernel.";
    return false;
  }
  if (!solve()) {
    AERROR << "Fail to solve the qp problem.";
    return false;
  }

  AINFO << common::util::StrCat("Spline dl:", _init_point.dl(), ", ddl:",
                                _init_point.ddl());

  // extract data
  const Spline1d& spline = _spline_generator->spline();
  std::vector<common::PathPoint> path_points;

  double start_l = spline(_init_point.s());
  ReferencePoint ref_point =
      reference_line.get_reference_point(_init_point.s());
  common::math::Vec2d xy_point = SLAnalyticTransformation::calculate_xypoint(
      ref_point.heading(), common::math::Vec2d(ref_point.x(), ref_point.y()),
      start_l);

  double x_diff = xy_point.x() - init_point.path_point().x();
  double y_diff = xy_point.y() - init_point.path_point().y();

  double s = _init_point.s();
  double s_resolution =
      (end_s - _init_point.s()) / _qp_spline_path_config.num_output();
  while (Double::compare(s, end_s) < 0) {
    double l = spline(s);
    double dl = spline.derivative(s);
    double ddl = spline.second_order_derivative(s);
    ReferencePoint ref_point = reference_line.get_reference_point(s);
    common::math::Vec2d xy_point = SLAnalyticTransformation::calculate_xypoint(
        ref_point.heading(), common::math::Vec2d(ref_point.x(), ref_point.y()),
        l);
    xy_point.set_x(xy_point.x() - x_diff);
    xy_point.set_y(xy_point.y() - y_diff);
    double theta = SLAnalyticTransformation::calculate_theta(
        ref_point.heading(), ref_point.kappa(), l, dl);
    double kappa = SLAnalyticTransformation::calculate_kappa(
        ref_point.kappa(), ref_point.dkappa(), l, dl, ddl);
    common::PathPoint path_point = common::util::MakePathPoint(
        xy_point.x(), xy_point.y(), 0.0, theta, kappa, 0.0, 0.0);
    if (path_points.size() != 0) {
      double distance =
          common::util::Distance2D(path_points.back(), path_point);
      path_point.set_s(path_points.back().s() + distance);
    }
    if (Double::compare(path_point.s(), end_s) >= 0) {
      break;
    }
    path_points.push_back(path_point);
    s += s_resolution;
  }
  path_data->set_discretized_path(path_points);
  return true;
}

bool QpSplinePathGenerator::calculate_sl_point(
    const ReferenceLine& reference_line,
    const common::TrajectoryPoint& traj_point,
    common::FrenetFramePoint* const frenet_frame_point) {
  common::SLPoint sl_point;
  if (!reference_line.get_point_in_frenet_frame(
          {traj_point.path_point().x(), traj_point.path_point().y()},
          &sl_point)) {
    return false;
  }
  frenet_frame_point->set_s(sl_point.s());
  frenet_frame_point->set_l(sl_point.l());
  const double theta = traj_point.path_point().theta();
  const double kappa = traj_point.path_point().kappa();
  const double l = frenet_frame_point->l();

  ReferencePoint ref_point =
      reference_line.get_reference_point(frenet_frame_point->s());

  const double theta_ref = ref_point.heading();
  const double kappa_ref = ref_point.kappa();
  const double dkappa_ref = ref_point.dkappa();

  const double dl = SLAnalyticTransformation::calculate_lateral_derivative(
      theta_ref, theta, l, kappa_ref);
  const double ddl =
      SLAnalyticTransformation::calculate_second_order_lateral_derivative(
          theta_ref, theta, kappa_ref, kappa, dkappa_ref, l);
  frenet_frame_point->set_dl(dl);
  frenet_frame_point->set_ddl(ddl);
  return true;
}

bool QpSplinePathGenerator::init_coord_range(
    const QpFrenetFrame& qp_frenet_frame, double* const start_s,
    double* const end_s) {
  // TODO(all): step 1 get current sl coordinate - with init coordinate point
  double start_point = std::max(_init_point.s() - 5.0, 0.0);

  const ReferenceLine& reference_line = qp_frenet_frame.GetReferenceLine();

  double end_point =
      std::min(reference_line.length(), *start_s + FLAGS_planning_distance);

  end_point =
      std::min(qp_frenet_frame.feasible_longitudinal_upper_bound(), end_point);
  *start_s = start_point;
  *end_s = end_point;
  return true;
}

bool QpSplinePathGenerator::init_smoothing_spline(
    const ReferenceLine& reference_line, const double start_s,
    const double end_s) {
  QpSplinePathSampler sampler(_qp_spline_path_config);

  // TODO(all): refine here, add end_s tolorence here
  std::vector<double> sampling_point;
  if (!sampler.Sample(_init_point, reference_line, start_s, end_s - 0.1,
                      &sampling_point)) {
    AERROR << "Qp spline sampler failed!";
    return false;
  }

  _spline_generator.reset(new Spline1dGenerator(
      sampling_point, _qp_spline_path_config.spline_order()));
  return true;
}

bool QpSplinePathGenerator::setup_constraint(
    const QpFrenetFrame& qp_frenet_frame) {
  Spline1dConstraint* spline_constraint =
      _spline_generator->mutable_spline_constraint();
  // add init status constraint
  spline_constraint->add_point_fx_constraint(_init_point.s(), _init_point.l());
  spline_constraint->add_point_derivative_constraint(_init_point.s(),
                                                     _init_point.dl());
  spline_constraint->add_point_second_derivative_constraint(_init_point.s(),
                                                            _init_point.ddl());

  AINFO << "init frenet point: " << _init_point.ShortDebugString();

  // add end point constraint
  const std::vector<double> spline_knots =
      _spline_generator->spline().x_knots();
  if (spline_knots.size() < 2) {
    AERROR << common::util::StrCat("Smoothing spline knot size(",
                                   spline_knots.size(), ") < 2");
    return false;
  }
  double s_length = spline_knots.back() - spline_knots.front();
  if (s_length <= 0) {
    AERROR << common::util::StrCat("Smoothing spline knot length(", s_length,
                                   ") <= 0");
    return false;
  }

  std::pair<double, double> boundary = std::make_pair(0.0, 0.0);
  double end_ref_l = (boundary.first + boundary.second) / 2.0;
  spline_constraint->add_point_fx_constraint(spline_knots.back(), end_ref_l);
  spline_constraint->add_point_derivative_constraint(spline_knots.back(), 0.0);
  spline_constraint->add_point_second_derivative_constraint(spline_knots.back(),
                                                            0.0);
  AINFO << "end frenet point:" << s_length << ", " << end_ref_l
        << ", 0.0, 0.0.";
  const std::vector<double> sampling_knots = spline_knots;

  if (sampling_knots.size() <= 2) {
    return false;
  }

  std::uint32_t num_fx_bound =
      _qp_spline_path_config.number_of_fx_constraint_knots();
  std::vector<double> boundary_low;
  std::vector<double> boundary_high;
  std::vector<double> fx_knots;

  if (num_fx_bound > 1) {
    double ds = (sampling_knots.back() - sampling_knots.front()) / num_fx_bound;
    double s = sampling_knots.front();

    for (std::uint32_t i = 0; i < num_fx_bound + 1; ++i) {
      fx_knots.push_back(s);
      std::pair<double, double> boundary = std::make_pair(0.0, 0.0);
      qp_frenet_frame.get_map_bound(s, &boundary);
      boundary_low.push_back(boundary.first);
      boundary_high.push_back(boundary.second);
      s += ds;
      // calculate boundary here
    }

    if (!spline_constraint->add_fx_boundary(fx_knots, boundary_low,
                                            boundary_high)) {
      AERROR << "Add boundary constraint failed";
      return false;
    }
  }
  // add smooth jointness constraint
  if (!spline_constraint->add_third_derivative_smooth_constraint()) {
    AERROR << "Add spline jointness constraint failed!";
    return false;
  }

  return true;
}

bool QpSplinePathGenerator::setup_kernel() {
  Spline1dKernel* spline_kernel = _spline_generator->mutable_spline_kernel();

  if (_qp_spline_path_config.regularization_weight() > 0) {
    spline_kernel->add_regularization(
        _qp_spline_path_config.regularization_weight());
  }

  if (_qp_spline_path_config.derivative_weight() > 0) {
    spline_kernel->add_derivative_kernel_matrix(
        _qp_spline_path_config.derivative_weight());
  }

  if (_qp_spline_path_config.second_derivative_weight() > 0) {
    spline_kernel->add_second_order_derivative_matrix(
        _qp_spline_path_config.second_derivative_weight());
  }

  if (_qp_spline_path_config.third_derivative_weight() > 0) {
    spline_kernel->add_third_order_derivative_matrix(
        _qp_spline_path_config.third_derivative_weight());
  }

  // TODO(all): Add reference line kernel here
  return true;
}

bool QpSplinePathGenerator::solve() {
  if (!_spline_generator->solve()) {
    AERROR << "Could not solve the qp problem in spline path generator.";
    return false;
  }
  return true;
}

}  // namespace planning
}  // namespace apollo
<|endoftext|>


<commit_before>/*
Copyright 2011, Jernej Kovacic

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.
*/

/**
@file NumericUtil.cpp

Implementation  of the class NumericUtil, a collection of some useful
numerical utilities. This is a templated class and must not be compiled.
Instead it must be included after the class declaration in the .h file

@author Jernej Kovacic
*/

// Delibarately there is no #include "NumericUtil.h"
#include "Rational.h"

// Note that the optimal EPS depends on application requirements
/*
 * Definition of EPS for type float
 */
template<>
float NumericUtil<float>::EPS = 1e-9f;

/*
 * Double is a more accurate type...
 */
template<>
double NumericUtil<double>::EPS = 1e-16;

/*
 * In int and other types, EPS doesn't make sense, so set it to 0
 */
template<class T>
T NumericUtil<T>::EPS = (T) 0;

/*
 * The implementation for integers et al. where the == operator
 * does make sense and no comparison to EPS is necessary.
 */
template<class T>
bool NumericUtil<T>::isZero(T value)
{
    bool retVal = ( 0==value ? true : false );

    return retVal;
}

/*
 * Two specialized implementations for float and double.
 * In case of these two types, the equality operator (==) is useless.
 * In numerical mathematics, two numbers are considered "equal", when
 * absolute value of their difference does not exceed a reasonably set EPS.
 * Both specializations are very similar and only differ in types of an input value.
 * TODO: would it make sense using #define ???
 */

// float:
template<>
bool NumericUtil<float>::isZero(float value)
{
    bool retVal = false;
    // quick definition of an absolute value
    float absValue = ( value>=0 ? value : -value );

    retVal = (absValue < EPS ? true : false );

    return retVal;
}

// and double:
template<>
bool NumericUtil<double>::isZero(double value)
{
    bool retVal = false;
    // quick definition of an absolute value
    double absValue = ( value>=0 ? value : -value );

    retVal = (absValue < EPS ? true : false );

    return retVal;
}

/*
 * Implementation for Rational
 */
template<>
bool NumericUtil<Rational>::isZero(Rational value)
{
    // Rational already contains its own isZero()...
    return value.isZero();
}
<commit_msg>arg. passing<commit_after>/*
Copyright 2011, Jernej Kovacic

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.
*/

/**
@file NumericUtil.cpp

Implementation  of the class NumericUtil, a collection of some useful
numerical utilities. This is a templated class and must not be compiled.
Instead it must be included after the class declaration in the .h file

@author Jernej Kovacic
*/

// Delibarately there is no #include "NumericUtil.h"
#include "Rational.h"

// Note that the optimal EPS depends on application requirements
/*
 * Definition of EPS for type float
 */
template<>
float NumericUtil<float>::EPS = 1e-9f;

/*
 * Double is a more accurate type...
 */
template<>
double NumericUtil<double>::EPS = 1e-16;

/*
 * In int and other types, EPS doesn't make sense, so set it to 0
 */
template<class T>
T NumericUtil<T>::EPS = (T) 0;

/*
 * The implementation for integers et al. where the == operator
 * does make sense and no comparison to EPS is necessary.
 */
template<class T>
bool NumericUtil<T>::isZero(const T& value)
{
    bool retVal = ( 0==value ? true : false );

    return retVal;
}

/*
 * Two specialized implementations for float and double.
 * In case of these two types, the equality operator (==) is useless.
 * In numerical mathematics, two numbers are considered "equal", when
 * absolute value of their difference does not exceed a reasonably set EPS.
 * Both specializations are very similar and only differ in types of an input value.
 * TODO: would it make sense using #define ???
 */

// float:
template<>
bool NumericUtil<float>::isZero(const float& value)
{
    bool retVal = false;
    // quick definition of an absolute value
    float absValue = ( value>=0 ? value : -value );

    retVal = (absValue < EPS ? true : false );

    return retVal;
}

// and double:
template<>
bool NumericUtil<double>::isZero(const double& value)
{
    bool retVal = false;
    // quick definition of an absolute value
    double absValue = ( value>=0 ? value : -value );

    retVal = (absValue < EPS ? true : false );

    return retVal;
}

/*
 * Implementation for Rational
 */
template<>
bool NumericUtil<Rational>::isZero(const Rational& value)
{
    // Rational already contains its own isZero()...
    return value.isZero();
}
<|endoftext|>


<commit_before>// Copyright 2008, Google Inc.
// 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 Google Inc. 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 <windows.h>
#include <string>

#include "base/icu_util.h"

#include "base/logging.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "unicode/udata.h"

namespace icu_util {

bool Initialize() {
  // Assert that we are not called more than once.  Even though calling this
  // function isn't harmful (ICU can handle it), being called twice probably
  // indicates a programming error.
#ifndef DEBUG
  static bool called_once = false;
  DCHECK(!called_once);
  called_once = true;
#endif

  // We expect to find the ICU data module alongside the current module.
  std::wstring data_path;
  PathService::Get(base::DIR_MODULE, &data_path);
  file_util::AppendToPath(&data_path, L"icudt38.dll");

  HMODULE module = LoadLibrary(data_path.c_str());
  if (!module)
    return false;

  FARPROC addr = GetProcAddress(module, "icudt38_dat");
  if (!addr)
    return false;

  UErrorCode err = U_ZERO_ERROR;
  udata_setCommonData(reinterpret_cast<void*>(addr), &err);
  return err == U_ZERO_ERROR;
}

}  // namespace icu_util
<commit_msg>ICU isn't packaged on the Mac as it is on Windows. Review URL: http://chrome-reviews.prom.corp.google.com/1092<commit_after>// Copyright 2008, Google Inc.
// 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 Google Inc. 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 "build/build_config.h"

#ifdef OS_WIN
#include <windows.h>
#endif

#include <string>

#include "base/icu_util.h"

#include "base/logging.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "unicode/udata.h"

namespace icu_util {

bool Initialize() {
#ifdef OS_WIN
  // Assert that we are not called more than once.  Even though calling this
  // function isn't harmful (ICU can handle it), being called twice probably
  // indicates a programming error.
#ifndef NDEBUG
  static bool called_once = false;
  DCHECK(!called_once);
  called_once = true;
#endif

  // We expect to find the ICU data module alongside the current module.
  std::wstring data_path;
  PathService::Get(base::DIR_MODULE, &data_path);
  file_util::AppendToPath(&data_path, L"icudt38.dll");

  HMODULE module = LoadLibrary(data_path.c_str());
  if (!module)
    return false;

  FARPROC addr = GetProcAddress(module, "icudt38_dat");
  if (!addr)
    return false;

  UErrorCode err = U_ZERO_ERROR;
  udata_setCommonData(reinterpret_cast<void*>(addr), &err);
  return err == U_ZERO_ERROR;
#else
  // Windows ships ICU's data separate, so it needs to link the code to data
  // here. Other platforms don't need this.
  return true;
#endif  // OS_WIN
}

}  // namespace icu_util
<|endoftext|>


<commit_before>// key.cc

#include "stdsneezy.h"
#include "obj_open_container.h"
#include "obj_keyring.h"
#include "obj_key.h"
TKey::TKey() :
  TObj()
{
}

TKey::TKey(const TKey &a)
   : TObj(a)
{
}

TKey & TKey::operator=(const TKey &a)
{
  if (this == &a) return *this;
  TObj::operator=(a);
  return *this;
}

TKey::~TKey()
{
}

void TKey::assignFourValues(int, int, int, int)
{
}

void TKey::getFourValues(int *x1, int *x2, int *x3, int *x4) const
{
  *x1 = 0;
  *x2 = 0;
  *x3 = 0;
  *x4 = 0;
}

sstring TKey::statObjInfo() const
{
  char buf[256];
  sprintf(buf, "It is a key to %s", what_does_it_open(this));

  sstring a(buf);
  return a;
}

void TKey::lowCheck()
{
  if ((obj_flags.cost >= 0) && isRentable() &&
           (obj_flags.decay_time <= 0))
    vlogf(LOG_LOW, fmt("rentable key (%s)!") %  getName());

  TObj::lowCheck();
}

bool TKey::objectRepair(TBeing *ch, TMonster *repair, silentTypeT silent)
{
  if (!silent) {

    repair->doTell(fname(ch->name), "Does this look like a locksmithery to you?");
  }
  return TRUE;
}

int TKey::stealModifier()
{
  return 77;   // make keys tough to steal
}

int TKey::putMeInto(TBeing *ch, TOpenContainer *container)
{
  TObj *o;
  TThing *t;
  char buf[256];

  for(t=container->getStuff(); t; t=t->nextThing){
    o = dynamic_cast<TObj *>(t);

    if (!o)
      continue;

    if (dynamic_cast<TKeyring *>(container) &&
	obj_index[getItemIndex()].virt == obj_index[o->getItemIndex()].virt) {
      sprintf(buf, "You already have one of those keys in your %s.\n\r",
	      fname(container->name).c_str());
      ch->sendTo(buf);
      return TRUE;
    }
  }
  return FALSE;
}
<commit_msg>Rentable keys with the [housekey] keyword won't generate LOW errors.<commit_after>// key.cc

#include "stdsneezy.h"
#include "obj_open_container.h"
#include "obj_keyring.h"
#include "obj_key.h"
TKey::TKey() :
  TObj()
{
}

TKey::TKey(const TKey &a)
   : TObj(a)
{
}

TKey & TKey::operator=(const TKey &a)
{
  if (this == &a) return *this;
  TObj::operator=(a);
  return *this;
}

TKey::~TKey()
{
}

void TKey::assignFourValues(int, int, int, int)
{
}

void TKey::getFourValues(int *x1, int *x2, int *x3, int *x4) const
{
  *x1 = 0;
  *x2 = 0;
  *x3 = 0;
  *x4 = 0;
}

sstring TKey::statObjInfo() const
{
  char buf[256];
  sprintf(buf, "It is a key to %s", what_does_it_open(this));

  sstring a(buf);
  return a;
}

void TKey::lowCheck()
{
  if ((obj_flags.cost >= 0) && isRentable() &&
           isname("[housekey]", getName()) &&
           (obj_flags.decay_time <= 0))
    vlogf(LOG_LOW, fmt("rentable key (%s)!") %  getName());

  TObj::lowCheck();
}

bool TKey::objectRepair(TBeing *ch, TMonster *repair, silentTypeT silent)
{
  if (!silent) {

    repair->doTell(fname(ch->name), "Does this look like a locksmithery to you?");
  }
  return TRUE;
}

int TKey::stealModifier()
{
  return 77;   // make keys tough to steal
}

int TKey::putMeInto(TBeing *ch, TOpenContainer *container)
{
  TObj *o;
  TThing *t;
  char buf[256];

  for(t=container->getStuff(); t; t=t->nextThing){
    o = dynamic_cast<TObj *>(t);

    if (!o)
      continue;

    if (dynamic_cast<TKeyring *>(container) &&
	obj_index[getItemIndex()].virt == obj_index[o->getItemIndex()].virt) {
      sprintf(buf, "You already have one of those keys in your %s.\n\r",
	      fname(container->name).c_str());
      ch->sendTo(buf);
      return TRUE;
    }
  }
  return FALSE;
}
<|endoftext|>


<commit_before>/** @file distributed_table_test.cc
 *
 *  @author Dongryeol Lee (dongryel@cc.gatech.edu)
 */
#include "core/metric_kernels/lmetric.h"
#include "core/table/distributed_table.h"
#include "core/table/mailbox.h"
#include "core/tree/gen_kdtree.h"
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>

typedef core::tree::GeneralBinarySpaceTree < core::tree::GenKdTree > TreeType;
typedef core::table::Table<TreeType> TableType;

bool CheckDistributedTableIntegrity(
  const core::table::DistributedTable &table_in,
  const boost::mpi::communicator &world,
  const boost::mpi::communicator &table_outbox_group,
  const boost::mpi::communicator &table_inbox_group) {
  for(int i = 0; i < world.size(); i++) {
    printf(
      "Process %d thinks Process %d owns %d points of dimensionality %d.\n",
      world.rank(), i, table_in.local_n_entries(i % (world.size() / 3)),
      table_in.n_attributes());
  }
  return true;
}

core::table::DistributedTable *InitDistributedTable(
  boost::mpi::communicator &world,
  boost::mpi::communicator &table_outbox_group,
  boost::mpi::communicator &table_inbox_group,
  boost::mpi::communicator &computation_group) {

  std::pair< core::table::DistributedTable *, std::size_t >
  distributed_table_pair =
    core::table::global_m_file_->UniqueFind<core::table::DistributedTable>();
  core::table::DistributedTable *distributed_table =
    distributed_table_pair.first;

  if(distributed_table == NULL) {
    printf("Process %d: TableOutbox.\n", world.rank());

    // Each process generates its own random data, dumps it to the file,
    // and read its own file back into its own distributed table.
    core::table::Table<TreeType> random_dataset;
    const int num_dimensions = 5;
    int num_points = core::math::RandInt(10, 20);
    random_dataset.Init(5, num_points);
    for(int j = 0; j < num_points; j++) {
      core::table::DensePoint point;
      random_dataset.get(j, &point);
      for(int i = 0; i < num_dimensions; i++) {
        point[i] = core::math::Random(0.1, 1.0);
      }
    }
    printf("Process %d generated %d points...\n", world.rank(), num_points);
    std::stringstream file_name_sstr;
    file_name_sstr << "random_dataset_" << world.rank() << ".csv";
    std::string file_name = file_name_sstr.str();
    random_dataset.Save(file_name);

    std::stringstream distributed_table_name_sstr;
    distributed_table_name_sstr << "distributed_table_" << world.rank() << "\n";
    distributed_table = core::table::global_m_file_->UniqueConstruct <
                        core::table::DistributedTable > ();
    distributed_table->Init(
      file_name, table_outbox_group);
    printf(
      "Process %d read in %d points...\n",
      world.rank(), distributed_table->local_n_entries());
  }
  return distributed_table;
}

void TableOutboxProcess(
  core::table::DistributedTable *distributed_table,
  boost::mpi::communicator &world,
  boost::mpi::communicator &table_outbox_group,
  boost::mpi::communicator &table_inbox_group,
  boost::mpi::communicator &computation_group) {

  printf("Process %d: TableOutbox.\n", world.rank());
  distributed_table->RunOutbox(
    table_outbox_group, table_inbox_group, computation_group);
}

void TableInboxProcess(
  core::table::DistributedTable *distributed_table,
  boost::mpi::communicator &world,
  boost::mpi::communicator &table_outbox_group,
  boost::mpi::communicator &table_inbox_group,
  boost::mpi::communicator &computation_group) {
  printf("Process %d: TableInbox.\n", world.rank());

  distributed_table->RunInbox(
    table_outbox_group, table_inbox_group, computation_group);
}

void ComputationProcess(
  core::table::DistributedTable *distributed_table,
  boost::mpi::communicator &world,
  boost::mpi::communicator &table_outbox_group,
  boost::mpi::communicator &table_inbox_group,
  boost::mpi::communicator &computation_group) {

  printf("Process %d: Computation.\n", world.rank());

  // Do a test where each computation process requests a random point
  // from a randomly chosen process.
  int num_points = core::math::RandInt(10, 30);
  for(int n = 0; n < num_points; n++) {
    core::table::DenseConstPoint point;
    int random_request_rank = core::math::RandInt(0, table_outbox_group.size());
    int random_request_point_id =
      core::math::RandInt(
        0, distributed_table->local_n_entries(random_request_rank));
    distributed_table->get(
      table_outbox_group, table_inbox_group,
      random_request_rank, random_request_point_id, &point);

    // Print the point.
    point.Print();

    // Tell the inbox that we are done using the point.
    distributed_table->UnlockPointinTableInbox();
  }
}

int main(int argc, char *argv[]) {

  // Initialize boost MPI.
  boost::mpi::environment env(argc, argv);
  boost::mpi::communicator world;

  if(world.size() <= 1 || world.size() % 3 != 0) {
    std::cout << "Please specify a process number greater than 1 and "
              "a multiple of 3.\n";
    return 0;
  }

  // Delete the teporary files and put a barrier.
  std::stringstream temporary_file_name;
  temporary_file_name << "tmp_file" << world.rank();
  remove(temporary_file_name.str().c_str());
  world.barrier();

  // Initialize the memory allocator.
  core::table::global_m_file_ = new core::table::MemoryMappedFile();
  core::table::global_m_file_->Init(
    std::string("tmp_file"), world.rank(),
    world.rank() % (world.size() / 3), 5000000);

  // Seed the random number.
  srand(time(NULL) + world.rank());

  if(world.rank() == 0) {
    printf("%d processes are present...\n", world.size());
  }

  // If the process ID is less than half of the size of the
  // communicator, make it a table process. Otherwise, make it a
  // computation process. This assignment depends heavily on the
  // round-robin assignment of mpirun.
  boost::mpi::communicator table_outbox_group = world.split(
        (world.rank() < world.size() / 3) ? 1 : 0);
  boost::mpi::communicator table_inbox_group = world.split(
        (world.rank() >= world.size() / 3 &&
         world.rank() < world.size() / 3 * 2) ? 1 : 0);
  boost::mpi::communicator computation_group = world.split(
        (world.rank() >= world.size() / 3 * 2) ? 1 : 0);

  printf("Check: %d %d %d %d\n", world.rank(), table_outbox_group.size(),
         table_inbox_group.size(), computation_group.size());
  return 0;

  core::table::DistributedTable *distributed_table = NULL;

  // Wait until the memory allocator is in synch.
  world.barrier();

  // Read the distributed table once per each compute node, and put a
  // barrier.
  if(world.rank() < world.size() / 3) {
    distributed_table =
      InitDistributedTable(
        world, table_outbox_group, table_inbox_group, computation_group);
  }
  world.barrier();

  // Attach the distributed table for all the processes and put a
  // barrier.
  std::pair< core::table::DistributedTable *, std::size_t >
  distributed_table_pair =
    core::table::global_m_file_->UniqueFind<core::table::DistributedTable>();
  distributed_table = distributed_table_pair.first;

  // Check the integrity of the distributed table.
  CheckDistributedTableIntegrity(
    *distributed_table, world, table_outbox_group, table_inbox_group);

  // The main computation loop.
  if(world.rank() < world.size() / 3) {
    TableOutboxProcess(
      distributed_table, world, table_outbox_group,
      table_inbox_group, computation_group);
  }
  else if(world.rank() < world.size() / 3 * 2) {
    TableInboxProcess(
      distributed_table, world, table_outbox_group,
      table_inbox_group, computation_group);
  }
  else {
    ComputationProcess(
      distributed_table, world,
      table_outbox_group, table_inbox_group, computation_group);
  }

  return 0;
}
<commit_msg>Trying to get communicator (inter) working.<commit_after>/** @file distributed_table_test.cc
 *
 *  @author Dongryeol Lee (dongryel@cc.gatech.edu)
 */
#include "core/metric_kernels/lmetric.h"
#include "core/table/distributed_table.h"
#include "core/table/mailbox.h"
#include "core/tree/gen_kdtree.h"
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>

typedef core::tree::GeneralBinarySpaceTree < core::tree::GenKdTree > TreeType;
typedef core::table::Table<TreeType> TableType;

bool CheckDistributedTableIntegrity(
  const core::table::DistributedTable &table_in,
  const boost::mpi::communicator &world,
  const boost::mpi::communicator &table_outbox_group,
  const boost::mpi::communicator &table_inbox_group) {
  for(int i = 0; i < world.size(); i++) {
    printf(
      "Process %d thinks Process %d owns %d points of dimensionality %d.\n",
      world.rank(), i, table_in.local_n_entries(i % (world.size() / 3)),
      table_in.n_attributes());
  }
  return true;
}

core::table::DistributedTable *InitDistributedTable(
  boost::mpi::communicator &world,
  boost::mpi::communicator &table_outbox_group) {

  std::pair< core::table::DistributedTable *, std::size_t >
  distributed_table_pair =
    core::table::global_m_file_->UniqueFind<core::table::DistributedTable>();
  core::table::DistributedTable *distributed_table =
    distributed_table_pair.first;

  if(distributed_table == NULL) {
    printf("Process %d: TableOutbox.\n", world.rank());

    // Each process generates its own random data, dumps it to the file,
    // and read its own file back into its own distributed table.
    core::table::Table<TreeType> random_dataset;
    const int num_dimensions = 5;
    int num_points = core::math::RandInt(10, 20);
    random_dataset.Init(5, num_points);
    for(int j = 0; j < num_points; j++) {
      core::table::DensePoint point;
      random_dataset.get(j, &point);
      for(int i = 0; i < num_dimensions; i++) {
        point[i] = core::math::Random(0.1, 1.0);
      }
    }
    printf("Process %d generated %d points...\n", world.rank(), num_points);
    std::stringstream file_name_sstr;
    file_name_sstr << "random_dataset_" << world.rank() << ".csv";
    std::string file_name = file_name_sstr.str();
    random_dataset.Save(file_name);

    std::stringstream distributed_table_name_sstr;
    distributed_table_name_sstr << "distributed_table_" << world.rank() << "\n";
    distributed_table = core::table::global_m_file_->UniqueConstruct <
                        core::table::DistributedTable > ();
    distributed_table->Init(
      file_name, table_outbox_group);
    printf(
      "Process %d read in %d points...\n",
      world.rank(), distributed_table->local_n_entries());
  }
  return distributed_table;
}

void TableOutboxProcess(
  core::table::DistributedTable *distributed_table,
  boost::mpi::communicator &world,
  boost::mpi::communicator &table_outbox_group,
  boost::mpi::communicator &table_inbox_group,
  boost::mpi::communicator &computation_group) {

  printf("Process %d: TableOutbox.\n", world.rank());
  distributed_table->RunOutbox(
    table_outbox_group, table_inbox_group, computation_group);
}

void TableInboxProcess(
  core::table::DistributedTable *distributed_table,
  boost::mpi::communicator &world,
  boost::mpi::communicator &table_outbox_group,
  boost::mpi::communicator &table_inbox_group,
  boost::mpi::communicator &computation_group) {
  printf("Process %d: TableInbox.\n", world.rank());

  distributed_table->RunInbox(
    table_outbox_group, table_inbox_group, computation_group);
}

void ComputationProcess(
  core::table::DistributedTable *distributed_table,
  boost::mpi::communicator &world,
  boost::mpi::communicator &table_outbox_group,
  boost::mpi::communicator &table_inbox_group,
  boost::mpi::communicator &computation_group) {

  printf("Process %d: Computation.\n", world.rank());

  // Do a test where each computation process requests a random point
  // from a randomly chosen process.
  int num_points = core::math::RandInt(10, 30);
  for(int n = 0; n < num_points; n++) {
    core::table::DenseConstPoint point;
    int random_request_rank = core::math::RandInt(0, table_outbox_group.size());
    int random_request_point_id =
      core::math::RandInt(
        0, distributed_table->local_n_entries(random_request_rank));
    distributed_table->get(
      table_outbox_group, table_inbox_group,
      random_request_rank, random_request_point_id, &point);

    // Print the point.
    point.Print();

    // Tell the inbox that we are done using the point.
    distributed_table->UnlockPointinTableInbox();
  }
}

int main(int argc, char *argv[]) {

  // Initialize boost MPI.
  boost::mpi::environment env(argc, argv);
  boost::mpi::communicator world;

  if(world.size() <= 1 || world.size() % 3 != 0) {
    std::cout << "Please specify a process number greater than 1 and "
              "a multiple of 3.\n";
    return 0;
  }

  // Delete the teporary files and put a barrier.
  std::stringstream temporary_file_name;
  temporary_file_name << "tmp_file" << world.rank();
  remove(temporary_file_name.str().c_str());
  world.barrier();

  // Initialize the memory allocator.
  core::table::global_m_file_ = new core::table::MemoryMappedFile();
  core::table::global_m_file_->Init(
    std::string("tmp_file"), world.rank(),
    world.rank() % (world.size() / 3), 5000000);

  // Seed the random number.
  srand(time(NULL) + world.rank());

  if(world.rank() == 0) {
    printf("%d processes are present...\n", world.size());
  }

  // If the process ID is less than half of the size of the
  // communicator, make it a table process. Otherwise, make it a
  // computation process. This assignment depends heavily on the
  // round-robin assignment of mpirun.
  boost::mpi::group world_group = world.group();
  std::vector<int> table_outbox_group_vector(world.size() / 3, 0);
  std::vector<int> table_inbox_group_vector(world.size() / 3, 0);
  std::vector<int> computation_group_vector(world.size() / 3, 0);
  for(int i = 0; i < world.size() / 3; i++) {
    table_outbox_group_vector[i] = i;
    table_inbox_group_vector[i] = i + world.size() / 3;
    computation_group_vector[i] = i + world.size() / 3 * 2;
  }

  boost::mpi::group table_outbox_group =
    world_group.include(
      table_outbox_group_vector.begin(), table_outbox_group_vector.end());
  boost::mpi::communicator table_outbox_group_comm(world, table_outbox_group);
  boost::mpi::group table_inbox_group =
    world_group.include(
      table_inbox_group_vector.begin(), table_inbox_group_vector.end());
  boost::mpi::communicator table_inbox_group_comm(world, table_inbox_group);
  boost::mpi::group computation_group =
    world_group.include(
      computation_group_vector.begin(), computation_group_vector.end());
  boost::mpi::communicator computation_group_comm(world, computation_group);

  // Create the intercommunicator between the current process and each
  // of the subgroups.
  //  if(world.rank() >= world.size() / 3) {
  table_outbox_group_vector.push_back(world.rank());
  //}
  //if( world.rank() < world.size() / 3 ||
  //     world.rank() >= world.size() / 3 * 2 ) {
  table_inbox_group_vector.push_back(world.rank());
  //}
  //if( world.rank() < world.size() / 3 * 2) {
  computation_group_vector.push_back(world.rank());
  // }
  boost::mpi::group table_outbox_inter_group =
    world_group.include(
      table_outbox_group_vector.begin(), table_outbox_group_vector.end());
  boost::mpi::communicator table_outbox_group_inter_comm(
    world, table_outbox_inter_group);
  boost::mpi::group table_inbox_inter_group =
    world_group.include(
      table_inbox_group_vector.begin(), table_inbox_group_vector.end());
  boost::mpi::communicator table_inbox_group_inter_comm(
    world, table_inbox_inter_group);
  boost::mpi::group computation_inter_group =
    world_group.include(
      computation_group_vector.begin(), computation_group_vector.end());
  boost::mpi::communicator computation_group_inter_comm(
    world, computation_inter_group);

  // Declare the distributed table.
  core::table::DistributedTable *distributed_table = NULL;

  // Wait until the memory allocator is in synch.
  world.barrier();

  // Read the distributed table once per each compute node, and put a
  // barrier.
  if(world.rank() < world.size() / 3) {
    distributed_table =
      InitDistributedTable(world, table_outbox_group_comm);
  }
  world.barrier();

  // Attach the distributed table for all the processes and put a
  // barrier.
  std::pair< core::table::DistributedTable *, std::size_t >
  distributed_table_pair =
    core::table::global_m_file_->UniqueFind<core::table::DistributedTable>();
  distributed_table = distributed_table_pair.first;

  // Check the integrity of the distributed table.
  CheckDistributedTableIntegrity(
    *distributed_table, world,
    table_outbox_group_inter_comm, table_inbox_group_inter_comm);

  // The main computation loop.
  if(world.rank() < world.size() / 3) {
    TableOutboxProcess(
      distributed_table, world, table_outbox_group_inter_comm,
      table_inbox_group_inter_comm, computation_group_inter_comm);
  }
  else if(world.rank() < world.size() / 3 * 2) {
    TableInboxProcess(
      distributed_table, world, table_outbox_group_inter_comm,
      table_inbox_group_inter_comm, computation_group_inter_comm);
  }
  else {
    ComputationProcess(
      distributed_table, world,
      table_outbox_group_inter_comm, table_inbox_group_inter_comm,
      computation_group_inter_comm);
  }

  return 0;
}
<|endoftext|>


<commit_before>#include <vector>
#include "../lib/hayai/hayai.hpp"
#include "../lib/hayai/hayai_posix_main.cpp"
#include "../src/vector.hpp"

using namespace lsh;

std::vector<bool> c(128);

vector u = vector::random(128);
vector v = vector::random(128);

BENCHMARK(vector, vector, 10000, 200) {
  lsh::vector v(c);
}

BENCHMARK(vector, size, 10000, 75000) {
  v.size();
}

BENCHMARK(vector, get, 10000, 18000) {
  v.get(64);
}

BENCHMARK(vector, equals, 10000, 10000) {
  bool f = v == u;
}

BENCHMARK(vector, dot_product, 10000, 10000) {
  v * u;
}

BENCHMARK(vector, and, 10000, 500) {
  v & u;
}

BENCHMARK(vector, hash, 10000, 28000) {
  v.hash();
}

BENCHMARK(vector, distance, 10000, 9000) {
  vector::distance(u, v);
}

BENCHMARK(vector, random, 10000, 10) {
  vector::random(128);
}
<commit_msg>Increase vector bench iteration count<commit_after>#include <vector>
#include "../lib/hayai/hayai.hpp"
#include "../lib/hayai/hayai_posix_main.cpp"
#include "../src/vector.hpp"

using namespace lsh;

std::vector<bool> c(128);

vector u = vector::random(128);
vector v = vector::random(128);

BENCHMARK(vector, vector, 10000, 300) {
  lsh::vector v(c);
}

BENCHMARK(vector, size, 10000, 75000) {
  v.size();
}

BENCHMARK(vector, get, 10000, 18000) {
  v.get(64);
}

BENCHMARK(vector, equals, 10000, 10000) {
  bool f = v == u;
}

BENCHMARK(vector, dot_product, 10000, 10000) {
  v * u;
}

BENCHMARK(vector, and, 10000, 500) {
  v & u;
}

BENCHMARK(vector, hash, 10000, 28000) {
  v.hash();
}

BENCHMARK(vector, distance, 10000, 9000) {
  vector::distance(u, v);
}

BENCHMARK(vector, random, 10000, 10) {
  vector::random(128);
}
<|endoftext|>


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

#include <iostream>
#include <boost/shared_ptr.hpp>
#ifdef DEBUG_ELEMENT
#include "ooxmlLoggers.hxx"
#include <resourcemodel/Protocol.hxx>
#endif
#include "OOXMLFastDocumentHandler.hxx"
#include "OOXMLFastContextHandler.hxx"
#include "OOXMLFastTokens.hxx"
#include "OOXMLFactory.hxx"

namespace writerfilter {
namespace ooxml
{
using namespace ::com::sun::star;
using namespace ::std;

OOXMLFastDocumentHandler::OOXMLFastDocumentHandler
(uno::Reference< uno::XComponentContext > const & context)
: m_xContext(context)
{}

// ::com::sun::star::xml::sax::XFastContextHandler:
void SAL_CALL OOXMLFastDocumentHandler::startFastElement
(::sal_Int32
#ifdef DEBUG_CONTEXT_STACK
Element
#endif
, const uno::Reference< xml::sax::XFastAttributeList > & /*Attribs*/)
    throw (uno::RuntimeException, xml::sax::SAXException)
{
#ifdef DEBUG_CONTEXT_STACK
    clog << this << ":start element:"
         << fastTokenToId(Element)
         << endl;
#endif
}

void SAL_CALL OOXMLFastDocumentHandler::startUnknownElement
(const ::rtl::OUString &
#ifdef DEBUG_CONTEXT_STACK
Namespace
#endif
, const ::rtl::OUString &
#ifdef DEBUG_CONTEXT_STACK
Name
#endif
,
 const uno::Reference< xml::sax::XFastAttributeList > & /*Attribs*/)
throw (uno::RuntimeException, xml::sax::SAXException)
{
#ifdef DEBUG_CONTEXT_STACK
    clog << this << ":start unknown element:"
         << OUStringToOString(Namespace, RTL_TEXTENCODING_ASCII_US).getStr()
         << ":"
         << OUStringToOString(Name, RTL_TEXTENCODING_ASCII_US).getStr()
         << endl;
#endif
}

void SAL_CALL OOXMLFastDocumentHandler::endFastElement(::sal_Int32
#ifdef DEBUG_CONTEXT_STACK
Element
#endif
)
throw (uno::RuntimeException, xml::sax::SAXException)
{
#ifdef DEBUG_CONTEXT_STACK
    clog << this << ":end element:"
         << fastTokenToId(Element)
         << endl;
#endif
}

void SAL_CALL OOXMLFastDocumentHandler::endUnknownElement
(const ::rtl::OUString &
#ifdef DEBUG_CONTEXT_STACK
Namespace
#endif
, const ::rtl::OUString &
#ifdef DEBUG_CONTEXT_STACK
Name
#endif
)
throw (uno::RuntimeException, xml::sax::SAXException)
{
#ifdef DEBUG_CONTEXT_STACK
    clog << this << ":end unknown element:"
         << OUStringToOString(Namespace, RTL_TEXTENCODING_ASCII_US).getStr()
         << ":"
         << OUStringToOString(Name, RTL_TEXTENCODING_ASCII_US).getStr()
         << endl;
#endif
}

OOXMLFastContextHandler::Pointer_t
OOXMLFastDocumentHandler::getContextHandler() const
{
    if (mpContextHandler == OOXMLFastContextHandler::Pointer_t())
    {
        mpContextHandler.reset
        (new OOXMLFastContextHandler(m_xContext));
        mpContextHandler->setStream(mpStream);
        mpContextHandler->setDocument(mpDocument);
        mpContextHandler->setXNoteId(msXNoteId);
        mpContextHandler->setForwardEvents(true);
    }

    return mpContextHandler;
}

uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
 OOXMLFastDocumentHandler::createFastChildContext
(::sal_Int32 Element,
 const uno::Reference< xml::sax::XFastAttributeList > & /*Attribs*/)
    throw (uno::RuntimeException, xml::sax::SAXException)
{
#ifdef DEBUG_CONTEXT_STACK
    clog << this << ":createFastChildContext:"
         << fastTokenToId(Element)
         << endl;
#endif

    return OOXMLFactory::getInstance()->createFastChildContextFromStart(getContextHandler().get(), Element);
}

OOXMLParserState::Pointer_t OOXMLFastDocumentHandler::getParserState() const
{
    OOXMLParserState::Pointer_t pParserState;

    return getContextHandler()->getParserState();
}

uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
OOXMLFastDocumentHandler::createUnknownChildContext
(const ::rtl::OUString &
#ifdef DEBUG_CONTEXT_STACK
Namespace
#endif
,
 const ::rtl::OUString &
#ifdef DEBUG_CONTEXT_STACK
Name
#endif
, const uno::Reference< xml::sax::XFastAttributeList > & /*Attribs*/)
    throw (uno::RuntimeException, xml::sax::SAXException)
{
#ifdef DEBUG_CONTEXT_STACK
    clog << this << ":createUnknownChildContext:"
         << OUStringToOString(Namespace, RTL_TEXTENCODING_ASCII_US).getStr()
         << ":"
         << OUStringToOString(Name, RTL_TEXTENCODING_ASCII_US).getStr()
         << endl;
#endif

    return uno::Reference< xml::sax::XFastContextHandler >
        (new OOXMLFastDocumentHandler(m_xContext));
}

void SAL_CALL OOXMLFastDocumentHandler::characters(const ::rtl::OUString & /*aChars*/)
    throw (uno::RuntimeException, xml::sax::SAXException)
{
    // TODO: Insert your implementation for "characters" here.
}

// ::com::sun::star::xml::sax::XFastDocumentHandler:
void SAL_CALL OOXMLFastDocumentHandler::startDocument()
    throw (uno::RuntimeException, xml::sax::SAXException)
{
}

void SAL_CALL OOXMLFastDocumentHandler::endDocument()
    throw (uno::RuntimeException, xml::sax::SAXException)
{
#ifdef DEBUG_CONTEXT_STACK
    OOXMLFastContextHandler::dumpOpenContexts();
#endif
}

void SAL_CALL OOXMLFastDocumentHandler::setDocumentLocator
(const uno::Reference< xml::sax::XLocator > & /*xLocator*/)
    throw (uno::RuntimeException, xml::sax::SAXException)
{
    // TODO: Insert your implementation for "setDocumentLocator" here.
}

void OOXMLFastDocumentHandler::setStream(Stream * pStream)
{
#ifdef DEBUG_PROTOCOL
    mpTmpStream.reset(new StreamProtocol(pStream, debug_logger));
    mpStream = mpTmpStream.get();
#else
    mpStream = pStream;
#endif
}

void OOXMLFastDocumentHandler::setDocument(OOXMLDocument * pDocument)
{
    mpDocument = pDocument;
}

void OOXMLFastDocumentHandler::setXNoteId(const ::rtl::OUString & rXNoteId)
{
    msXNoteId = rXNoteId;
}

void OOXMLFastDocumentHandler::setIsSubstream( bool bSubstream )
{
    getContextHandler( )->getParserState( )->setInSectionGroup( bSubstream );
}

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

#include <iostream>
#include <boost/shared_ptr.hpp>
#ifdef DEBUG_ELEMENT
#include "ooxmlLoggers.hxx"
#include <resourcemodel/Protocol.hxx>
#endif
#include "OOXMLFastDocumentHandler.hxx"
#include "OOXMLFastContextHandler.hxx"
#include "OOXMLFastTokens.hxx"
#include "OOXMLFactory.hxx"

namespace writerfilter {
namespace ooxml
{
using namespace ::com::sun::star;
using namespace ::std;

OOXMLFastDocumentHandler::OOXMLFastDocumentHandler
(uno::Reference< uno::XComponentContext > const & context)
: m_xContext(context)
{}

// ::com::sun::star::xml::sax::XFastContextHandler:
void SAL_CALL OOXMLFastDocumentHandler::startFastElement
(::sal_Int32
#ifdef DEBUG_CONTEXT_STACK
Element
#endif
, const uno::Reference< xml::sax::XFastAttributeList > & /*Attribs*/)
    throw (uno::RuntimeException, xml::sax::SAXException)
{
#ifdef DEBUG_CONTEXT_STACK
    clog << this << ":start element:"
         << fastTokenToId(Element)
         << endl;
#endif
}

void SAL_CALL OOXMLFastDocumentHandler::startUnknownElement
(const ::rtl::OUString &
#ifdef DEBUG_CONTEXT_STACK
Namespace
#endif
, const ::rtl::OUString &
#ifdef DEBUG_CONTEXT_STACK
Name
#endif
,
 const uno::Reference< xml::sax::XFastAttributeList > & /*Attribs*/)
throw (uno::RuntimeException, xml::sax::SAXException)
{
#ifdef DEBUG_CONTEXT_STACK
    clog << this << ":start unknown element:"
         << OUStringToOString(Namespace, RTL_TEXTENCODING_ASCII_US).getStr()
         << ":"
         << OUStringToOString(Name, RTL_TEXTENCODING_ASCII_US).getStr()
         << endl;
#endif
}

void SAL_CALL OOXMLFastDocumentHandler::endFastElement(::sal_Int32
#ifdef DEBUG_CONTEXT_STACK
Element
#endif
)
throw (uno::RuntimeException, xml::sax::SAXException)
{
#ifdef DEBUG_CONTEXT_STACK
    clog << this << ":end element:"
         << fastTokenToId(Element)
         << endl;
#endif
}

void SAL_CALL OOXMLFastDocumentHandler::endUnknownElement
(const ::rtl::OUString &
#ifdef DEBUG_CONTEXT_STACK
Namespace
#endif
, const ::rtl::OUString &
#ifdef DEBUG_CONTEXT_STACK
Name
#endif
)
throw (uno::RuntimeException, xml::sax::SAXException)
{
#ifdef DEBUG_CONTEXT_STACK
    clog << this << ":end unknown element:"
         << OUStringToOString(Namespace, RTL_TEXTENCODING_ASCII_US).getStr()
         << ":"
         << OUStringToOString(Name, RTL_TEXTENCODING_ASCII_US).getStr()
         << endl;
#endif
}

OOXMLFastContextHandler::Pointer_t
OOXMLFastDocumentHandler::getContextHandler() const
{
    if (mpContextHandler == OOXMLFastContextHandler::Pointer_t())
    {
        mpContextHandler.reset
        (new OOXMLFastContextHandler(m_xContext));
        mpContextHandler->setStream(mpStream);
        mpContextHandler->setDocument(mpDocument);
        mpContextHandler->setXNoteId(msXNoteId);
        mpContextHandler->setForwardEvents(true);
    }

    return mpContextHandler;
}

uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
 OOXMLFastDocumentHandler::createFastChildContext
(::sal_Int32 Element,
 const uno::Reference< xml::sax::XFastAttributeList > & /*Attribs*/)
    throw (uno::RuntimeException, xml::sax::SAXException)
{
#ifdef DEBUG_CONTEXT_STACK
    clog << this << ":createFastChildContext:"
         << fastTokenToId(Element)
         << endl;
#endif

    return OOXMLFactory::getInstance()->createFastChildContextFromStart(getContextHandler().get(), Element);
}

OOXMLParserState::Pointer_t OOXMLFastDocumentHandler::getParserState() const
{
    OOXMLParserState::Pointer_t pParserState;

    return getContextHandler()->getParserState();
}

uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
OOXMLFastDocumentHandler::createUnknownChildContext
(const ::rtl::OUString &
#ifdef DEBUG_CONTEXT_STACK
Namespace
#endif
,
 const ::rtl::OUString &
#ifdef DEBUG_CONTEXT_STACK
Name
#endif
, const uno::Reference< xml::sax::XFastAttributeList > & /*Attribs*/)
    throw (uno::RuntimeException, xml::sax::SAXException)
{
#ifdef DEBUG_CONTEXT_STACK
    clog << this << ":createUnknownChildContext:"
         << OUStringToOString(Namespace, RTL_TEXTENCODING_ASCII_US).getStr()
         << ":"
         << OUStringToOString(Name, RTL_TEXTENCODING_ASCII_US).getStr()
         << endl;
#endif

    return uno::Reference< xml::sax::XFastContextHandler >
        (new OOXMLFastDocumentHandler(m_xContext));
}

void SAL_CALL OOXMLFastDocumentHandler::characters(const ::rtl::OUString & /*aChars*/)
    throw (uno::RuntimeException, xml::sax::SAXException)
{
    // TODO: Insert your implementation for "characters" here.
}

// ::com::sun::star::xml::sax::XFastDocumentHandler:
void SAL_CALL OOXMLFastDocumentHandler::startDocument()
    throw (uno::RuntimeException, xml::sax::SAXException)
{
}

void SAL_CALL OOXMLFastDocumentHandler::endDocument()
    throw (uno::RuntimeException, xml::sax::SAXException)
{
}

void SAL_CALL OOXMLFastDocumentHandler::setDocumentLocator
(const uno::Reference< xml::sax::XLocator > & /*xLocator*/)
    throw (uno::RuntimeException, xml::sax::SAXException)
{
    // TODO: Insert your implementation for "setDocumentLocator" here.
}

void OOXMLFastDocumentHandler::setStream(Stream * pStream)
{
#ifdef DEBUG_PROTOCOL
    mpTmpStream.reset(new StreamProtocol(pStream, debug_logger));
    mpStream = mpTmpStream.get();
#else
    mpStream = pStream;
#endif
}

void OOXMLFastDocumentHandler::setDocument(OOXMLDocument * pDocument)
{
    mpDocument = pDocument;
}

void OOXMLFastDocumentHandler::setXNoteId(const ::rtl::OUString & rXNoteId)
{
    msXNoteId = rXNoteId;
}

void OOXMLFastDocumentHandler::setIsSubstream( bool bSubstream )
{
    getContextHandler( )->getParserState( )->setInSectionGroup( bSubstream );
}

}}
<|endoftext|>