enum Language:int {
  PYTHON = 0,
  CPP = 1,
  JAVA = 2
}

// These indexes are mapped to strings in ray_redis_module.cc.
enum TablePrefix:int {
  UNUSED = 0,
  TASK,
  RAYLET_TASK,
  CLIENT,
  OBJECT,
  ACTOR,
  FUNCTION,
  TASK_RECONSTRUCTION,
  HEARTBEAT,
  HEARTBEAT_BATCH,
  ERROR_INFO,
  DRIVER,
  PROFILE,
  TASK_LEASE,
}

// The channel that Add operations to the Table should be published on, if any.
enum TablePubsub:int {
  NO_PUBLISH = 0,
  TASK,
  RAYLET_TASK,
  CLIENT,
  OBJECT,
  ACTOR,
  HEARTBEAT,
  HEARTBEAT_BATCH,
  ERROR_INFO,
  TASK_LEASE,
  DRIVER,
}

table Arg {
  // Object ID for pass-by-reference arguments. Normally there is only one
  // object ID in this list which represents the object that is being passed.
  // However to support reducers in a MapReduce workload, we also support
  // passing multiple object IDs for each argument.
  object_ids: [string];
  // Data for pass-by-value arguments.
  data: string;
}

table TaskInfo {
  // ID of the driver that created this task.
  driver_id: string;
  // Task ID of the task.
  task_id: string;
  // Task ID of the parent task.
  parent_task_id: string;
  // A count of the number of tasks submitted by the parent task before this one.
  parent_counter: int;
  // The ID of the actor to create if this is an actor creation task.
  actor_creation_id: string;
  // The dummy object ID of the actor creation task if this is an actor method.
  actor_creation_dummy_object_id: string;
  // Actor ID of the task. This is the actor that this task is executed on
  // or NIL_ACTOR_ID if the task is just a normal task.
  actor_id: string;
  // The ID of the handle that was used to submit the task. This should be
  // unique across handles with the same actor_id.
  actor_handle_id: string;
  // Number of tasks that have been submitted to this actor so far.
  actor_counter: int;
  // True if this task is an actor checkpoint task and false otherwise.
  is_actor_checkpoint_method: bool;
  // Function ID of the task.
  function_id: string;
  // Task arguments.
  args: [Arg];
  // Object IDs of return values.
  returns: [string];
  // The required_resources vector indicates the quantities of the different
  // resources required by this task.
  required_resources: [ResourcePair];
  // The resources required for placing this task on a node. If this is empty,
  // then the placement resources are equal to the required_resources.
  required_placement_resources: [ResourcePair];
  // The language that this task belongs to.
  language: Language;
  // Function descriptor, which is a list of strings that can
  // uniquely describe a function.
  // For a Python function, it should be: [module_name, class_name, function_name]
  // For a Java function, it should be: [class_name, method_name, type_descriptor]
  // TODO(hchen): after changing Python worker to use function_descriptor,
  // function_id can be removed.
  function_descriptor: [string];
}

table ResourcePair {
  // The name of the resource.
  key: string;
  // The quantity of the resource.
  value: double;
}

table GcsTableEntry {
  id: string;
  entries: [string];
}

table FunctionTableData {
  language: Language;
  name: string;
  data: string;
}

table ObjectTableData {
  // The size of the object.
  object_size: long;
  // The node manager ID that this object appeared on or was evicted by.
  manager: string;
  // Whether this entry is an addition or a deletion.
  is_eviction: bool;
  // The number of times this object has been evicted from this node so far.
  num_evictions: int;
}

table TaskReconstructionData {
  // The number of times this task has been reconstructed so far.
  num_reconstructions: int;
  // The node manager that is trying to reconstruct the task.
  node_manager_id: string;
}

enum SchedulingState:int {
  NONE = 0,
  WAITING = 1,
  SCHEDULED = 2,
  QUEUED = 4,
  RUNNING = 8,
  DONE = 16,
  LOST = 32,
  RECONSTRUCTING = 64
}

table TaskTableData {
  // The state of the task.
  scheduling_state: SchedulingState;
  // A local scheduler ID.
  scheduler_id: string;
  // A string of bytes representing the task's TaskExecutionDependencies.
  execution_dependencies: string;
  // The number of times the task was spilled back by local schedulers.
  spillback_count: long;
  // A string of bytes representing the task specification.
  task_info: string;
  // TODO(pcm): This is at the moment duplicated in task_info, remove that one
  updated: bool;
}

table TaskTableTestAndUpdate {
  test_scheduler_id: string;
  test_state_bitmask: SchedulingState;
  update_state: SchedulingState;
}

table ClassTableData {
}

enum ActorState:int {
  // Actor is alive.
  ALIVE = 0,
  // Actor is already dead and won't be reconstructed.
  DEAD
}

table ActorTableData {
  // The ID of the actor that was created.
  actor_id: string;
  // The dummy object ID returned by the actor creation task. If the actor
  // dies, then this is the object that should be reconstructed for the actor
  // to be recreated.
  actor_creation_dummy_object_id: string;
  // The ID of the driver that created the actor.
  driver_id: string;
  // The ID of the node manager that created the actor.
  node_manager_id: string;
  // Current state of this actor.
  state: ActorState;
}

table ErrorTableData {
  // The ID of the job that the error is for.
  job_id: string;
  // The type of the error.
  type: string;
  // The error message.
  error_message: string;
  // The timestamp of the error message.
  timestamp: double;
}

table CustomSerializerData {
}

table ConfigTableData {
}

table ProfileEvent {
  // The type of the event.
  event_type: string;
  // The start time of the event.
  start_time: double;
  // The end time of the event. If the event is a point event, then this should
  // be the same as the start time.
  end_time: double;
  // Additional data associated with the event. This data must be serialized
  // using JSON.
  extra_data: string;
}

table ProfileTableData {
  // The type of the component that generated the event, e.g., worker or
  // object_manager, or node_manager.
  component_type: string;
  // An identifier for the component that generated the event.
  component_id: string;
  // An identifier for the node that generated the event.
  node_ip_address: string;
  // This is a batch of profiling events. We batch these together for
  // performance reasons because a single task may generate many events, and
  // we don't want each event to require a GCS command.
  profile_events: [ProfileEvent];
}

table RayResource {
  // The type of the resource.
  resource_name: string;
  // The total capacity of this resource type.
  resource_capacity: double;
}

table ClientTableData {
  // The client ID of the client that the message is about.
  client_id: string;
  // The IP address of the client's node manager.
  node_manager_address: string;
  // The IPC socket name of the client's raylet.
  raylet_socket_name: string;
  // The IPC socket name of the client's plasma store.
  object_store_socket_name: string;
  // The port at which the client's node manager is listening for TCP
  // connections from other node managers.
  node_manager_port: int;
  // The port at which the client's object manager is listening for TCP
  // connections from other object managers.
  object_manager_port: int;
  // True if the message is about the addition of a client and false if it is
  // about the deletion of a client.
  is_insertion: bool;
  resources_total_label: [string];
  resources_total_capacity: [double];
}

table HeartbeatTableData {
  // Node manager client id
  client_id: string;
  // Resource capacity currently available on this node manager.
  resources_available_label: [string];
  resources_available_capacity: [double];
  // Total resource capacity configured for this node manager.
  resources_total_label: [string];
  resources_total_capacity: [double];
  // Aggregate outstanding resource load on this node manager.
  resource_load_label: [string];
  resource_load_capacity: [double];
}

table HeartbeatBatchTableData {
  batch: [HeartbeatTableData];
}

// Data for a lease on task execution.
table TaskLeaseData {
  // Node manager client ID.
  node_manager_id: string;
  // The time that the lease was last acquired at. NOTE(swang): This is the
  // system clock time according to the node that added the entry and is not
  // synchronized with other nodes.
  acquired_at: long;
  // The period that the lease is active for.
  timeout: long;
}

table DriverTableData {
  // The driver ID.
  driver_id: string;
  // Whether it's dead.
  is_dead: bool;
}
