Skip to content

Commit 6803271

Browse files
authored
Use milliseconds in bigtable::SetCell (#335)
The timestamps must be in milliseconds, so make it hard for the user to make a mistake with them. This fixes #274.
1 parent 86a70bc commit 6803271

14 files changed

Lines changed: 149 additions & 140 deletions

bigtable/benchmarks/embedded_server_test.cc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "bigtable/client/table_admin.h"
2020

2121
using namespace bigtable::benchmarks;
22+
using std::chrono::milliseconds;
2223

2324
TEST(EmbeddedServer, WaitAndShutdown) {
2425
auto server = CreateEmbeddedServer();
@@ -69,8 +70,8 @@ TEST(EmbeddedServer, TableApply) {
6970

7071
bigtable::SingleRowMutation mutation(
7172
"row1",
72-
{bigtable::SetCell("fam", "col", 0, "val"),
73-
bigtable::SetCell("fam", "col", 0, "val")});
73+
{bigtable::SetCell("fam", "col", milliseconds(0), "val"),
74+
bigtable::SetCell("fam", "col", milliseconds(0), "val")});
7475

7576
EXPECT_EQ(0, server->mutate_row_count());
7677
table.Apply(std::move(mutation));
@@ -93,9 +94,9 @@ TEST(EmbeddedServer, TableBulkApply) {
9394

9495
bigtable::BulkMutation bulk;
9596
bulk.emplace_back(bigtable::SingleRowMutation(
96-
"row1", {bigtable::SetCell("fam", "col", 0, "val")}));
97+
"row1", {bigtable::SetCell("fam", "col", milliseconds(0), "val")}));
9798
bulk.emplace_back(bigtable::SingleRowMutation(
98-
"row2", {bigtable::SetCell("fam", "col", 0, "val")}));
99+
"row2", {bigtable::SetCell("fam", "col", milliseconds(0), "val")}));
99100

100101
EXPECT_EQ(0, server->mutate_rows_count());
101102
table.BulkApply(std::move(bulk));

bigtable/benchmarks/random.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ std::string Sample(DefaultPRNG& gen, int n, std::string const& population) {
2828

2929
bigtable::Mutation MakeRandomMutation(DefaultPRNG& gen, int f) {
3030
std::string field = "field" + std::to_string(f);
31-
return bigtable::SetCell(kColumnFamily, std::move(field), 0,
32-
MakeRandomValue(gen));
31+
return bigtable::SetCell(kColumnFamily, std::move(field),
32+
std::chrono::milliseconds(0), MakeRandomValue(gen));
3333
}
3434

3535
std::string MakeRandomValue(DefaultPRNG& generator) {

bigtable/client/idempotent_mutation_policy_test.cc

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,38 +13,35 @@
1313
// limitations under the License.
1414

1515
#include "bigtable/client/idempotent_mutation_policy.h"
16-
1716
#include <gmock/gmock.h>
17+
#include "bigtable/client/testing/chrono_literals.h"
1818

1919
/// @test Verify that the default policy works as expected.
2020
TEST(IdempotentMutationPolicyTest, Simple) {
21+
using namespace bigtable::chrono_literals;
2122
auto policy = bigtable::DefaultIdempotentMutationPolicy();
2223
EXPECT_TRUE(policy->is_idempotent(
2324
bigtable::DeleteFromColumn("fam", "col", 0, 10).op));
2425
EXPECT_TRUE(policy->is_idempotent(bigtable::DeleteFromFamily("fam").op));
2526

2627
EXPECT_TRUE(
27-
policy->is_idempotent(bigtable::SetCell("fam", "col", 0, "v1").op));
28+
policy->is_idempotent(bigtable::SetCell("fam", "col", 0_ms, "v1").op));
2829
EXPECT_FALSE(policy->is_idempotent(bigtable::SetCell("fam", "c2", "v2").op));
29-
EXPECT_FALSE(policy->is_idempotent(
30-
bigtable::SetCell("f", "c", bigtable::ServerSetTimestamp(), "v").op));
3130
}
3231

3332
/// @test Verify that bigtable::AlwaysRetryMutationPolicy works as expected.
3433
TEST(IdempotentMutationPolicyTest, AlwaysRetry) {
34+
using namespace bigtable::chrono_literals;
3535
bigtable::AlwaysRetryMutationPolicy policy;
3636
EXPECT_TRUE(
3737
policy.is_idempotent(bigtable::DeleteFromColumn("fam", "col", 0, 10).op));
3838
EXPECT_TRUE(policy.is_idempotent(bigtable::DeleteFromFamily("fam").op));
3939

4040
EXPECT_TRUE(
41-
policy.is_idempotent(bigtable::SetCell("fam", "col", 0, "v1").op));
41+
policy.is_idempotent(bigtable::SetCell("fam", "col", 0_ms, "v1").op));
4242
EXPECT_TRUE(policy.is_idempotent(bigtable::SetCell("fam", "c2", "v2").op));
43-
EXPECT_TRUE(policy.is_idempotent(
44-
bigtable::SetCell("f", "c", bigtable::ServerSetTimestamp(), "v").op));
4543

4644
auto clone = policy.clone();
47-
EXPECT_TRUE(clone->is_idempotent(
48-
bigtable::SetCell("f", "c", bigtable::ServerSetTimestamp(), "v").op));
49-
EXPECT_TRUE(clone->is_idempotent(bigtable::SetCell("f", "c", 10, "v").op));
45+
EXPECT_TRUE(clone->is_idempotent(bigtable::SetCell("f", "c", "v").op));
46+
EXPECT_TRUE(clone->is_idempotent(bigtable::SetCell("f", "c", 10_ms, "v").op));
5047
}

bigtable/client/internal/bulk_mutator_test.cc

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,9 @@
1313
// limitations under the License.
1414

1515
#include "bigtable/client/internal/bulk_mutator.h"
16-
1716
#include <google/bigtable/v2/bigtable_mock.grpc.pb.h>
18-
1917
#include "bigtable/client/internal/make_unique.h"
18+
#include "bigtable/client/testing/chrono_literals.h"
2019

2120
/// Define types and functions used in the tests.
2221
namespace {
@@ -35,12 +34,13 @@ TEST(MultipleRowsMutatorTest, Simple) {
3534
namespace btproto = ::google::bigtable::v2;
3635
namespace bt = ::bigtable;
3736
using namespace ::testing;
37+
using namespace bigtable::chrono_literals;
3838

3939
// In this test we create a Mutation for two rows, which succeeds in the
4040
// first RPC request. First create the mutation.
4141
bt::BulkMutation mut(
42-
bt::SingleRowMutation("foo", {bt::SetCell("fam", "col", 0, "baz")}),
43-
bt::SingleRowMutation("bar", {bt::SetCell("fam", "col", 0, "qux")}));
42+
bt::SingleRowMutation("foo", {bt::SetCell("fam", "col", 0_ms, "baz")}),
43+
bt::SingleRowMutation("bar", {bt::SetCell("fam", "col", 0_ms, "qux")}));
4444

4545
// Prepare the mocks. The mutator should issue a RPC which must return a
4646
// stream of responses, we prepare the stream first because it is easier than
@@ -88,12 +88,13 @@ TEST(MultipleRowsMutatorTest, RetryPartialFailure) {
8888
namespace btproto = ::google::bigtable::v2;
8989
namespace bt = ::bigtable;
9090
using namespace ::testing;
91+
using namespace bigtable::chrono_literals;
9192

9293
// In this test we create a Mutation for two rows, one of which will fail.
9394
// First create the mutation.
9495
bt::BulkMutation mut(
95-
bt::SingleRowMutation("foo", {bt::SetCell("fam", "col", 0, "baz")}),
96-
bt::SingleRowMutation("bar", {bt::SetCell("fam", "col", 0, "qux")}));
96+
bt::SingleRowMutation("foo", {bt::SetCell("fam", "col", 0_ms, "baz")}),
97+
bt::SingleRowMutation("bar", {bt::SetCell("fam", "col", 0_ms, "qux")}));
9798

9899
// Prepare the mocks for the request. First create a stream response which
99100
// indicates a partial failure.
@@ -162,12 +163,13 @@ TEST(MultipleRowsMutatorTest, PermanentFailure) {
162163
namespace btproto = ::google::bigtable::v2;
163164
namespace bt = ::bigtable;
164165
using namespace ::testing;
166+
using namespace bigtable::chrono_literals;
165167

166168
// In this test we handle a recoverable and one unrecoverable failures.
167169
// Create a bulk mutation with two SetCell() mutations.
168170
bt::BulkMutation mut(
169-
bt::SingleRowMutation("foo", {bt::SetCell("fam", "col", 0, "baz")}),
170-
bt::SingleRowMutation("bar", {bt::SetCell("fam", "col", 0, "qux")}));
171+
bt::SingleRowMutation("foo", {bt::SetCell("fam", "col", 0_ms, "baz")}),
172+
bt::SingleRowMutation("bar", {bt::SetCell("fam", "col", 0_ms, "qux")}));
171173

172174
// Make the first RPC return one recoverable and one unrecoverable failures.
173175
auto r1 = bigtable::internal::make_unique<MockReader>();
@@ -237,12 +239,13 @@ TEST(MultipleRowsMutatorTest, PartialStream) {
237239
namespace btproto = ::google::bigtable::v2;
238240
namespace bt = ::bigtable;
239241
using namespace ::testing;
242+
using namespace bigtable::chrono_literals;
240243

241244
// We are going to test the case where the stream does not contain a response
242245
// for all requests. Create a BulkMutation with two entries.
243246
bt::BulkMutation mut(
244-
bt::SingleRowMutation("foo", {bt::SetCell("fam", "col", 0, "baz")}),
245-
bt::SingleRowMutation("bar", {bt::SetCell("fam", "col", 0, "qux")}));
247+
bt::SingleRowMutation("foo", {bt::SetCell("fam", "col", 0_ms, "baz")}),
248+
bt::SingleRowMutation("bar", {bt::SetCell("fam", "col", 0_ms, "qux")}));
246249

247250
// This will be the stream returned by the first request. It is missing
248251
// information about one of the mutations.
@@ -305,11 +308,12 @@ TEST(MultipleRowsMutatorTest, RetryOnlyIdempotent) {
305308
namespace btproto = ::google::bigtable::v2;
306309
namespace bt = ::bigtable;
307310
using namespace ::testing;
311+
using namespace bigtable::chrono_literals;
308312

309313
// Create a BulkMutation with a non-idempotent mutation.
310314
bt::BulkMutation mut(
311315
bt::SingleRowMutation("foo", {bt::SetCell("fam", "col", "baz")}),
312-
bt::SingleRowMutation("bar", {bt::SetCell("fam", "col", 0, "qux")}),
316+
bt::SingleRowMutation("bar", {bt::SetCell("fam", "col", 0_ms, "qux")}),
313317
bt::SingleRowMutation("baz", {bt::SetCell("fam", "col", "v")}));
314318

315319
// We will setup the mock to return recoverable failures for idempotent

bigtable/client/mutations.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@
1717

1818
namespace bigtable {
1919
inline namespace BIGTABLE_CLIENT_NS {
20-
Mutation SetCell(std::string family, std::string column, std::int64_t timestamp,
21-
std::string value) {
20+
Mutation SetCell(std::string family, std::string column,
21+
std::chrono::milliseconds timestamp, std::string value) {
2222
Mutation m;
2323
auto& set_cell = *m.op.mutable_set_cell();
2424
set_cell.set_family_name(std::move(family));
2525
set_cell.set_column_qualifier(std::move(column));
26-
set_cell.set_timestamp_micros(timestamp);
26+
set_cell.set_timestamp_micros(
27+
std::chrono::duration_cast<std::chrono::microseconds>(timestamp).count());
2728
set_cell.set_value(std::move(value));
2829
return m;
2930
}

bigtable/client/mutations.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ struct Mutation {
3838
};
3939

4040
/// Create a mutation to set a cell value.
41-
Mutation SetCell(std::string family, std::string column, std::int64_t timestamp,
42-
std::string value);
41+
Mutation SetCell(std::string family, std::string column,
42+
std::chrono::milliseconds timestamp, std::string value);
4343

4444
/**
4545
* Create a mutation to set a cell value where the server sets the time.

bigtable/client/mutations_test.cc

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,17 @@
1515
#include "bigtable/client/mutations.h"
1616
#include <gmock/gmock.h>
1717
#include <google/rpc/error_details.pb.h>
18+
#include "bigtable/client/testing/chrono_literals.h"
19+
20+
using namespace bigtable::chrono_literals;
1821

1922
/// @test Verify that SetCell() works as expected.
2023
TEST(MutationsTest, SetCell) {
21-
auto actual = bigtable::SetCell("family", "col", 1234, "value");
24+
auto actual = bigtable::SetCell("family", "col", 1234_ms, "value");
2225
ASSERT_TRUE(actual.op.has_set_cell());
2326
EXPECT_EQ("family", actual.op.set_cell().family_name());
2427
EXPECT_EQ("col", actual.op.set_cell().column_qualifier());
25-
EXPECT_EQ(1234, actual.op.set_cell().timestamp_micros());
28+
EXPECT_EQ(1234000, actual.op.set_cell().timestamp_micros());
2629
EXPECT_EQ("value", actual.op.set_cell().value());
2730

2831
auto server_set = bigtable::SetCell("fam", "col", "v");
@@ -40,8 +43,8 @@ TEST(MutationsTest, SetCell) {
4043
// work around that optimization and test the move behavior.
4144
std::string val(1000000, 'a');
4245
auto val_data = val.data();
43-
auto moved =
44-
bigtable::SetCell(std::move(fam), std::move(col), 2345, std::move(val));
46+
auto moved = bigtable::SetCell(std::move(fam), std::move(col), 2345_ms,
47+
std::move(val));
4548
ASSERT_TRUE(moved.op.has_set_cell());
4649
EXPECT_EQ("fam2", moved.op.set_cell().family_name());
4750
EXPECT_EQ("col2", moved.op.set_cell().column_qualifier());
@@ -113,7 +116,7 @@ TEST(MutationsTest, DeleteFromRow) {
113116
// @test Verify that FailedMutation works as expected.
114117
TEST(MutationsTest, FailedMutation) {
115118
bigtable::SingleRowMutation mut("foo",
116-
{bigtable::SetCell("f", "c", 0, "val")});
119+
{bigtable::SetCell("f", "c", 0_ms, "val")});
117120

118121
// Create an overly complicated detail status, the idea is to make
119122
// sure it works in this case.
@@ -153,9 +156,9 @@ TEST(MutationsTest, MutipleRowMutations) {
153156

154157
actual
155158
.emplace_back(bigtable::SingleRowMutation(
156-
"foo1", {bigtable::SetCell("f", "c", 0, "v1")}))
159+
"foo1", {bigtable::SetCell("f", "c", 0_ms, "v1")}))
157160
.push_back(bigtable::SingleRowMutation(
158-
"foo2", {bigtable::SetCell("f", "c", 0, "v2")}));
161+
"foo2", {bigtable::SetCell("f", "c", 0_ms, "v2")}));
159162

160163
actual.MoveTo(&request);
161164
ASSERT_EQ(2, request.entries_size());
@@ -164,11 +167,11 @@ TEST(MutationsTest, MutipleRowMutations) {
164167

165168
std::vector<bigtable::SingleRowMutation> vec{
166169
bigtable::SingleRowMutation("foo1",
167-
{bigtable::SetCell("f", "c", 0, "v1")}),
170+
{bigtable::SetCell("f", "c", 0_ms, "v1")}),
168171
bigtable::SingleRowMutation("foo2",
169-
{bigtable::SetCell("f", "c", 0, "v2")}),
172+
{bigtable::SetCell("f", "c", 0_ms, "v2")}),
170173
bigtable::SingleRowMutation("foo3",
171-
{bigtable::SetCell("f", "c", 0, "v3")}),
174+
{bigtable::SetCell("f", "c", 0_ms, "v3")}),
172175
};
173176
bigtable::BulkMutation from_vec(vec.begin(), vec.end());
174177

@@ -180,9 +183,9 @@ TEST(MutationsTest, MutipleRowMutations) {
180183

181184
bigtable::BulkMutation from_il{
182185
bigtable::SingleRowMutation("foo2",
183-
{bigtable::SetCell("f", "c", 0, "v2")}),
186+
{bigtable::SetCell("f", "c", 0_ms, "v2")}),
184187
bigtable::SingleRowMutation("foo3",
185-
{bigtable::SetCell("f", "c", 0, "v3")}),
188+
{bigtable::SetCell("f", "c", 0_ms, "v3")}),
186189
};
187190
from_il.MoveTo(&request);
188191
ASSERT_EQ(2, request.entries_size());
@@ -195,8 +198,8 @@ TEST(MutationsTest, SingleRowMutationMultipleVariadic) {
195198
std::string const row_key = "row-key-1";
196199

197200
bigtable::SingleRowMutation actual(
198-
row_key, bigtable::SetCell("family", "c1", 1000, "V1000"),
199-
bigtable::SetCell("family", "c2", 2000, "V2000"));
201+
row_key, bigtable::SetCell("family", "c1", 1_ms, "V1000"),
202+
bigtable::SetCell("family", "c2", 2_ms, "V2000"));
200203

201204
google::bigtable::v2::MutateRowsRequest::Entry entry;
202205
(void)entry.add_mutations();
@@ -212,7 +215,7 @@ TEST(MutationsTest, SingleRowMutationSingleVariadic) {
212215
std::string const row_key = "row-key-1";
213216

214217
bigtable::SingleRowMutation actual(
215-
row_key, bigtable::SetCell("family", "c1", 1000, "V1000"));
218+
row_key, bigtable::SetCell("family", "c1", 1_ms, "V1000"));
216219

217220
google::bigtable::v2::MutateRowsRequest::Entry entry;
218221
(void)entry.add_mutations();

bigtable/client/table_apply_test.cc

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// limitations under the License.
1414

1515
#include "bigtable/client/table.h"
16+
#include "bigtable/client/testing/chrono_literals.h"
1617
#include "bigtable/client/testing/table_test_fixture.h"
1718

1819
/// Define helper types and functions for this test.
@@ -21,14 +22,17 @@ class TableApplyTest : public bigtable::testing::TableTestFixture {};
2122
} // anonymous namespace
2223

2324
/// @test Verify that Table::Apply() works in a simplest case.
25+
26+
using namespace bigtable::chrono_literals;
27+
2428
TEST_F(TableApplyTest, Simple) {
2529
using namespace ::testing;
2630

2731
EXPECT_CALL(*bigtable_stub_, MutateRow(_, _, _))
2832
.WillOnce(Return(grpc::Status::OK));
2933

3034
table_.Apply(bigtable::SingleRowMutation(
31-
"bar", {bigtable::SetCell("fam", "col", 0, "val")}));
35+
"bar", {bigtable::SetCell("fam", "col", 0_ms, "val")}));
3236
}
3337

3438
/// @test Verify that Table::Apply() raises an exception on permanent failures.
@@ -41,12 +45,12 @@ TEST_F(TableApplyTest, Failure) {
4145

4246
#if GOOGLE_CLOUD_CPP_HAVE_EXCEPTIONS
4347
EXPECT_THROW(table_.Apply(bigtable::SingleRowMutation(
44-
"bar", {bigtable::SetCell("fam", "col", 0, "val")})),
48+
"bar", {bigtable::SetCell("fam", "col", 0_ms, "val")})),
4549
std::exception);
4650
#else
4751
EXPECT_DEATH_IF_SUPPORTED(
4852
table_.Apply(bigtable::SingleRowMutation(
49-
"bar", {bigtable::SetCell("fam", "col", 0, "val")})),
53+
"bar", {bigtable::SetCell("fam", "col", 0_ms, "val")})),
5054
"exceptions are disabled");
5155
#endif // GOOGLE_CLOUD_CPP_HAVE_EXCEPTIONS
5256
}
@@ -65,7 +69,7 @@ TEST_F(TableApplyTest, Retry) {
6569
.WillOnce(Return(grpc::Status::OK));
6670

6771
table_.Apply(bigtable::SingleRowMutation(
68-
"bar", {bigtable::SetCell("fam", "col", 0, "val")}));
72+
"bar", {bigtable::SetCell("fam", "col", 0_ms, "val")}));
6973
}
7074

7175
/// @test Verify that Table::Apply() retries only idempotent mutations.

0 commit comments

Comments
 (0)