@@ -117,10 +117,16 @@ int main(int argc, char* argv[]) {
117117 config.instance_id = *std::move (instance);
118118 }
119119
120- cs::Database database (
121- config.project_id , config.instance_id ,
122- google::cloud::spanner_testing::RandomDatabaseName (generator));
123- config.database_id = database.database_id ();
120+ // If the user specified a database name on the command line, re-use it to
121+ // reduce setup time when running the benchmark repeatedly. It's assumed that
122+ // other flags related to database creation have not been changed across runs.
123+ bool user_specified_database = !config.database_id .empty ();
124+ if (!user_specified_database) {
125+ config.database_id =
126+ google::cloud::spanner_testing::RandomDatabaseName (generator);
127+ }
128+ cs::Database database (config.project_id , config.instance_id ,
129+ config.database_id );
124130
125131 // Once the configuration is fully initialized and the database name set,
126132 // print everything out.
@@ -137,18 +143,27 @@ int main(int argc, char* argv[]) {
137143 }
138144 return statements;
139145 }();
140- auto created = admin_client.CreateDatabase (database, additional_statements);
146+ auto create_future =
147+ admin_client.CreateDatabase (database, additional_statements);
141148 std::cout << " # Waiting for database creation to complete " << std::flush;
142149 for (;;) {
143- auto status = created .wait_for (std::chrono::seconds (1 ));
150+ auto status = create_future .wait_for (std::chrono::seconds (1 ));
144151 if (status == std::future_status::ready) break ;
145152 std::cout << ' .' << std::flush;
146153 }
147154 std::cout << " DONE\n " ;
148- auto db = created.get ();
155+
156+ bool database_created = true ;
157+ auto db = create_future.get ();
149158 if (!db) {
150- std::cerr << " Error creating database: " << db.status () << " \n " ;
151- return 1 ;
159+ if (user_specified_database &&
160+ db.status ().code () == google::cloud::StatusCode::kAlreadyExists ) {
161+ std::cout << " # Re-using existing database\n " ;
162+ database_created = false ;
163+ } else {
164+ std::cerr << " Error creating database: " << db.status () << " \n " ;
165+ return 1 ;
166+ }
152167 }
153168
154169 std::cout << " ClientCount,ThreadCount,UsingStub"
@@ -158,21 +173,32 @@ int main(int argc, char* argv[]) {
158173 int exit_status = EXIT_SUCCESS;
159174
160175 auto experiment = e->second (generator);
161- auto status = experiment->SetUp (config, database);
162- if (!status.ok ()) {
163- std::cout << " # Skipping experiment, SetUp() failed: " << status << " \n " ;
164- exit_status = EXIT_FAILURE;
165- } else {
166- status = experiment->Run (config, database);
167- if (!status.ok ()) exit_status = EXIT_FAILURE;
168- (void )experiment->TearDown (config, database);
176+ Status setup_status;
177+ if (database_created) {
178+ setup_status = experiment->SetUp (config, database);
179+ if (!setup_status.ok ()) {
180+ std::cout << " # Skipping experiment, SetUp() failed: " << setup_status
181+ << " \n " ;
182+ exit_status = EXIT_FAILURE;
183+ }
184+ }
185+ if (setup_status.ok ()) {
186+ auto run_status = experiment->Run (config, database);
187+ if (!run_status.ok ()) exit_status = EXIT_FAILURE;
188+ if (database_created) {
189+ (void )experiment->TearDown (config, database);
190+ }
169191 }
170192
171- auto drop = admin_client.DropDatabase (database);
172- if (!drop.ok ()) {
173- std::cerr << " # Error dropping database: " << drop << " \n " ;
193+ if (!user_specified_database) {
194+ auto drop = admin_client.DropDatabase (database);
195+ if (!drop.ok ()) {
196+ std::cerr << " # Error dropping database: " << drop << " \n " ;
197+ }
174198 }
175- std::cout << " # Experiment finished, database dropped\n " ;
199+ std::cout << " # Experiment finished, "
200+ << (user_specified_database ? " user-specified database kept\n "
201+ : " database dropped\n " );
176202 return exit_status;
177203}
178204
@@ -1457,7 +1483,10 @@ class RunAllExperiment : public Experiment {
14571483 : generator_(generator) {}
14581484
14591485 std::string AdditionalDdlStatement () override { return {}; }
1460- Status SetUp (Config const &, cs::Database const &) override { return {}; }
1486+ Status SetUp (Config const &, cs::Database const &) override {
1487+ setup_called_ = true ;
1488+ return {};
1489+ }
14611490 Status TearDown (Config const &, cs::Database const &) override { return {}; }
14621491
14631492 Status Run (Config const & cfg, cs::Database const & database) override {
@@ -1482,11 +1511,14 @@ class RunAllExperiment : public Experiment {
14821511
14831512 std::cout << " # Smoke test for experiment\n " ;
14841513 std::cout << config << " \n " << std::flush;
1485- auto status = experiment->SetUp (config, database);
1486- if (!status.ok ()) {
1487- std::cout << " # ERROR in SetUp: " << status << " \n " ;
1488- last_error = status;
1489- continue ;
1514+ if (setup_called_) {
1515+ // Only call SetUp() on each experiment if our own SetUp() was called.
1516+ auto status = experiment->SetUp (config, database);
1517+ if (!status.ok ()) {
1518+ std::cout << " # ERROR in SetUp: " << status << " \n " ;
1519+ last_error = status;
1520+ continue ;
1521+ }
14901522 }
14911523 config.use_only_clients = true ;
14921524 config.use_only_stubs = false ;
@@ -1501,6 +1533,7 @@ class RunAllExperiment : public Experiment {
15011533 }
15021534
15031535 private:
1536+ bool setup_called_ = false ;
15041537 std::mutex mu_;
15051538 google::cloud::internal::DefaultPRNG generator_;
15061539};
0 commit comments