syntax = "proto2";

import "cockroach/proto/api.proto";
import "cockroach/proto/config.proto";
import "cockroach/proto/data.proto";
package cockroach.proto;

option go_package = "proto";

// TxnPushType determines what action to take when pushing a
//  transaction.
enum PushTxnType {
  // Push the timestamp forward if possible to accommodate a concurrent reader.
  PUSH_TIMESTAMP = 0;
  // Abort the transaction if possible to accommodate a concurrent writer.
  ABORT_TXN = 1;
  // Cleanup the transaction if already committed/aborted, or if too old.
  CLEANUP_TXN = 2;
}

// InternalValueType defines a set of string constants placed in the "tag" field
//  of Value messages which are created internally. These are defined as a
//  protocol buffer enumeration so that they can be used portably between our Go
//  and C code.
enum InternalValueType {
  // _CR_TS is applied to values which contain InternalTimeSeriesData. This
  //  tag is used by the RocksDB Merge Operator to perform a specialized merge
  //  for this data.
  _CR_TS = 1;
}

// An InternalRangeLookupRequest is arguments to the
//  InternalRangeLookup() method. It specifies the key for which the
//  containing range is being requested, and the maximum number of
//  total range descriptors that should be returned, if there are
//  additional consecutive addressable ranges. Specify max_ranges > 1
//  to pre-fill the range descriptor cache.
message InternalRangeLookupRequest {
  optional .cockroach.proto.RequestHeader header = 1;
  optional int32 max_ranges = 2;
  // Ignore intents indicates whether or not intents encountered
  //  while looking up the range info should be resolved. This should
  //  be false in general, except for the case where the lookup is
  //  already in service of pushing intents on meta records. Attempting
  //  to resolve intents in this case would lead to infinite recursion.
  optional bool ignore_intents = 3;
}

// An InternalRangeLookupResponse is the return value from the
//  InternalRangeLookup() method. It returns metadata for the range
//  containing the requested key, optionally returning the metadata for
//  additional consecutive ranges beyond the requested range to pre-fill
//  the range descriptor cache.
message InternalRangeLookupResponse {
  optional .cockroach.proto.ResponseHeader header = 1;
  repeated .cockroach.proto.RangeDescriptor ranges = 2;
}

// An InternalHeartbeatTxnRequest is arguments to the
//  InternalHeartbeatTxn() method. It's sent by transaction
//  coordinators to let the system know that the transaction is still
//  ongoing. Note that this heartbeat message is different from the
//  heartbeat message in the gossip protocol.
message InternalHeartbeatTxnRequest {
  optional .cockroach.proto.RequestHeader header = 1;
}

// An InternalHeartbeatTxnResponse is the return value from the
//  InternalHeartbeatTxn() method. It returns the transaction info in
//  the response header. The returned transaction lets the coordinator
//  know the disposition of the transaction (i.e. aborted, committed or
//  pending).
message InternalHeartbeatTxnResponse {
  optional .cockroach.proto.ResponseHeader header = 1;
}

// An InternalGCRequest is arguments to the InternalGC() method. It's
//  sent by range leaders after scanning range data to find expired
//  MVCC values.
message InternalGCRequest {
  message GCKey {
    optional bytes key = 1;
    optional .cockroach.proto.Timestamp timestamp = 2;
  }
  optional .cockroach.proto.RequestHeader header = 1;
  optional .cockroach.proto.GCMetadata gc_meta = 2;
  repeated .cockroach.proto.InternalGCRequest.GCKey keys = 3;
}

// An InternalGCResponse is the return value from the InternalGC()
//  method.
message InternalGCResponse {
  optional .cockroach.proto.ResponseHeader header = 1;
}

// An InternalPushTxnRequest is arguments to the InternalPushTxn()
//  method. It's sent by readers or writers which have encountered an
//  "intent" laid down by another transaction. The goal is to resolve
//  the conflict. Note that args.Key should be set to the txn ID of
//  args.PusheeTxn, not args.Txn, as is usual. This RPC is addressed
//  to the range which owns the pushee's txn record.
//  Resolution is trivial if the txn which owns the intent has either
//  been committed or aborted already. Otherwise, the existing txn can
//  either be aborted (for write/write conflicts), or its commit
//  timestamp can be moved forward (for read/write conflicts). The
//  course of action is determined by the specified push type, and by
//  the owning txn's status and priority.
message InternalPushTxnRequest {
  optional .cockroach.proto.RequestHeader header = 1;
  optional .cockroach.proto.Transaction pushee_txn = 2;
  // Readers set this to PUSH_TIMESTAMP to move PusheeTxn's commit
  //  timestamp forward. Writers set this to ABORT_TXN to request that
  //  the PushTxn be aborted if possible. This is done in the event of
  //  a writer conflicting with PusheeTxn. Inconsistent readers set
  //  this to CLEANUP_TXN to determine whether dangling intents
  //  may be resolved.
  optional .cockroach.proto.PushTxnType push_type = 3;
  // Range lookup indicates whether we're pushing a txn because of an
  //  intent encountered while servicing an internal range lookup
  //  request. See notes in InternalLookupRangeRequest.
  optional bool range_lookup = 4;
}

// An InternalPushTxnResponse is the return value from the
//  InternalPushTxn() method. It returns success and the resulting
//  state of PusheeTxn if the conflict was resolved in favor of the
//  caller; the caller should subsequently invoke
//  InternalResolveIntent() on the conflicted key. It returns an error
//  otherwise.
message InternalPushTxnResponse {
  optional .cockroach.proto.ResponseHeader header = 1;
  // Txn is non-nil if the transaction could be heartbeat and contains
  //  the current value of the transaction.
  optional .cockroach.proto.Transaction pushee_txn = 2;
}

// An InternalResolveIntentRequest is arguments to the
//  InternalResolveIntent() method. It is sent by transaction
//  coordinators and after success calling InternalPushTxn to clean up
//  write intents: either to remove them or commit them.
message InternalResolveIntentRequest {
  optional .cockroach.proto.RequestHeader header = 1;
}

// An InternalResolveIntentResponse is the return value from the
//  InternalResolveIntent() method.
message InternalResolveIntentResponse {
  optional .cockroach.proto.ResponseHeader header = 1;
}

// An InternalMergeRequest contains arguments to the InternalMerge() method. It
//  specifies a key and a value which should be merged into the existing value at
//  that key.
message InternalMergeRequest {
  optional .cockroach.proto.RequestHeader header = 1;
  optional .cockroach.proto.Value value = 2;
}

// InternalMergeResponse is the response to an InternalMerge() operation.
message InternalMergeResponse {
  optional .cockroach.proto.ResponseHeader header = 1;
}

// InternalTruncateLogRequest is used to remove a prefix of the raft log. While there
//  is no requirement for correctness that the raft log truncation be synchronized across
//  replicas, it is nice to preserve the property that all replicas of a range are as close
//  to identical as possible. The raft leader can also inform decisions about the cutoff point
//  with its knowledge of the replicas' acknowledgement status.
message InternalTruncateLogRequest {
  optional .cockroach.proto.RequestHeader header = 1;
  // Log entries < this index are to be discarded.
  optional uint64 index = 2;
}

// InternalTruncateLogResponse is the response to an InternalTruncateLog() operation.
message InternalTruncateLogResponse {
  optional .cockroach.proto.ResponseHeader header = 1;
}

// An InternalLeaderLeaseRequest is arguments to the InternalLeaderLease()
//  method. It is sent by the store on behalf of one of its ranges upon receipt
//  of a leader election event for that range.
message InternalLeaderLeaseRequest {
  optional .cockroach.proto.RequestHeader header = 1;
  optional .cockroach.proto.Lease lease = 2;
}

// An InternalLeaderLeaseResponse is the response to an InternalLeaderLease()
//  operation.
message InternalLeaderLeaseResponse {
  optional .cockroach.proto.ResponseHeader header = 1;
}

// An InternalRequestUnion contains exactly one of the optional requests.
//  Non-internal values added to RequestUnion must be added here.
message InternalRequestUnion {
   oneof value {
    .cockroach.proto.ContainsRequest contains = 1;
    .cockroach.proto.GetRequest get = 2;
    .cockroach.proto.PutRequest put = 3;
    .cockroach.proto.ConditionalPutRequest conditional_put = 4;
    .cockroach.proto.IncrementRequest increment = 5;
    .cockroach.proto.DeleteRequest delete = 6;
    .cockroach.proto.DeleteRangeRequest delete_range = 7;
    .cockroach.proto.ScanRequest scan = 8;
    .cockroach.proto.EndTransactionRequest end_transaction = 9;
    .cockroach.proto.InternalPushTxnRequest internal_push_txn = 30;
    .cockroach.proto.InternalResolveIntentRequest internal_resolve_intent = 31;
  }
}

// An InternalResponseUnion contains exactly one of the optional responses.
//  Non-internal values added to ResponseUnion must be added here.
message InternalResponseUnion {
   oneof value {
    .cockroach.proto.ContainsResponse contains = 1;
    .cockroach.proto.GetResponse get = 2;
    .cockroach.proto.PutResponse put = 3;
    .cockroach.proto.ConditionalPutResponse conditional_put = 4;
    .cockroach.proto.IncrementResponse increment = 5;
    .cockroach.proto.DeleteResponse delete = 6;
    .cockroach.proto.DeleteRangeResponse delete_range = 7;
    .cockroach.proto.ScanResponse scan = 8;
    .cockroach.proto.EndTransactionResponse end_transaction = 9;
    .cockroach.proto.InternalPushTxnResponse internal_push_txn = 30;
    .cockroach.proto.InternalResolveIntentResponse internal_resolve_intent = 31;
  }
}

// An InternalBatchRequest contains a superset of commands from
//  BatchRequest and internal batchable commands.
//  See comments for BatchRequest.
message InternalBatchRequest {
  optional .cockroach.proto.RequestHeader header = 1;
  repeated .cockroach.proto.InternalRequestUnion requests = 2;
}

// An InternalBatchResponse contains command responses.
//  See comments for BatchResponse.
message InternalBatchResponse {
  optional .cockroach.proto.ResponseHeader header = 1;
  repeated .cockroach.proto.InternalResponseUnion responses = 2;
}

// A ReadWriteCmdResponse is a union type containing instances of all
//  mutating commands. Note that any entry added here must be handled
//  in storage/engine/db.cc in GetResponseHeader().
message ReadWriteCmdResponse {
   oneof value {
    .cockroach.proto.PutResponse put = 1;
    .cockroach.proto.ConditionalPutResponse conditional_put = 2;
    .cockroach.proto.IncrementResponse increment = 3;
    .cockroach.proto.DeleteResponse delete = 4;
    .cockroach.proto.DeleteRangeResponse delete_range = 5;
    .cockroach.proto.EndTransactionResponse end_transaction = 6;
    .cockroach.proto.InternalHeartbeatTxnResponse internal_heartbeat_txn = 10;
    .cockroach.proto.InternalPushTxnResponse internal_push_txn = 11;
    .cockroach.proto.InternalResolveIntentResponse internal_resolve_intent = 12;
    .cockroach.proto.InternalMergeResponse internal_merge = 13;
    .cockroach.proto.InternalTruncateLogResponse internal_truncate_log = 14;
    .cockroach.proto.InternalGCResponse internal_gc = 15;
    .cockroach.proto.InternalLeaderLeaseResponse internal_leader_lease = 16;
  }
}

// An InternalRaftCommandUnion is the union of all commands which can be
//  sent via raft.
message InternalRaftCommandUnion {
   oneof value {
    // Non-batched external requests. This section is the same as RequestUnion.
    .cockroach.proto.ContainsRequest contains = 1;
    .cockroach.proto.GetRequest get = 2;
    .cockroach.proto.PutRequest put = 3;
    .cockroach.proto.ConditionalPutRequest conditional_put = 4;
    .cockroach.proto.IncrementRequest increment = 5;
    .cockroach.proto.DeleteRequest delete = 6;
    .cockroach.proto.DeleteRangeRequest delete_range = 7;
    .cockroach.proto.ScanRequest scan = 8;
    .cockroach.proto.EndTransactionRequest end_transaction = 9;
    // Other requests. Allow a gap in tag numbers so the previous list can
    //  be copy/pasted from RequestUnion.
    .cockroach.proto.BatchRequest batch = 30;
    .cockroach.proto.InternalRangeLookupRequest internal_range_lookup = 31;
    .cockroach.proto.InternalHeartbeatTxnRequest internal_heartbeat_txn = 32;
    .cockroach.proto.InternalPushTxnRequest internal_push_txn = 33;
    .cockroach.proto.InternalResolveIntentRequest internal_resolve_intent = 34;
    .cockroach.proto.InternalMergeRequest internal_merge_response = 35;
    .cockroach.proto.InternalTruncateLogRequest internal_truncate_log = 36;
    .cockroach.proto.InternalGCRequest internal_gc = 37;
    .cockroach.proto.InternalLeaderLeaseRequest internal_lease = 38;
    .cockroach.proto.InternalBatchRequest internal_batch = 39;
  }
}

// An InternalRaftCommand is a command which can be serialized and
//  sent via raft.
message InternalRaftCommand {
  optional int64 raft_id = 1;
  optional uint64 origin_node_id = 2;
  optional .cockroach.proto.InternalRaftCommandUnion cmd = 3;
}

// RaftMessageRequest is the request used to send raft messages using our
//  protobuf-based RPC codec. Unlike most of the requests defined in this file
//  and api.proto, this one is implemented in a separate service defined in
//  server/transport.go.
//  This is the equivalent of the non-protobuf multiraft.RaftMessageRequest.
message RaftMessageRequest {
  optional uint64 group_id = 1;
  // The raft payload, an encoded raftpb.Message. We transmit the message as
  //  an opaque blob to avoid the complexity of importing proto files across
  //  packages.
  optional bytes msg = 2;
}

// RaftMessageResponse is an empty message returned by raft RPCs.
message RaftMessageResponse {
}

// InternalTimeSeriesData is a collection of data samples for some measurable
//  value, where each sample is taken over a uniform time interval.
//  The collection itself contains a start timestamp (in seconds since the unix
//  epoch) and a sample duration (in milliseconds). Each sample in the collection
//  will contain a positive integer offset that indicates the length of time
//  between the start_timestamp of the collection and the time when the sample
//  began, expressed as an whole number of sample intervals. For example, if the
//  sample duration is 60000 (indicating 1 minute), then a contained sample with
//  an offset value of 5 begins (5*60000ms = 300000ms = 5 minutes) after the
//  start timestamp of this data.
//  This is meant to be an efficient internal representation of time series data,
//  ensuring that very little redundant data is stored on disk. With this goal in
//  mind, this message does not identify the variable which is actually being
//  measured; that information is expected be encoded in the key where this
//  message is stored.
message InternalTimeSeriesData {
  // Holds a wall time, expressed as a unix epoch time in nanoseconds. This
  //  represents the earliest possible timestamp for a sample within the
  //  collection.
  optional int64 start_timestamp_nanos = 1;
  // The duration of each sample interval, expressed in nanoseconds.
  optional int64 sample_duration_nanos = 2;
  // The actual data samples for this metric.
  repeated .cockroach.proto.InternalTimeSeriesSample samples = 3;
}

// A InternalTimeSeriesSample represents data gathered from multiple
//  measurements of a variable value over a given period of time. The length of
//  that period of time is stored in an InternalTimeSeriesData message; a sample
//  cannot be interpreted correctly without a start timestamp and sample
//  duration.
//  Each sample may contain data gathered from multiple measurements of the same
//  variable, as long as all of those measurements occured within the sample
//  period. The sample stores several aggregated values from these measurements:
//  - The sum of all measured values
//  - A count of all measurements taken
//  - The maximum individual measurement seen
//  - The minimum individual measurement seen
//  If zero measurements are present in a sample, then it should be omitted
//  entirely from any collection it would be a part of.
//  If the count of measurements is 1, then max and min fields may be omitted
//  and assumed equal to the sum field.
//  The variable being measured may be either an integer or a floating point;
//  therefore, there are two fields each for "sum", "max" and "min" to hold
//  either an integer or floating point number. In practice, only one set of
//  these fields should be present for any individual sample; however, int and
//  float values are recorded in parallel, allowing clients to write both floats
//  and integers to the same value. These are recorded separately to retain
//  precision, but are easily combined by higher-level logic at query time.
message InternalTimeSeriesSample {
  // Temporal offset from the "start_timestamp" of the InternalTimeSeriesData
  //  collection this data point is part in. The units of this value are
  //  determined by the value of the "sample_duration_milliseconds" field of
  //  the TimeSeriesData collection.
  optional int32 offset = 1;
  // Count of integer measurements taken within this sample.
  optional uint32 int_count = 2;
  // Sum of all integer measurements.
  optional int64 int_sum = 3;
  // Maximum encountered integer measurement in this sample.
  optional int64 int_max = 4;
  // Minimum encountered integer measurement in this sample.
  optional int64 int_min = 5;
  // Count of floating point measurements taken within this sample.
  optional uint32 float_count = 6;
  // Sum of all floating point measurements.
  optional float float_sum = 7;
  // Maximum encountered floating point measurement in this sample.
  optional float float_max = 8;
  // Minimum encountered floating point measurement in this sample.
  optional float float_min = 9;
}

// RaftTruncatedState contains metadata about the truncated portion of the raft log.
//  Raft requires access to the term of the last truncated log entry even after the
//  rest of the entry has been discarded.
message RaftTruncatedState {
  // The highest index that has been removed from the log.
  optional uint64 index = 1;
  // The term corresponding to 'index'.
  optional uint64 term = 2;
}

// RaftSnapshotData is the payload of a raftpb.Snapshot. It contains a raw copy of
//  all of the range's data and metadata, including the raft log, response cache, etc.
message RaftSnapshotData {
  message KeyValue {
    optional bytes key = 1;
    optional bytes value = 2;
  }
  repeated .cockroach.proto.RaftSnapshotData.KeyValue KV = 1;
}

