// Database.

syntax = "proto3";

// Database.
message Database {
  // Number of elements in a vector.
  uint32 vector_size = 1;
  // Number of partitions in the database.
  uint32 num_partitions = 2; 
  // Number of subvector divisions. vector_size must be multiple of this.
  uint32 num_divisions = 3;
  // Number of codes in each codebook.
  uint32 num_codes = 4;

  // Reference IDs of the partitions (→ Vec<Partition>).
  // Reference ID is supposed to be a URL-safe Base-64 encoded SHA-256 digest
  // of a serialized partition.
  // Number of elements must match num_partitions.
  repeated string partition_ids = 10;

  // Reference IDs of the partition centroids (→ VectorSet).
  // Reference ID is supposed to be a URL-safe Base-64 encoded SHA-256 digest
  // of the serialized partition centroids.
  string partition_centroids_id = 11;

  // Reference IDs of the codebooks (→ Vec<VectorSet>).
  // Reference ID is supposed to be a URL-safe Base-64 encoded SHA-256 digest
  // of a serialized codebook.
  // Each codebook must have num_codes vectors.
  // Number of elements must match num_divisions.
  repeated string codebook_ids = 12;

  // Reference IDs of the attributes logs (→ Vec<AttributesLog>).
  // Reference ID is supposed to be a URL-safe Base-64 encoded SHA-256 digest
  // of a serialized attributes log.
  // Each partition has a separate attributes log.
  // Number of elements must match num_partitions.
  repeated string attributes_log_ids = 13;

  // Attribute names in the database.
  // Every attribute name is represented (encoded) as the index in this list.
  repeated string attribute_names = 14;
}

// Single partition.
message Partition {
  // Vector size. Must match Database::vector_size.
  uint32 vector_size = 1;
  // Number of subvector divisions. Must match Database::num_divisions.
  uint32 num_divisions = 2;

  // Centroid of the partition.
  // Number of elements is given by vector_size.
  repeated float centroid = 10;

  // Encoded vectors.
  // Each vector must have num_divisions elements.
  EncodedVectorSet encoded_vectors = 11;

  // Vector IDs. Must be unique across the database.
  repeated Uuid vector_ids = 12;
}

// Vector set.
message VectorSet {
  // Vector size. Must match vector_size of the container.
  uint32 vector_size = 1;

  // Elements of all the vectors.
  // i-th vector is given by:
  //   data[i * vector_size..(i + 1) * vector_size]
  repeated float data = 10;
}

// Encoded vector set.
message EncodedVectorSet {
  // Vector size. Must match vector_size of the container.
  uint32 vector_size = 1;

  // Elements of all the vectors.
  // i-th vector is given by:
  //   data[i * vector_size..(i + 1) * vector_size]
  repeated uint32 data = 10;
}

// Attribute value.
message AttributeValue {
  oneof value {
    string string_value = 1;
    uint64 uint64_value = 2;
  }
}

// Log of attributes.
message AttributesLog {
  // ID of the partition.
  string partition_id = 1;

  // Log entries.
  // AttributesLog contains only "set" operations.
  // If an attribute value is set multiple times, the last value is used.
  repeated OperationSetAttribute entries = 10;
}

// Operation to set an attribute.
message OperationSetAttribute {
  // Vector ID.
  Uuid vector_id = 1;
  // Index of the name of the attribute to set.
  // The name is stored at this index in `attribute_names` in the database.
  uint32 name_index = 2;
  // Value of the attribute to set.
  AttributeValue value = 3;
}

// UUID.
message Uuid {
  // Upper half of the ID; i.e., most significant 64 bits.
  fixed64 upper = 1;
  // Lower half of the ID; i.e., least significant 64 bits.
  fixed64 lower = 2;
}
