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

#include "kudu/common/iterator_stats.h"

#include <glog/logging.h>

#include "kudu/gutil/strings/substitute.h"

namespace kudu {

using std::string;
using strings::Substitute;

IteratorStats::IteratorStats()
    : cells_read(0),
      bytes_read(0),
      blocks_read(0),
      predicates_disabled(0) {
}

string IteratorStats::ToString() const {
  return Substitute("cells_read=$0 bytes_read=$1 blocks_read=$2 predicates_disabled=$3",
                    cells_read, bytes_read, blocks_read, predicates_disabled);
}

IteratorStats& IteratorStats::operator+=(const IteratorStats& other) {
  cells_read += other.cells_read;
  bytes_read += other.bytes_read;
  blocks_read += other.blocks_read;
  predicates_disabled += other.predicates_disabled;
  DCheckNonNegative();
  return *this;
}

IteratorStats& IteratorStats::operator-=(const IteratorStats& other) {
  cells_read -= other.cells_read;
  bytes_read -= other.bytes_read;
  blocks_read -= other.blocks_read;
  predicates_disabled -= other.predicates_disabled;
  DCheckNonNegative();
  return *this;
}

IteratorStats IteratorStats::operator+(const IteratorStats& other) {
  IteratorStats copy = *this;
  copy += other;
  return copy;
}

IteratorStats IteratorStats::operator-(const IteratorStats& other) {
  IteratorStats copy = *this;
  copy -= other;
  return copy;
}

void IteratorStats::DCheckNonNegative() const {
  DCHECK_GE(cells_read, 0);
  DCHECK_GE(bytes_read, 0);
  DCHECK_GE(blocks_read, 0);
  DCHECK_GE(predicates_disabled, 0);
}
} // namespace kudu
