// 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.
syntax = "proto2";
package kudu;

option java_package = "org.apache.kudu";

// Captures the state of an Histogram.
message HistogramSnapshotPB {
  required string type = 1;
  required string name = 2;
  optional string description = 3;
  required string unit = 4;
  optional string label = 19;

  required uint64 max_trackable_value = 5;
  required int32 num_significant_digits = 6;
  required uint64 total_count = 7;
  optional uint64 total_sum = 18;
  required uint64 min = 8;
  required double mean = 9;
  required uint64 percentile_75 = 10;
  required uint64 percentile_95 = 11;
  required uint64 percentile_99 = 12;
  required uint64 percentile_99_9 = 13;
  required uint64 percentile_99_99 = 14;
  required uint64 max = 15;
  repeated uint64 values = 16 [packed = true];
  repeated uint64 counts = 17 [packed = true];
}

message HistogramSnapshotsListPB {
  repeated HistogramSnapshotPB histograms = 1;
}
