syntax = "proto2";

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

option go_package = "proto";

// ReplicaChangeType is a parameter of ChangeReplicasTrigger.
enum ReplicaChangeType {
  ADD_REPLICA = 0;
  REMOVE_REPLICA = 1;
}

// IsolationType TODO(jiajia) Needs documentation.
enum IsolationType {
  // SERIALIZABLE TODO(jiajia) Needs documentation.
  SERIALIZABLE = 0;
  // SNAPSHOT TODO(jiajia) Needs documentation.
  SNAPSHOT = 1;
}

// TransactionStatus specifies possible states for a transaction.
enum TransactionStatus {
  // PENDING is the default state for a new transaction. Transactions
  //  move from PENDING to one of COMMITTED or ABORTED. Mutations made
  //  as part of a PENDING transactions are recorded as "intents" in
  //  the underlying MVCC model.
  PENDING = 0;
  // COMMITTED is the state for a transaction which has been
  //  committed. Mutations made as part of a transaction which is moved
  //  into COMMITTED state become durable and visible to other
  //  transactions, moving from "intents" to permanent versioned
  //  values.
  COMMITTED = 1;
  // ABORTED is the state for a transaction which has been aborted.
  //  Mutations made as part of a transaction which is moved into
  //  ABORTED state are deleted and are never made visible to other
  //  transactions.
  ABORTED = 2;
}

// Timestamp represents a state of the hybrid logical clock.
message Timestamp {
  // Holds a wall time, typically a unix epoch time
  //  expressed in nanoseconds.
  optional int64 wall_time = 1;
  // The logical component captures causality for events whose wall
  //  times are equal. It is effectively bounded by (maximum clock
  //  skew)/(minimal ns between events) and nearly impossible to
  //  overflow.
  optional int32 logical = 2;
}

// Value specifies the value at a key. Multiple values at the same key
//  are supported based on timestamp. Values support the union of two
//  basic types: a "bag o' bytes" generic byte slice and an incrementable
//  int64, for use with the Increment API call.
message Value {
  // Bytes is the byte slice value. If this field is set, the integer field
  //  should not be.
  optional bytes bytes = 1;
  // Integer is an integer value type. If this field is set, the bytes field
  //  should not be. Only Integer values may exist at a key when making the
  //  Increment API call.
  optional int64 integer = 2;
  // Checksum is a CRC-32-IEEE checksum of the key + value, in that order.
  //  If this is an integer value, then the value is interpreted as an 8
  //  byte, big-endian encoded value. This value is set by the client on
  //  writes to do end-to-end integrity verification. If the checksum is
  //  incorrect, the write operation will fail. If the client does not
  //  wish to use end-to-end checksumming, this value should be nil.
  optional fixed32 checksum = 3;
  // Timestamp of value.
  optional .cockroach.proto.Timestamp timestamp = 4;
  // Tag is an optional string value which can be used to add additional
  //  metadata to this value. For example, Tag might provide information on how
  //  the bytes in the "bytes" field should be interpreted.
  optional string tag = 5;
}

// MVCCValue differentiates between normal versioned values and
//  deletion tombstones.
message MVCCValue {
  // True to indicate a deletion tombstone. If false, value should not
  //  be nil.
  optional bool deleted = 1;
  // The value. Nil if deleted is true; not nil otherwise.
  optional .cockroach.proto.Value value = 2;
}

// KeyValue is a pair of Key and Value for returned Key/Value pairs
//  from ScanRequest/ScanResponse. It embeds a Key and a Value.
message KeyValue {
  optional bytes key = 1;
  optional .cockroach.proto.Value value = 2;
}

// RawKeyValue contains the raw bytes of the value for a key.
message RawKeyValue {
  optional bytes key = 1;
  optional bytes value = 2;
}

// A StoreIdent uniquely identifies a store in the cluster. The
//  StoreIdent is written to the underlying storage engine at a
//  store-reserved system key (KeyLocalIdent).
message StoreIdent {
  optional string cluster_id = 1;
  optional int32 node_id = 2;
  optional int32 store_id = 3;
}

// A SplitTrigger is run after a successful commit of an AdminSplit
//  command. It provides the updated range descriptor covering the
//  first half of the split and the new range descriptor covering the
//  second half. This information allows the final bookkeeping for
//  the split to be completed and the new range put into operation.
message SplitTrigger {
  optional .cockroach.proto.RangeDescriptor updated_desc = 1;
  optional .cockroach.proto.RangeDescriptor new_desc = 2;
}

// A MergeTrigger is run after a successful commit of an AdminMerge
//  command. It provides the updated range descriptor that now encompasses
//  what was originally both ranges. This information allows the final bookkeeping
//  for the merge to be completed and put into operation.
message MergeTrigger {
  optional .cockroach.proto.RangeDescriptor updated_desc = 1;
  optional int64 subsumed_raft_id = 2;
}

message ChangeReplicasTrigger {
  optional int32 node_id = 1;
  optional int32 store_id = 2;
  optional .cockroach.proto.ReplicaChangeType change_type = 3;
  // The new replica list with this change applied.
  repeated .cockroach.proto.Replica updated_replicas = 4;
}

// CommitTrigger encapsulates all of the internal-only commit triggers.
message InternalCommitTrigger {
  optional .cockroach.proto.SplitTrigger split_trigger = 1;
  optional .cockroach.proto.MergeTrigger merge_trigger = 2;
  optional .cockroach.proto.ChangeReplicasTrigger change_replicas_trigger = 3;
  // List of intents to resolve on commit or abort. Note that keys
  //  listed here will only be resolved if they fall on the same range
  //  that the transaction was started on.
  repeated bytes intents = 4;
}

// NodeList keeps a growing set of NodeIDs as a sorted slice, with Add()
//  adding to the set and Contains() verifying membership.
message NodeList {
  // Note that this does not use the NodeID custom type because that appears
  //  to interact badly with the repeated and/or packed options.
  repeated int32 nodes = 1 [packed = true];
}

// A Transaction is a unit of work performed on the database.
//  Cockroach transactions support two isolation levels: snapshot
//  isolation and serializable snapshot isolation. Each Cockroach
//  transaction is assigned a random priority. This priority will be
//  used to decide whether a transaction will be aborted during
//  contention.
message Transaction {
  optional string name = 1;
  // Key is the key which anchors the transaction. This is typically
  //  the first key read or written during the transaction and
  //  determines which range in the cluster will hold the transaction
  //  record.
  optional bytes key = 2;
  // ID is a unique UUID value which identifies the transaction.
  optional bytes id = 3;
  optional int32 priority = 4;
  optional .cockroach.proto.IsolationType isolation = 5;
  optional .cockroach.proto.TransactionStatus status = 6;
  // Incremented on txn retry.
  optional int32 epoch = 7;
  // The last heartbeat timestamp.
  optional .cockroach.proto.Timestamp last_heartbeat = 8;
  // The proposed timestamp for the transaction. This starts as
  //  the current wall time on the txn coordinator.
  optional .cockroach.proto.Timestamp timestamp = 9;
  // The original timestamp at which the transaction started. For serializable
  //  transactions, if the timestamp drifts from the original timestamp, the
  //  transaction will retry.
  optional .cockroach.proto.Timestamp orig_timestamp = 10;
  // Initial Timestamp + clock skew. Reads which encounter values with
  //  timestamps between Timestamp and MaxTimestamp trigger a txn
  //  retry error, unless the node being read is listed in certain_nodes
  //  (in which case no more read uncertainty can occur).
  //  The case MaxTimestamp < Timestamp is possible for transactions which have
  //  been pushed; in this case, MaxTimestamp should be ignored.
  optional .cockroach.proto.Timestamp max_timestamp = 11;
  // A sorted list of ids of nodes for which a ReadWithinUncertaintyIntervalError
  //  occurred during a prior read. The purpose of keeping this information is
  //  that as a reaction to this error, the transaction's timestamp is forwarded
  //  appropriately to reflect that node's clock uncertainty. Future reads to
  //  the same node are therefore freed from uncertainty restarts.
  //  The exact mechanism is that upon encountering the above error, the trans-
  //  action will have to retry with a higher timestamp. This higher timestamp
  //  is either the one of the encountered future write returned in the error
  //  or (if higher, which is in the majority of cases), the time of the node
  //  serving the key at the time of the failed read.
  //  Additionally storing the node, we make sure to set MaxTimestamp=Timestamp
  //  at the time of the read for nodes whose clock we've taken into acount,
  //  which amounts to reading without any uncertainty.
  //  Bits of this mechanism are found in the local sender, the range and the
  //  txn_coord_sender, with brief comments referring here.
  //  See https://github.com/cockroachdb/cockroach/pull/221.
  optional .cockroach.proto.NodeList certain_nodes = 12;
}

// Lease contains information about leader leases including the
//  expiration and lease holder.
message Lease {
  // The start is a timestamp at which the lease begins. This value
  //  must be greater than the last lease expiration or this call will
  //  fail.
  optional .cockroach.proto.Timestamp start = 1;
  // The expiration is a timestamp at which the lease will expire.
  optional .cockroach.proto.Timestamp expiration = 2;
  // The Raft NodeID on which the would-be lease holder lives.
  optional uint64 raft_node_id = 3;
}

// MVCCMetadata holds MVCC metadata for a key. Used by storage/engine/mvcc.go.
message MVCCMetadata {
  optional .cockroach.proto.Transaction txn = 1;
  // The timestamp of the most recent versioned value.
  optional .cockroach.proto.Timestamp timestamp = 2;
  // Is the most recent value a deletion tombstone?
  optional bool deleted = 3;
  // The size in bytes of the most recent encoded key.
  optional int64 key_bytes = 4;
  // The size in bytes of the most recent versioned value.
  optional int64 val_bytes = 5;
  // Inline value, used for values with zero timestamp. This provides
  //  an efficient short circuit of the normal MVCC metadata sentinel
  //  and subsequent version rows. If timestamp == (0, 0), then there
  //  is only a single MVCC metadata row with value inlined, and with
  //  empty timestamp, key_bytes, and val_bytes.
  optional .cockroach.proto.Value value = 6;
}

// GCMetadata holds information about the last complete key/value
//  garbage collection scan of a range.
message GCMetadata {
  // The last GC scan timestamp in nanoseconds since the Unix epoch.
  optional int64 last_scan_nanos = 1;
  // The oldest unresolved write intent in nanoseconds since epoch.
  //  Null if there are no unresolved write intents.
  optional int64 oldest_intent_nanos = 2;
}

// TimeSeriesDatapoint is a single point of time series data; a value associated
//  with a timestamp.
message TimeSeriesDatapoint {
  // The timestamp when this datapoint is located, expressed in nanoseconds
  //  since the unix epoch.
  optional int64 timestamp_nanos = 1;
  // An integer representation of the value of this datapoint. If this field
  //  is set, then 'float_value' must not be set.
  optional int64 int_value = 2;
  // A floating point representation of the value of this datapoint. If this
  //  field is set, then 'int_value' must not be set.
  optional float float_value = 3;
}

// TimeSeriesData is a set of observations of a single variable value at
//  multiple points in time. This message contains a name and a source which, in
//  combination, uniquely identify the series being measured. The message also
//  contains a repeated set of TimeSeriesDatapoint messages representing distinct
//  measurements of the variable.
message TimeSeriesData {
  // A string which uniquely identifies the variable from which this data was
  //  measured.
  optional string name = 1;
  // A string which identifies the unique source from which the variable was measured.
  optional string source = 2;
  // Datapoints representing one or more measurements taken from the variable.
  repeated .cockroach.proto.TimeSeriesDatapoint datapoints = 3;
}

// MVCCStats tracks byte and instance counts for:
//   - Live key/values (i.e. what a scan at current time will reveal;
//     note that this includes intent keys and values, but not keys and
//     values with most recent value deleted)
//   - Key bytes (includes all keys, even those with most recent value deleted)
//   - Value bytes (includes all versions)
//   - Key count (count of all keys, including keys with deleted tombstones)
//   - Value count (all versions, including deleted tombstones)
//   - Intents (provisional values written during txns)
message MVCCStats {
  optional int64 live_bytes = 1;
  optional int64 key_bytes = 2;
  optional int64 val_bytes = 3;
  optional int64 intent_bytes = 4;
  optional int64 live_count = 5;
  optional int64 key_count = 6;
  optional int64 val_count = 7;
  optional int64 intent_count = 8;
  optional int64 intent_age = 9;
  optional int64 gc_bytes_age = 10;
  optional int64 last_update_nanos = 11;
}

