The main interface to interact with data in a Cloud Bigtable table.
This class provides member functions to:
- read specific rows:
Table::ReadRow()
- scan a ranges of rows:
Table::ReadRows()
- update or create a single row:
Table::Apply()
- update or modify multiple rows:
Table::BulkApply()
- update a row based on previous values:
Table::CheckAndMutateRow()
- to atomically append data and/or increment multiple values in a row:
Table::ReadModifyWriteRow()
- to sample the row keys:
Table::SampleRows()
.
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<T>
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 |
tr |
TableResource
identifies the table resource by its project, instance, and table ids. |
options |
Options
Configuration options for the table. Use |
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 |
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 |
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());
IdempotentMutationPolicy
which mutations are retried. UseSafeIdempotentMutationPolicy
to only retry idempotent operations, useAlwaysRetryMutationPolicy
to retry all operations. Read the caveats in the class definition to understand the downsides of the latter. You can also create your own policies that decide which mutations to retry.RPCBackoffPolicy
how to backoff from a failed RPC. Currently onlyExponentialBackoffPolicy
is implemented. You can also create your own policies that backoff using a different algorithm.RPCRetryPolicy
for how long to retry failed RPCs. UseLimitedErrorCountRetryPolicy
to limit the number of failures allowed. UseLimitedTimeRetryPolicy
to bound the time for any request. You can also create your own policies that combine time and error counts.
See Also
SafeIdempotentMutationPolicy, AlwaysRetryMutationPolicy, ExponentialBackoffPolicy, LimitedErrorCountRetryPolicy, LimitedTimeRetryPolicy.
google::cloud::bigtable::DataConnection
is the preferred way to communicate with the Bigtable Data API. To migrate existing code, see Migrating from DataClient.
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 |
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.
google::cloud::bigtable::DataConnection
is the preferred way to communicate with the Bigtable Data API. To migrate existing code, see Migrating from DataClient.
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 |
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 |
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 |
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 (auto& 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 |
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 |
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 |
false_mutations |
std::vector< Mutation >
the mutations which will be performed if |
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(
std::move(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
|
on_finish |
FinishFunctor
the callback to be invoked when the stream is closed; it should be invocable with |
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 |
typename FinishFunctor |
the type of the |
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
|
on_finish |
FinishFunctor
the callback to be invoked when the stream is closed; it should be invocable with |
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 |
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 |
typename FinishFunctor |
the type of the |
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 |