@@ -140,7 +140,12 @@ mongoc_bulkwriteopts_destroy (mongoc_bulkwriteopts_t *self)
140
140
typedef enum { MODEL_OP_INSERT , MODEL_OP_UPDATE , MODEL_OP_DELETE } model_op_t ;
141
141
typedef struct {
142
142
model_op_t op ;
143
- bson_iter_t id_iter ;
143
+ // `id_loc` locates the "_id" field of an insert document.
144
+ struct {
145
+ size_t op_start ; // Offset in `mongoc_bulkwrite_t::ops` to the BSON for the insert op: { "document": ... }
146
+ size_t op_len ; // Length of insert op.
147
+ uint32_t id_offset ; // Offset in the insert op to the "_id" field.
148
+ } id_loc ;
144
149
char * ns ;
145
150
} modeldata_t ;
146
151
@@ -271,19 +276,14 @@ mongoc_bulkwrite_append_insertone (mongoc_bulkwrite_t *self,
271
276
persisted_id_offset += existing_id_offset ;
272
277
}
273
278
274
- BSON_ASSERT (_mongoc_buffer_append (& self -> ops , bson_get_data (& op ), op .len ));
275
-
276
- // Store an iterator to the document's `_id` in the persisted payload:
277
- bson_iter_t persisted_id_iter ;
278
- {
279
- BSON_ASSERT (mcommon_in_range_size_t_unsigned (op .len ));
280
- size_t start = self -> ops .len - (size_t ) op .len ;
281
- BSON_ASSERT (bson_iter_init_from_data_at_offset (
282
- & persisted_id_iter , self -> ops .data + start , (size_t ) op .len , persisted_id_offset , strlen ("_id" )));
283
- }
279
+ size_t op_start = self -> ops .len ; // Save location of `op` to retrieve `_id` later.
280
+ BSON_ASSERT (mcommon_in_range_size_t_unsigned (op .len ));
281
+ BSON_ASSERT (_mongoc_buffer_append (& self -> ops , bson_get_data (& op ), (size_t ) op .len ));
284
282
285
283
self -> n_ops ++ ;
286
- modeldata_t md = {.op = MODEL_OP_INSERT , .id_iter = persisted_id_iter , .ns = bson_strdup (ns )};
284
+ modeldata_t md = {.op = MODEL_OP_INSERT ,
285
+ .id_loc = {.op_start = op_start , .op_len = (size_t ) op .len , .id_offset = persisted_id_offset },
286
+ .ns = bson_strdup (ns )};
287
287
_mongoc_array_append_val (& self -> arrayof_modeldata , md );
288
288
bson_destroy (& op );
289
289
return true;
@@ -1310,7 +1310,8 @@ static bool
1310
1310
_bulkwritereturn_apply_result (mongoc_bulkwritereturn_t * self ,
1311
1311
const bson_t * result ,
1312
1312
size_t ops_doc_offset ,
1313
- const mongoc_array_t * arrayof_modeldata )
1313
+ const mongoc_array_t * arrayof_modeldata ,
1314
+ const mongoc_buffer_t * ops )
1314
1315
{
1315
1316
BSON_ASSERT_PARAM (self );
1316
1317
BSON_ASSERT_PARAM (result );
@@ -1428,7 +1429,10 @@ _bulkwritereturn_apply_result (mongoc_bulkwritereturn_t *self,
1428
1429
break ;
1429
1430
}
1430
1431
case MODEL_OP_INSERT : {
1431
- _bulkwriteresult_set_insertresult (self -> res , & md -> id_iter , models_idx );
1432
+ bson_iter_t id_iter ;
1433
+ BSON_ASSERT (bson_iter_init_from_data_at_offset (
1434
+ & id_iter , ops -> data + md -> id_loc .op_start , md -> id_loc .op_len , md -> id_loc .id_offset , strlen ("_id" )));
1435
+ _bulkwriteresult_set_insertresult (self -> res , & id_iter , models_idx );
1432
1436
break ;
1433
1437
}
1434
1438
default :
@@ -1643,9 +1647,9 @@ mongoc_bulkwrite_execute (mongoc_bulkwrite_t *self, const mongoc_bulkwriteopts_t
1643
1647
bool batch_ok = false;
1644
1648
bson_t cmd_reply = BSON_INITIALIZER ;
1645
1649
mongoc_cursor_t * reply_cursor = NULL ;
1646
- // `ops_byte_len` is the number of documents from `ops` to send in this batch.
1650
+ // `ops_byte_len` is the number of bytes from `ops` to send in this batch.
1647
1651
size_t ops_byte_len = 0 ;
1648
- // `ops_doc_len` is the number of bytes from `ops` to send in this batch.
1652
+ // `ops_doc_len` is the number of documents from `ops` to send in this batch.
1649
1653
size_t ops_doc_len = 0 ;
1650
1654
1651
1655
if (ops_byte_offset == self -> ops .len ) {
@@ -1837,7 +1841,8 @@ mongoc_bulkwrite_execute (mongoc_bulkwrite_t *self, const mongoc_bulkwriteopts_t
1837
1841
// Iterate over cursor results.
1838
1842
const bson_t * result ;
1839
1843
while (mongoc_cursor_next (reply_cursor , & result )) {
1840
- if (!_bulkwritereturn_apply_result (& ret , result , ops_doc_offset , & self -> arrayof_modeldata )) {
1844
+ if (!_bulkwritereturn_apply_result (
1845
+ & ret , result , ops_doc_offset , & self -> arrayof_modeldata , & self -> ops )) {
1841
1846
goto batch_fail ;
1842
1847
}
1843
1848
}
0 commit comments