Github user zuyu commented on a diff in the pull request:

    https://github.com/apache/incubator-quickstep/pull/302#discussion_r141770622
  
    --- Diff: query_execution/ExecutionStats.hpp ---
    @@ -0,0 +1,210 @@
    +/**
    + * Licensed to the Apache Software Foundation (ASF) under one
    + * or more contributor license agreements.  See the NOTICE file
    + * distributed with this work for additional information
    + * regarding copyright ownership.  The ASF licenses this file
    + * to you 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.
    + **/
    +
    +#ifndef QUICKSTEP_QUERY_EXECUTION_EXECUTION_STATS_HPP_
    +#define QUICKSTEP_QUERY_EXECUTION_EXECUTION_STATS_HPP_
    +
    +#include <algorithm>
    +#include <cstddef>
    +#include <cstdint>
    +#include <deque>
    +#include <memory>
    +#include <unordered_map>
    +#include <utility>
    +
    +#include "utility/Macros.hpp"
    +
    +#include "glog/logging.h"
    +
    +namespace quickstep {
    +
    +/** \addtogroup QueryExecution
    + *  @{
    + */
    +
    +/**
    + * @brief Record the execution stats of a query.
    + **/
    +class ExecutionStats {
    + public:
    +  /**
    +   * @brief Constructor
    +   *
    +   * @param max_entries The maximum number of entries we remember for each
    +   *        operator.
    +   **/
    +  explicit ExecutionStats(const std::size_t max_entries)
    +      : max_entries_(max_entries) {}
    +
    +  /**
    +   * @brief Get the number of active operators in stats.
    +   **/
    +  const std::size_t getNumActiveOperators() const {
    +    return active_operators_.size();
    +  }
    +
    +  /**
    +   * @brief Check if there are stats present for at least one active 
operator.
    +   **/
    +  inline bool hasStats() const {
    +    for (auto it = active_operators_.begin(); it != 
active_operators_.end(); ++it) {
    +      if (it->second->hasStatsForOperator()) {
    +        return true;
    +      }
    +    }
    +    return false;
    +  }
    +
    +  /**
    +   * @brief Get the current stats for the query.
    +   *
    +   * @return A pair - 1st element is total time, 2nd element is total 
number of
    +   *         WorkOrders for the whole query.
    +   **/
    +  std::pair<std::uint64_t, std::uint64_t> getCurrentStatsForQuery() const {
    +    std::uint64_t total_time = 0;
    +    std::uint64_t num_workorders = 0;
    +    if (!active_operators_.empty()) {
    +      for (auto it = active_operators_.begin(); it != 
active_operators_.end(); ++it) {
    +        auto operator_stats = getCurrentStatsForOperator((it->first));
    +        total_time += operator_stats.first;
    +        num_workorders += operator_stats.second;
    +      }
    +    }
    +    return std::make_pair(total_time, num_workorders);
    +  }
    +
    +  /**
    +   * @brief Get the average work order time for the query.
    +   */
    +  float getAverageWorkOrderTimeForQuery() const {
    +    auto result = getCurrentStatsForQuery();
    +    if (result.second != 0) {
    +      return result.first/static_cast<float>(result.second);
    +    }
    +    return 0.0;
    +  }
    +
    +  /**
    +   * @brief Get the current stats for the given operator.
    +   * @param operator_id The ID of the operator.
    +   * @return A pair - 1st element is total time, 2nd element is total 
number of
    +   *         WorkOrders for the operator.
    +   */
    +  std::pair<std::uint64_t, std::uint64_t> 
getCurrentStatsForOperator(std::size_t operator_id) const {
    +    if (hasOperator(operator_id)) {
    +      DCHECK(active_operators_.at(operator_id).get() != nullptr);
    +      return active_operators_.at(operator_id)->getStats();
    +    }
    +    return std::make_pair(0, 0);
    +  }
    +
    +  float getAverageWorkOrderTimeForOperator(std::size_t operator_id) const {
    +    auto result = getCurrentStatsForOperator(operator_id);
    +    if (result.second != 0) {
    +      return result.first / static_cast<float>(result.second);
    +    }
    +    return 0.0;
    +  }
    +
    +  /**
    +   * @brief Add a new entry to stats.
    +   *
    +   * @param value The value to be added.
    +   * @param operator_index The operator index which the value belongs to.
    +   **/
    +  void addEntry(std::size_t value, std::size_t operator_index) {
    +    if (!hasOperator(operator_index)) {
    +      // This is the first entry for the given operator.
    +      // Create the OperatorStats object for this operator.
    +      active_operators_[operator_index] =
    +          std::unique_ptr<OperatorStats>(new OperatorStats(max_entries_));
    --- End diff --
    
    For exception-safety, use `std::make_unique<OperatorStats>(max_entries_)` 
instead.


---

Reply via email to