Class Table (2.28.0)

The main interface to interact with data in a Cloud Bigtable table.

This class provides member functions to:

The class deals with the most common transient failures, and retries the underlying RPC calls subject to the policies configured by the application. These policies are documented in Table::Table().

Thread-safety

Instances of this class created via copy-construction or copy-assignment share the underlying pool of connections. Access to these copies via multiple threads is guaranteed to work. Two threads operating concurrently on the same instance of this class is not guaranteed to work.

Cost

Creating a new object of type Table is comparable to creating a few objects of type std::string or a few objects of type std::shared_ptr<int>. The class represents a shallow handle to a remote object.

Error Handling

This class uses StatusOr<T> to report errors. When an operation fails to perform its work the returned StatusOr<T> contains the error details. If the ok() member function in the StatusOr<T> returns true then it contains the expected result. Operations that do not return a value simply return a google::cloud::Status indicating success or the details of the error Please consult the StatusOr documentation for more details.

namespace cbt = google::cloud::bigtable;
cbt::Table = ...;
google::cloud::StatusOr<std::pair<bool, cbt::Row>> row = table.ReadRow(...);

if (!row) {
  std::cerr << "Error reading row\n";
  return;
}

// Use "row" as a smart pointer here, e.g.:
if (!row->first) {
  std::cout << "Contacting the server was successful, but the row does not"
            << " exist\n";
  return;
}
std::cout << "The row has " << row->second.cells().size() << " cells\n";

In addition, the main page contains examples using StatusOr<T> to handle errors.

Retry, Backoff, and Idempotency Policies

The library automatically retries requests that fail with transient errors, and uses truncated exponential backoff to backoff between retries. The default policies are to continue retrying for up to 10 minutes. On each transient failure the backoff period is doubled, starting with an initial backoff of 100 milliseconds. The backoff period growth is truncated at 60 seconds. The default idempotency policy is to only retry idempotent operations. Note that most operations that change state are not idempotent. The application can override these policies when constructing objects of this class. The documentation for the constructors show examples of this in action.

See Also

https://cloud.google.com/bigtable/ for an overview of Cloud Bigtable.

See Also

https://cloud.google.com/bigtable/docs/overview for an overview of the Cloud Bigtable data model.

See Also

https://cloud.google.com/bigtable/docs/instances-clusters-nodes for an introduction of the main APIs into Cloud Bigtable.

See Also

https://cloud.google.com/bigtable/docs/reference/service-apis-overview for an overview of the underlying Cloud Bigtable API.

See Also

google::cloud::StatusOr for a description of the error reporting class used by this library.

See Also

LimitedTimeRetryPolicy and LimitedErrorCountRetryPolicy for alternative retry policies.

See Also

ExponentialBackoffPolicy to configure different parameters for the exponential backoff policy.

See Also

SafeIdempotentMutationPolicy and AlwaysRetryMutationPolicy for alternative idempotency policies.

Constructors

Table(std::shared_ptr< bigtable::DataConnection >, TableResource, Options)

Constructs a Table object.

Example Using AppProfile
  auto options =
      google::cloud::Options{}.set<cbt::AppProfileIdOption>(profile_id);
  cbt::Table read(connection,
                  cbt::TableResource(project_id, instance_id, table_id),
                  options);

  google::cloud::StatusOr<std::pair<bool, cbt::Row>> result =
      read.ReadRow("key-0", cbt::Filter::ColumnRangeClosed("fam", "c0", "c0"));
  if (!result) throw std::move(result).status();
  if (!result->first) throw std::runtime_error("missing row with key = key-0");
  cbt::Cell const& cell = result->second.cells().front();
  std::cout << cell.family_name() << ":" << cell.column_qualifier() << "    @ "
            << cell.timestamp().count() << "us\n"
            << '"' << cell.value() << '"' << "\n";
Idempotency Policy Example
  using ::google::cloud::Options;
  namespace cbt = ::google::cloud::bigtable;
  [](std::string const& project_id, std::string const& instance_id,
     std::string const& table_id, std::string const& row_key) {
    cbt::Table table(cbt::MakeDataConnection(),
                     cbt::TableResource(project_id, instance_id, table_id),
                     Options{}.set<cbt::IdempotentMutationPolicyOption>(
                         cbt::AlwaysRetryMutationPolicy().clone()));
    // Normally this is not retried on transient failures, because the operation
    // is not idempotent (each retry would set a different timestamp), in this
    // case it would, because the table is setup to always retry.
    cbt::SingleRowMutation mutation(
        row_key, cbt::SetCell("fam", "some-column", "some-value"));
    google::cloud::Status status = table.Apply(std::move(mutation));
    if (!status.ok()) throw std::runtime_error(status.message());
  }
Modified Retry Policy Example
  using ::google::cloud::Options;
  namespace cbt = ::google::cloud::bigtable;
  [](std::string const& project_id, std::string const& instance_id,
     std::string const& table_id, std::string const& row_key) {
    cbt::Table table(cbt::MakeDataConnection(),
                     cbt::TableResource(project_id, instance_id, table_id),
                     Options{}.set<cbt::DataRetryPolicyOption>(
                         cbt::DataLimitedErrorCountRetryPolicy(7).clone()));
    cbt::SingleRowMutation mutation(
        row_key, cbt::SetCell("fam", "some-column",
                              std::chrono::milliseconds(0), "some-value"));
    google::cloud::Status status = table.Apply(std::move(mutation));
    if (!status.ok()) throw std::runtime_error(status.message());
  }
Parameters
Name Description
conn std::shared_ptr< bigtable::DataConnection >

the connection to the Cloud Bigtable service. See MakeDataConnection() for how to create a connection. To mock the behavior of Table in your tests, use a bigtable_mocks::MockDataConnection.

tr TableResource

identifies the table resource by its project, instance, and table ids.

options Options

Configuration options for the table. Use AppProfileIdOption to supply an app profile for the Table operations. Or configure retry / backoff / idempotency policies with the options enumerated in DataPolicyOptionList.

Table(std::shared_ptr< DataClient >, std::string const &)

Constructor with default policies.

Parameters
Name Description
client std::shared_ptr< DataClient >

how to communicate with Cloud Bigtable, including credentials, the project id, and the instance id.

table_id std::string const &

the table id within the instance defined by client. The full table name is client->instance_name() + "/tables/" + table_id.

Table(std::shared_ptr< DataClient >, std::string, std::string const &)

Constructor with default policies.

Parameters
Name Description
client std::shared_ptr< DataClient >

how to communicate with Cloud Bigtable, including credentials, the project id, and the instance id.

app_profile_id std::string

the app_profile_id needed for using the replication API.

table_id std::string const &

the table id within the instance defined by client. The full table name is client->instance_name() + "/tables/" + table_id.

Table(std::shared_ptr< DataClient >, std::string const &, Policies &&...)

Constructor with explicit policies.

The policies are passed by value, because this makes it easy for applications to create them.

Example
using namespace std::chrono_literals; // assuming C++14.
auto client = bigtable::MakeClient(...); // details omitted
bigtable::Table table(client, "my-table",
                      // Allow up to 20 minutes to retry operations
                      bigtable::LimitedTimeRetryPolicy(20min),
                      // Start with 50 milliseconds backoff, grow
                      // exponentially to 5 minutes.
                      bigtable::ExponentialBackoffPolicy(50ms, 5min),
                      // Only retry idempotent mutations.
                      bigtable::SafeIdempotentMutationPolicy());
See Also

SafeIdempotentMutationPolicy, AlwaysRetryMutationPolicy, ExponentialBackoffPolicy, LimitedErrorCountRetryPolicy, LimitedTimeRetryPolicy.

Parameters
Name Description
client std::shared_ptr< DataClient >

how to communicate with Cloud Bigtable, including credentials, the project id, and the instance id.

table_id std::string const &

the table id within the instance defined by client. The full table name is client->instance_name() + "/tables/" + table_id.

policies Policies &&...

the set of policy overrides for this object.

typename...

Table(std::shared_ptr< DataClient >, std::string, std::string const &, Policies &&...)

Constructor with explicit policies.

The policies are passed by value, because this makes it easy for applications to create them.

Example
using namespace std::chrono_literals; // assuming C++14.
auto client = bigtable::MakeClient(...); // details omitted
bigtable::Table table(client, "app_id", "my-table",
                      // Allow up to 20 minutes to retry operations
                      bigtable::LimitedTimeRetryPolicy(20min),
                      // Start with 50 milliseconds backoff, grow
                      // exponentially to 5 minutes.
                      bigtable::ExponentialBackoffPolicy(50ms, 5min),
                      // Only retry idempotent mutations.
                      bigtable::SafeIdempotentMutationPolicy());
See Also

SafeIdempotentMutationPolicy, AlwaysRetryMutationPolicy, ExponentialBackoffPolicy, LimitedErrorCountRetryPolicy, LimitedTimeRetryPolicy.

Parameters
Name Description
client std::shared_ptr< DataClient >

how to communicate with Cloud Bigtable, including credentials, the project id, and the instance id.

app_profile_id std::string

the app_profile_id needed for using the replication API.

table_id std::string const &

the table id within the instance defined by client. The full table name is client->instance_name() + "/tables/" + table_id.

policies Policies &&...

the set of policy overrides for this object.

typename...

Functions

table_name() const

Returns
Type Description
std::string const &

app_profile_id() const

Returns
Type Description
std::string const &

project_id() const

Returns
Type Description
std::string const &

instance_id() const

Returns
Type Description
std::string const &

table_id() const

Returns
Type Description
std::string const &

WithNewTarget(std::string, std::string, std::string) const

Returns a Table that reuses the connection and configuration of this Table, but with a different resource name.

Parameters
Name Description
project_id std::string
instance_id std::string
table_id std::string
Returns
Type Description
Table

WithNewTarget(std::string, std::string, std::string, std::string) const

Returns a Table that reuses the connection and configuration of this Table, but with a different resource name.

Parameters
Name Description
project_id std::string
instance_id std::string
app_profile_id std::string
table_id std::string
Returns
Type Description
Table

Apply(SingleRowMutation, Options)

Attempts to apply the mutation to a row.

Idempotency

This operation is idempotent if the provided mutations are idempotent. Note that google::cloud::bigtable::SetCell() without an explicit timestamp is not an idempotent operation.

Thread-safety

Two threads concurrently calling this member function on the same instance of this class are not guaranteed to work.

Example
  namespace cbt = ::google::cloud::bigtable;
  [](cbt::Table table, std::string const& row_key) {
    auto timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(
        std::chrono::system_clock::now().time_since_epoch());

    cbt::SingleRowMutation mutation(row_key);
    mutation.emplace_back(
        cbt::SetCell("fam", "column0", timestamp, "value for column0"));
    mutation.emplace_back(
        cbt::SetCell("fam", "column1", timestamp, "value for column1"));
    auto status = table.Apply(std::move(mutation));
    if (!status.ok()) throw std::runtime_error(status.message());
  }
Parameters
Name Description
mut SingleRowMutation

the mutation. Note that this function takes ownership (and then discards) the data in the mutation. In general, a SingleRowMutation can be used to modify and/or delete multiple cells, across different columns and column families.

opts Options

(Optional) Override the class-level options, such as retry, backoff, and idempotency policies.

Returns
Type Description
Status

status of the operation.

AsyncApply(SingleRowMutation, Options)

Makes asynchronous attempts to apply the mutation to a row.

Idempotency

This operation is idempotent if the provided mutations are idempotent. Note that google::cloud::bigtable::SetCell() without an explicit timestamp is not an idempotent operation.

Example
  namespace cbt = ::google::cloud::bigtable;
  using ::google::cloud::future;
  using ::google::cloud::StatusOr;
  [](cbt::Table table, std::string const& row_key) {
    auto timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(
        std::chrono::system_clock::now().time_since_epoch());

    cbt::SingleRowMutation mutation(row_key);
    mutation.emplace_back(
        cbt::SetCell("fam", "column0", timestamp, "value for column0"));
    mutation.emplace_back(
        cbt::SetCell("fam", "column1", timestamp, "value for column1"));

    future<google::cloud::Status> status_future =
        table.AsyncApply(std::move(mutation));
    auto status = status_future.get();
    if (!status.ok()) throw std::runtime_error(status.message());
    std::cout << "Successfully applied mutation\n";
  }
Parameters
Name Description
mut SingleRowMutation

the mutation. Note that this function takes ownership (and then discards) the data in the mutation. In general, a SingleRowMutation can be used to modify and/or delete multiple cells, across different columns and column families.

opts Options

(Optional) Override the class-level options, such as retry, backoff, and idempotency policies.

Returns
Type Description
future< Status >

BulkApply(BulkMutation, Options)

Attempts to apply mutations to multiple rows.

These mutations are applied in bulk, in a single MutateRowsRequest RPC. Failures are handled on a per mutation basis. If the result of a mutation is a permanent (non-retryable) error, or if a non-idempotent mutation fails for any reason, the mutation will not be retried. Only idempotent mutations that encounter transient (retryable) errors can be retried. These mutations are collected and retried in bulk. This function will continue to retry any remaining errors until this class's retry policy is exhausted.

It is possible that some mutations may not be attempted at all. These mutations are considered failing and will be returned.

Idempotency

This operation is idempotent if the provided mutations are idempotent. Note that google::cloud::bigtable::SetCell() without an explicit timestamp is not an idempotent operation.

Thread-safety

Two threads concurrently calling this member function on the same instance of this class are not guaranteed to work. Consider copying the object and using different copies in each thread.

Example
  namespace cbt = ::google::cloud::bigtable;
  [](cbt::Table table) {
    // Write several rows in a single operation, each row has some trivial data.
    cbt::BulkMutation bulk;
    for (int i = 0; i != 5000; ++i) {
      // Note: This example uses sequential numeric IDs for simplicity, but
      // this can result in poor performance in a production application.
      // Since rows are stored in sorted order by key, sequential keys can
      // result in poor distribution of operations across nodes.
      //
      // For more information about how to design a Bigtable schema for the
      // best performance, see the documentation:
      //
      //     https://cloud.google.com/bigtable/docs/schema-design
      char buf[32];
      snprintf(buf, sizeof(buf), "key-%06d", i);
      cbt::SingleRowMutation mutation(buf);
      mutation.emplace_back(
          cbt::SetCell("fam", "col0", "value0-" + std::to_string(i)));
      mutation.emplace_back(
          cbt::SetCell("fam", "col1", "value1-" + std::to_string(i)));
      bulk.emplace_back(std::move(mutation));
    }
    std::vector<cbt::FailedMutation> failures =
        table.BulkApply(std::move(bulk));
    if (failures.empty()) {
      std::cout << "All mutations applied successfully\n";
      return;
    }
    // By default, the `table` object uses the `SafeIdempotentMutationPolicy`
    // which does not retry if any of the mutations fails and are
    // not-idempotent. In this example we simply print such failures, if any,
    // and ignore them otherwise.
    std::cerr << "The following mutations failed and were not retried:\n";
    for (auto const& f : failures) {
      std::cerr << "index[" << f.original_index() << "]=" << f.status() << "\n";
    }
  }
Parameters
Name Description
mut BulkMutation

the mutations

opts Options

(Optional) Override the class-level options, such as retry, backoff, and idempotency policies.

Returns
Type Description
std::vector< FailedMutation >

a list of failed mutations

AsyncBulkApply(BulkMutation, Options)

Makes asynchronous attempts to apply mutations to multiple rows.

These mutations are applied in bulk, in a single MutateRowsRequest RPC. Failures are handled on a per mutation basis. If the result of a mutation is a permanent (non-retryable) error, or if a non-idempotent mutation fails for any reason, the mutation will not be retried. Only idempotent mutations that encounter transient (retryable) errors can be retried. These mutations are collected and retried in bulk. This function will continue to retry any remaining errors until this class's retry policy is exhausted.

It is possible that some mutations may not be attempted at all. These mutations are considered failing and will be returned.

Idempotency

This operation is idempotent if the provided mutations are idempotent. Note that google::cloud::bigtable::SetCell() without an explicit timestamp is not an idempotent operation.

Thread-safety

Two threads concurrently calling this member function on the same instance of this class are not guaranteed to work. Consider copying the object and using different copies in each thread.

Example
  namespace cbt = ::google::cloud::bigtable;
  using ::google::cloud::future;
  [](cbt::Table table) {
    // Write several rows in a single operation, each row has some trivial data.
    cbt::BulkMutation bulk;
    for (int i = 0; i != 5000; ++i) {
      // Note: This example uses sequential numeric IDs for simplicity, but
      // this can result in poor performance in a production application.
      // Since rows are stored in sorted order by key, sequential keys can
      // result in poor distribution of operations across nodes.
      //
      // For more information about how to design a Bigtable schema for the
      // best performance, see the documentation:
      //
      //     https://cloud.google.com/bigtable/docs/schema-design
      char buf[32];
      snprintf(buf, sizeof(buf), "key-%06d", i);
      cbt::SingleRowMutation mutation(buf);
      mutation.emplace_back(
          cbt::SetCell("fam", "col0", "value0-" + std::to_string(i)));
      mutation.emplace_back(
          cbt::SetCell("fam", "col1", "value2-" + std::to_string(i)));
      mutation.emplace_back(
          cbt::SetCell("fam", "col2", "value3-" + std::to_string(i)));
      mutation.emplace_back(
          cbt::SetCell("fam", "col3", "value4-" + std::to_string(i)));
      bulk.emplace_back(std::move(mutation));
    }

    table.AsyncBulkApply(std::move(bulk))
        .then([](future<std::vector<cbt::FailedMutation>> ft) {
          auto failures = ft.get();
          if (failures.empty()) {
            std::cout << "All the mutations were successful\n";
            return;
          }
          // By default, the `table` object uses the
          // `SafeIdempotentMutationPolicy` which does not retry if any of the
          // mutations fails and are not idempotent. In this example we simply
          // print such failures, if any, and ignore them otherwise.
          std::cerr << "The following mutations failed and were not retried:\n";
          for (auto const& f : failures) {
            std::cerr << "index[" << f.original_index() << "]=" << f.status()
                      << "\n";
          }
        })
        .get();  // block to simplify the example
  }
Parameters
Name Description
mut BulkMutation

the mutations

opts Options

(Optional) Override the class-level options, such as retry, backoff, and idempotency policies.

Returns
Type Description
future< std::vector< FailedMutation > >

a future to be filled with a list of failed mutations, when the operation is complete.

ReadRows(RowSet, Filter, Options)

Reads a set of rows from the table.

Idempotency

This is a read-only operation and therefore it is always idempotent.

Thread-safety

Two threads concurrently calling this member function on the same instance of this class are not guaranteed to work. Consider copying the object and using different copies in each thread. The values returned by different calls are independent with respect to thread-safety, please see the RowReader documentation for more details.

Example
  namespace cbt = ::google::cloud::bigtable;
  using ::google::cloud::StatusOr;
  [](cbt::Table table) {
    // Read and print the rows.
    for (StatusOr<cbt::Row>& row :
         table.ReadRows(cbt::RowRange::Range("phone#4c410523#20190501",
                                             "phone#4c410523#201906201"),
                        cbt::Filter::PassAllFilter())) {
      if (!row) throw std::move(row).status();
      PrintRow(*row);
    }
  }
Parameters
Name Description
row_set RowSet

the rows to read from.

filter Filter

is applied on the server-side to data in the rows.

opts Options

(Optional) Override the class-level options, such as retry, backoff, and idempotency policies.

Returns
Type Description
RowReader

ReadRows(RowSet, std::int64_t, Filter, Options)

Reads a limited set of rows from the table.

Idempotency

This is a read-only operation and therefore it is always idempotent.

Thread-safety

Two threads concurrently calling this member function on the same instance of this class are not guaranteed to work. Consider copying the object and using different copies in each thread. The values returned by different calls are independent with respect to thread-safety, please see the RowReader documentation for more details.

Example
  namespace cbt = ::google::cloud::bigtable;
  using ::google::cloud::StatusOr;
  [](cbt::Table table, std::int64_t limit) {
    // Create the range of rows to read.
    auto range = cbt::RowRange::Range("phone#4c410523#20190501",
                                      "phone#4c410523#20190502");
    // Filter the results, only include values from the "connected_wifi" column
    // in the "stats_summary" column family, and only get the latest value.
    cbt::Filter filter = cbt::Filter::Chain(
        cbt::Filter::ColumnRangeClosed("stats_summary", "connected_wifi",
                                       "connected_wifi"),
        cbt::Filter::Latest(1));
    // Read and print the first rows in the range, within the row limit.
    for (auto& row : table.ReadRows(range, limit, filter)) {
      if (!row) throw std::move(row).status();
      if (row->cells().size() != 1) {
        std::ostringstream os;
        os << "Unexpected number of cells in " << row->row_key();
        throw std::runtime_error(os.str());
      }
      auto const& cell = row->cells().at(0);
      std::cout << cell.row_key() << " = [" << cell.value() << "]\n";
    }
  }
Parameters
Name Description
row_set RowSet

the rows to read from.

rows_limit std::int64_t

the maximum number of rows to read. Cannot be a negative number or zero. Use ReadRows(RowSet, Filter) to read all matching rows.

filter Filter

is applied on the server-side to data in the rows.

opts Options

(Optional) Override the class-level options, such as retry, backoff, and idempotency policies.

Returns
Type Description
RowReader

ReadRow(std::string, Filter, Options)

Read and return a single row from the table.

Idempotency

This is a read-only operation and therefore it is always idempotent.

Thread-safety

Two threads concurrently calling this member function on the same instance of this class are not guaranteed to work. Consider copying the object and using different copies in each thread.

Example
  namespace cbt = ::google::cloud::bigtable;
  using ::google::cloud::StatusOr;
  [](google::cloud::bigtable::Table table, std::string const& row_key) {
    StatusOr<std::pair<bool, cbt::Row>> tuple = table.ReadRow(
        row_key, cbt::Filter::ColumnName("stats_summary", "os_build"));
    if (!tuple) throw std::move(tuple).status();
    if (!tuple->first) {
      std::cout << "Row " << row_key << " not found\n";
      return;
    }
    PrintRow(tuple->second);
  }
Parameters
Name Description
row_key std::string

the row to read.

filter Filter

a filter expression, can be used to select a subset of the column families and columns in the row.

opts Options

(Optional) Override the class-level options, such as retry, backoff, and idempotency policies.

Returns
Type Description
StatusOr< std::pair< bool, Row > >

a tuple, the first element is a boolean, with value false if the row does not exist. If the first element is true the second element has the contents of the Row. Note that the contents may be empty if the filter expression removes all column families and columns.

CheckAndMutateRow(std::string, Filter, std::vector< Mutation >, std::vector< Mutation >, Options)

Atomic test-and-set for a row using filter expressions.

Atomically check the value of a row using a filter expression. If the expression passes (meaning at least one element is returned by it), one set of mutations is applied. If the filter does not pass, a different set of mutations is applied. The changes are atomically applied in the server.

Idempotency

This operation is always treated as non-idempotent.

Thread-safety

Two threads concurrently calling this member function on the same instance of this class are not guaranteed to work. Consider copying the object and using different copies in each thread.

Check for Value Example
  namespace cbt = ::google::cloud::bigtable;
  using ::google::cloud::StatusOr;
  [](cbt::Table table, std::string const& row_key) {
    // Check if the latest value of the flip-flop column is "on".
    cbt::Filter predicate = cbt::Filter::Chain(
        cbt::Filter::ColumnRangeClosed("fam", "flip-flop", "flip-flop"),
        cbt::Filter::Latest(1), cbt::Filter::ValueRegex("on"));
    // If the predicate matches, change the latest value to "off", otherwise,
    // change the latest value to "on".  Modify the "flop-flip" column at the
    // same time.
    StatusOr<cbt::MutationBranch> branch =
        table.CheckAndMutateRow(row_key, std::move(predicate),
                                {cbt::SetCell("fam", "flip-flop", "off"),
                                 cbt::SetCell("fam", "flop-flip", "on")},
                                {cbt::SetCell("fam", "flip-flop", "on"),
                                 cbt::SetCell("fam", "flop-flip", "off")});

    if (!branch) throw std::move(branch).status();
    if (*branch == cbt::MutationBranch::kPredicateMatched) {
      std::cout << "The predicate was matched\n";
    } else {
      std::cout << "The predicate was not matched\n";
    }
  }
Check for Cell Presence Example
  namespace cbt = ::google::cloud::bigtable;
  using ::google::cloud::StatusOr;
  [](cbt::Table table, std::string const& row_key) {
    // Check if the latest value of the "test-column" column is present,
    // regardless of its value.
    cbt::Filter predicate = cbt::Filter::Chain(
        cbt::Filter::ColumnRangeClosed("fam", "test-column", "test-column"),
        cbt::Filter::Latest(1));
    // If the predicate matches, do nothing, otherwise set the
    // "had-test-column" to "false":
    StatusOr<cbt::MutationBranch> branch = table.CheckAndMutateRow(
        row_key, std::move(predicate), {},
        {cbt::SetCell("fam", "had-test-column", "false")});

    if (!branch) throw std::move(branch).status();
    if (*branch == cbt::MutationBranch::kPredicateMatched) {
      std::cout << "The predicate was matched\n";
    } else {
      std::cout << "The predicate was not matched\n";
    }
  }
Parameters
Name Description
row_key std::string

the row to modify.

filter Filter

the filter expression.

true_mutations std::vector< Mutation >

the mutations for the "filter passed" case.

false_mutations std::vector< Mutation >

the mutations for the "filter did not pass" case.

opts Options

(Optional) Override the class-level options, such as retry, backoff, and idempotency policies.

Returns
Type Description
StatusOr< MutationBranch >

true if the filter passed.

AsyncCheckAndMutateRow(std::string, Filter, std::vector< Mutation >, std::vector< Mutation >, Options)

Make an asynchronous request to conditionally mutate a row.

Idempotency

This operation is always treated as non-idempotent.

Thread-safety

Two threads concurrently calling this member function on the same instance of this class are not guaranteed to work. Consider copying the object and using different copies in each thread.

Example
  namespace cbt = ::google::cloud::bigtable;
  using ::google::cloud::future;
  using ::google::cloud::StatusOr;
  [](cbt::Table table, std::string const& row_key) {
    // Check if the latest value of the flip-flop column is "on".
    cbt::Filter predicate = cbt::Filter::Chain(
        cbt::Filter::ColumnRangeClosed("fam", "flip-flop", "flip-flop"),
        cbt::Filter::Latest(1), cbt::Filter::ValueRegex("on"));
    future<StatusOr<cbt::MutationBranch>> branch_future =
        table.AsyncCheckAndMutateRow(row_key, std::move(predicate),
                                     {cbt::SetCell("fam", "flip-flop", "off"),
                                      cbt::SetCell("fam", "flop-flip", "on")},
                                     {cbt::SetCell("fam", "flip-flop", "on"),
                                      cbt::SetCell("fam", "flop-flip", "off")});

    branch_future
        .then([](future<StatusOr<cbt::MutationBranch>> f) {
          auto response = f.get();
          if (!response) throw std::move(response).status();
          if (*response == cbt::MutationBranch::kPredicateMatched) {
            std::cout << "The predicate was matched\n";
          } else {
            std::cout << "The predicate was not matched\n";
          }
        })
        .get();  // block to simplify the example.
  }
Parameters
Name Description
row_key std::string

the row key on which the conditional mutation will be performed

filter Filter

the condition, depending on which the mutation will be performed

true_mutations std::vector< Mutation >

the mutations which will be performed if filter is true

false_mutations std::vector< Mutation >

the mutations which will be performed if filter is false

opts Options

(Optional) Override the class-level options, such as retry, backoff, and idempotency policies.

Returns
Type Description
future< StatusOr< MutationBranch > >

SampleRows(Options)

Sample of the row keys in the table, including approximate data sizes.

Idempotency

This operation is always treated as idempotent.

Thread-safety

Two threads concurrently calling this member function on the same instance of this class are not guaranteed to work. Consider copying the object and using different copies in each thread.

Examples
  namespace cbt = ::google::cloud::bigtable;
  using ::google::cloud::StatusOr;
  [](cbt::Table table) {
    StatusOr<std::vector<cbt::RowKeySample>> samples = table.SampleRows();
    if (!samples) throw std::move(samples).status();
    for (auto const& sample : *samples) {
      std::cout << "key=" << sample.row_key << " - " << sample.offset_bytes
                << "\n";
    }
  }
Parameter
Name Description
opts Options
Returns
Type Description
StatusOr< std::vector< bigtable::RowKeySample > >

AsyncSampleRows(Options)

Asynchronously obtains a sample of the row keys in the table, including approximate data sizes.

Idempotency

This operation is always treated as idempotent.

Thread-safety

Two threads concurrently calling this member function on the same instance of this class are not guaranteed to work. Consider copying the object and using different copies in each thread.

Examples
  namespace cbt = ::google::cloud::bigtable;
  using ::google::cloud::future;
  using ::google::cloud::StatusOr;
  [](cbt::Table table) {
    future<StatusOr<std::vector<cbt::RowKeySample>>> samples_future =
        table.AsyncSampleRows();

    samples_future
        .then([](future<StatusOr<std::vector<cbt::RowKeySample>>> f) {
          auto samples = f.get();
          if (!samples) throw std::move(samples).status();
          for (auto const& sample : *samples) {
            std::cout << "key=" << sample.row_key << " - "
                      << sample.offset_bytes << "\n";
          }
        })
        .get();  // block to simplify the example.
  }
Parameter
Name Description
opts Options
Returns
Type Description
future< StatusOr< std::vector< bigtable::RowKeySample > > >

a future, that becomes satisfied when the operation completes.

ReadModifyWriteRow(std::string, bigtable::ReadModifyWriteRule, Args &&...)

Atomically read and modify the row in the server, returning the resulting row.

Idempotency

This operation is always treated as non-idempotent.

Thread-safety

Two threads concurrently calling this member function on the same instance of this class are not guaranteed to work. Consider copying the object and using different copies in each thread.

Example
  namespace cbt = ::google::cloud::bigtable;
  using ::google::cloud::StatusOr;
  [](cbt::Table table, std::string const& row_key) {
    StatusOr<cbt::Row> row = table.ReadModifyWriteRow(
        row_key, cbt::ReadModifyWriteRule::IncrementAmount("fam", "counter", 1),
        cbt::ReadModifyWriteRule::AppendValue("fam", "list", ";element"));

    // As the modify in this example is not idempotent, and this example
    // does not attempt to retry if there is a failure, we simply print
    // such failures, if any, and otherwise ignore them.
    if (!row) {
      std::cout << "Failed to append row: " << row.status().message() << "\n";
      return;
    }
    // Print the contents of the row
    std::cout << row->row_key() << "\n";
    for (auto const& cell : row->cells()) {
      std::cout << "    " << cell.family_name() << ":"
                << cell.column_qualifier() << " = <";
      if (cell.column_qualifier() == "counter") {
        // This example uses "counter" to store 64-bit numbers in big-endian
        // format, extract them as follows:
        std::cout << cell.decode_big_endian_integer<std::int64_t>().value();
      } else {
        std::cout << cell.value();
      }
      std::cout << ">\n";
    }
  }
Parameters
Name Description
row_key std::string

the row to read

rule bigtable::ReadModifyWriteRule

to modify the row. Two types of rules are applied here AppendValue which will read the existing value and append the text provided to the value. IncrementAmount which will read the existing uint64 big-endian-int and add the value provided. Both rules accept the family and column identifier to modify.

rules_and_options Args &&...

is the zero or more ReadModifyWriteRules to apply on a row. Options to override the class-level options, such as retry, backoff, and idempotency policies are also be passed via this parameter pack.

typename...
Returns
Type Description
StatusOr< Row >

the new contents of all modified cells.

AsyncReadModifyWriteRow(std::string, bigtable::ReadModifyWriteRule, Args &&...)

Make an asynchronous request to atomically read and modify a row.

Idempotency

This operation is always treated as non-idempotent.

Thread-safety

Two threads concurrently calling this member function on the same instance of this class are not guaranteed to work.

Example
  namespace cbt = ::google::cloud::bigtable;
  using ::google::cloud::future;
  using ::google::cloud::StatusOr;
  [](cbt::Table table, std::string const& row_key) {
    future<StatusOr<cbt::Row>> row_future = table.AsyncReadModifyWriteRow(
        row_key,
        cbt::ReadModifyWriteRule::AppendValue("fam", "list", ";element"));

    row_future
        .then([](future<StatusOr<cbt::Row>> f) {
          auto row = f.get();
          // As the modify in this example is not idempotent, and this example
          // does not attempt to retry if there is a failure, we simply print
          // such failures, if any, and otherwise ignore them.
          if (!row) {
            std::cout << "Failed to append row: " << row.status().message()
                      << "\n";
            return;
          }
          std::cout << "Successfully appended to " << row->row_key() << "\n";
        })
        .get();  // block to simplify example.
  }
Parameters
Name Description
row_key std::string

the row key on which modification will be performed

rule bigtable::ReadModifyWriteRule

to modify the row. Two types of rules are applied here AppendValue which will read the existing value and append the text provided to the value. IncrementAmount which will read the existing uint64 big-endian-int and add the value provided. Both rules accept the family and column identifier to modify.

rules_and_options Args &&...

is the zero or more ReadModifyWriteRules to apply on a row. Options to override the class-level options, such as retry, backoff, and idempotency policies are also be passed via this parameter pack.

typename...
Returns
Type Description
future< StatusOr< Row > >

a future, that becomes satisfied when the operation completes, at that point the future has the contents of all modified cells.

AsyncReadRows(RowFunctor, FinishFunctor, RowSet, Filter, Options)

Asynchronously reads a set of rows from the table.

Thread-safety

Two threads concurrently calling this member function on the same instance of this class are not guaranteed to work. Consider copying the object and using different copies in each thread.

Example
  namespace cbt = ::google::cloud::bigtable;
  using ::google::cloud::make_ready_future;
  using ::google::cloud::promise;
  using ::google::cloud::Status;
  [](cbt::Table table) {
    // Create the range of rows to read.
    auto range = cbt::RowRange::Range("key-000010", "key-000020");
    // Filter the results, only include values from the "col0" column in the
    // "fam" column family, and only get the latest value.
    auto filter = cbt::Filter::Chain(
        cbt::Filter::ColumnRangeClosed("fam", "col0", "col0"),
        cbt::Filter::Latest(1));
    promise<Status> stream_status_promise;
    // Read and print the rows.
    table.AsyncReadRows(
        [](cbt::Row const& row) {
          if (row.cells().size() != 1) {
            std::cout << "Unexpected number of cells in " << row.row_key()
                      << "\n";
            return make_ready_future(false);
          }
          auto const& cell = row.cells().at(0);
          std::cout << cell.row_key() << " = [" << cell.value() << "]\n";
          return make_ready_future(true);
        },
        [&stream_status_promise](Status const& stream_status) {
          stream_status_promise.set_value(stream_status);
        },
        range, filter);
    Status stream_status = stream_status_promise.get_future().get();
    if (!stream_status.ok()) throw std::runtime_error(stream_status.message());
  }
Parameters
Name Description
on_row RowFunctor

the callback to be invoked on each successfully read row; it should be invocable with Row and return a future

on_finish FinishFunctor

the callback to be invoked when the stream is closed; it should be invocable with Status and not return anything; it will always be called as the last callback; if on_finish throws, the results are undefined

row_set RowSet

the rows to read from.

filter Filter

is applied on the server-side to data in the rows.

opts Options

(Optional) Override the class-level options, such as retry, backoff, and idempotency policies.

typename RowFunctor

the type of the on_row callback.

typename FinishFunctor

the type of the on_finish callback.

Returns
Type Description
void

AsyncReadRows(RowFunctor, FinishFunctor, RowSet, std::int64_t, Filter, Options)

Asynchronously reads a set of rows from the table.

Thread-safety

Two threads concurrently calling this member function on the same instance of this class are not guaranteed to work. Consider copying the object and using different copies in each thread. The callbacks passed to this function may be executed on any thread running the provided completion queue.

Example
  namespace cbt = ::google::cloud::bigtable;
  using ::google::cloud::make_ready_future;
  using ::google::cloud::promise;
  using ::google::cloud::Status;
  [](cbt::Table table, std::int64_t const& limit) {
    // Create the range of rows to read.
    auto range = cbt::RowRange::Range("key-000010", "key-000020");
    // Filter the results, only include values from the "col0" column in the
    // "fam" column family, and only get the latest value.
    auto filter = cbt::Filter::Chain(
        cbt::Filter::ColumnRangeClosed("fam", "col0", "col0"),
        cbt::Filter::Latest(1));
    promise<Status> stream_status_promise;
    // Read and print the rows.
    table.AsyncReadRows(
        [](cbt::Row const& row) {
          if (row.cells().size() != 1) {
            std::cout << "Unexpected number of cells in " << row.row_key()
                      << "\n";
            return make_ready_future(false);
          }
          auto const& cell = row.cells().at(0);
          std::cout << cell.row_key() << " = [" << cell.value() << "]\n";
          return make_ready_future(true);
        },
        [&stream_status_promise](Status const& stream_status) {
          stream_status_promise.set_value(stream_status);
        },
        range, limit, filter);
    Status stream_status = stream_status_promise.get_future().get();
    if (!stream_status.ok()) throw std::runtime_error(stream_status.message());
  }
Parameters
Name Description
on_row RowFunctor

the callback to be invoked on each successfully read row; it should be invocable with Row and return a future

on_finish FinishFunctor

the callback to be invoked when the stream is closed; it should be invocable with Status and not return anything; it will always be called as the last callback; if on_finish throws, the results are undefined

row_set RowSet

the rows to read from.

rows_limit std::int64_t

the maximum number of rows to read. Cannot be a negative number or zero. Use AsyncReadRows(RowSet, Filter) to read all matching rows.

filter Filter

is applied on the server-side to data in the rows.

opts Options

(Optional) Override the class-level options, such as retry, backoff, and idempotency policies.

typename RowFunctor

the type of the on_row callback.

typename FinishFunctor

the type of the on_finish callback.

Returns
Type Description
void

AsyncReadRow(std::string, Filter, Options)

Asynchronously read and return a single row from the table.

Idempotency

This is a read-only operation and therefore it is always idempotent.

Thread-safety

Two threads concurrently calling this member function on the same instance of this class are not guaranteed to work. Consider copying the object and using different copies in each thread.

Example
  namespace cbt = ::google::cloud::bigtable;
  using ::google::cloud::future;
  using ::google::cloud::StatusOr;
  [](google::cloud::bigtable::Table table, std::string const& row_key) {
    // Filter the results, only include the latest value on each cell.
    cbt::Filter filter = cbt::Filter::Latest(1);
    table.AsyncReadRow(row_key, std::move(filter))
        .then(
            [row_key](future<StatusOr<std::pair<bool, cbt::Row>>> row_future) {
              // Read a row, this returns a tuple (bool, row)
              auto tuple = row_future.get();
              if (!tuple) throw std::move(tuple).status();
              if (!tuple->first) {
                std::cout << "Row " << row_key << " not found\n";
                return;
              }
              std::cout << "key: " << tuple->second.row_key() << "\n";
              for (auto const& cell : tuple->second.cells()) {
                std::cout << "    " << cell.family_name() << ":"
                          << cell.column_qualifier() << " = <";
                if (cell.column_qualifier() == "counter") {
                  // This example uses "counter" to store 64-bit numbers in
                  // big-endian format, extract them as follows:
                  std::cout
                      << cell.decode_big_endian_integer<std::int64_t>().value();
                } else {
                  std::cout << cell.value();
                }
                std::cout << ">\n";
              }
            })
        .get();  // block to simplify the example
  }
Parameters
Name Description
row_key std::string

the row to read.

filter Filter

a filter expression, can be used to select a subset of the column families and columns in the row.

opts Options

(Optional) Override the class-level options, such as retry, backoff, and idempotency policies.

Returns
Type Description
future< StatusOr< std::pair< bool, Row > > >

a future satisfied when the operation completes, fails permanently or keeps failing transiently, but the retry policy has been exhausted. The future will return a tuple. The first element is a boolean, with value false if the row does not exist. If the first element is true the second element has the contents of the Row. Note that the contents may be empty if the filter expression removes all column families and columns.