@@ -111,11 +111,11 @@ struct Options {
111111 };
112112};
113113
114- enum OpType { kOpWrite , kOpRead0 , kOpRead1 , kOpRead2 };
114+ enum OpType { kOpWrite , kOpInsert , kOpRead0 , kOpRead1 , kOpRead2 };
115115struct IterationResult {
116116 OpType op;
117- std::uint64_t object_size;
118- std::uint64_t app_buffer_size;
117+ std::int64_t object_size;
118+ std::int64_t app_buffer_size;
119119 std::uint64_t lib_buffer_size;
120120 bool crc_enabled;
121121 bool md5_enabled;
@@ -254,6 +254,8 @@ char const* ToString(OpType type) {
254254 return " READ[2]" ;
255255 case kOpWrite :
256256 return " WRITE" ;
257+ case kOpInsert :
258+ return " INSERT" ;
257259 }
258260 return nullptr ; // silence g++ error.
259261}
@@ -301,17 +303,18 @@ TestResults RunThread(Options const& options, std::string const& bucket_name) {
301303 gcs::Client grpc_client (rest_client);
302304#endif // GOOGLE_CLOUD_CPP_STORAGE_HAVE_GRP
303305
304- std::uniform_int_distribution<std::uint64_t > size_generator (
306+ std::uniform_int_distribution<std::int64_t > size_generator (
305307 options.minimum_object_size , options.maximum_object_size );
306- std::uniform_int_distribution<std::uint64_t > write_size_generator (
308+ std::uniform_int_distribution<std::int64_t > write_size_generator (
307309 options.minimum_write_size / options.write_quantum ,
308310 options.maximum_write_size / options.write_quantum );
309- std::uniform_int_distribution<std::uint64_t > read_size_generator (
311+ std::uniform_int_distribution<std::int64_t > read_size_generator (
310312 options.minimum_read_size / options.read_quantum ,
311313 options.maximum_read_size / options.read_quantum );
312314
313315 std::bernoulli_distribution crc_generator;
314316 std::bernoulli_distribution md5_generator;
317+ std::bernoulli_distribution use_insert;
315318
316319 std::uniform_int_distribution<std::size_t > api_generator (
317320 0 , options.enabled_apis .size () - 1 );
@@ -363,25 +366,44 @@ TestResults RunThread(Options const& options, std::string const& bucket_name) {
363366 break ;
364367 }
365368
366- timer.Start ();
367- auto writer = client->WriteObject (
368- bucket_name, object_name, gcs::DisableCrc32cChecksum (!enable_crc),
369- gcs::DisableMD5Hash (!enable_md5), xml_write_selector);
370- for (std::size_t offset = 0 ; offset < object_size; offset += write_size) {
371- auto len = write_size;
372- if (offset + len > object_size) {
373- len = object_size - offset;
369+ auto perform_upload = [&options, &contents, client, bucket_name,
370+ object_name, object_size, write_size, enable_crc,
371+ enable_md5, xml_write_selector](bool prefer_insert) {
372+ // When the object is relatively small using `ObjectInsert` might be more
373+ // efficient. Randomly select about 1/2 of the small writes to use
374+ // ObjectInsert()
375+ if (object_size < options.maximum_write_size && prefer_insert) {
376+ std::string data = contents.substr (0 , object_size);
377+ auto object_metadata = client->InsertObject (
378+ bucket_name, object_name, std::move (data),
379+ gcs::DisableCrc32cChecksum (!enable_crc),
380+ gcs::DisableMD5Hash (!enable_md5), xml_write_selector);
381+ return std::make_pair (kOpInsert , std::move (object_metadata));
374382 }
375- writer.write (contents.data (), len);
376- }
377- writer.Close ();
383+ auto writer = client->WriteObject (
384+ bucket_name, object_name, gcs::DisableCrc32cChecksum (!enable_crc),
385+ gcs::DisableMD5Hash (!enable_md5), xml_write_selector);
386+ for (std::int64_t offset = 0 ; offset < object_size;
387+ offset += write_size) {
388+ auto len = write_size;
389+ if (offset + len > object_size) {
390+ len = object_size - offset;
391+ }
392+ writer.write (contents.data (), len);
393+ }
394+ writer.Close ();
395+ return std::make_pair (kOpWrite , writer.metadata ());
396+ };
397+
398+ timer.Start ();
399+ auto upload_result = perform_upload (use_insert (generator));
378400 timer.Stop ();
379401
380- auto object_metadata = writer. metadata ( );
381- results.emplace_back (
382- IterationResult{ kOpWrite , object_size, write_size, upload_buffer_size,
383- enable_crc, enable_md5, api, timer.elapsed_time (),
384- timer. cpu_time (), object_metadata.status ().code ()});
402+ auto object_metadata = std::move (upload_result. second );
403+ results.emplace_back (IterationResult{
404+ upload_result. first , object_size, write_size, upload_buffer_size,
405+ enable_crc, enable_md5, api, timer.elapsed_time (), timer. cpu_time (),
406+ object_metadata.status ().code ()});
385407
386408 if (!object_metadata) {
387409 if (options.thread_count == 1 ) {
0 commit comments