@@ -1211,7 +1211,15 @@ func (db *DatabaseCollectionWithUser) Put(ctx context.Context, docid string, bod
1211
1211
return newRevID , doc , err
1212
1212
}
1213
1213
1214
- func (db * DatabaseCollectionWithUser ) PutExistingCurrentVersion (ctx context.Context , newDoc * Document , newDocHLV * HybridLogicalVector , existingDoc * sgbucket.BucketDocument , revTreeHistory []string , revTreeISGRProperty bool ) (doc * Document , cv * Version , newRevID string , err error ) {
1214
+ // PutExistingCurrentVersion:
1215
+ // - newDoc: new incoming doc
1216
+ // - newDocHLV: new incoming doc's HLV
1217
+ // - existsingDoc: existing doc in bucket (if present)
1218
+ // - revTreeHistory: list of revID's from the incoming docs history (including docs current rev).
1219
+ // - alignRevTrees: if this is true then we will align the new write with the incoming docs rev tree. If this is
1220
+ // false and len(revTreeHistory) > 0 then this meaans the lcoal version of this doc is legacy doc so this parameter
1221
+ // will be used to check for conflicts.
1222
+ func (db * DatabaseCollectionWithUser ) PutExistingCurrentVersion (ctx context.Context , newDoc * Document , newDocHLV * HybridLogicalVector , existingDoc * sgbucket.BucketDocument , revTreeHistory []string , alignRevTrees bool ) (doc * Document , cv * Version , newRevID string , err error ) {
1215
1223
var matchRev string
1216
1224
if existingDoc != nil {
1217
1225
doc , unmarshalErr := db .unmarshalDocumentWithXattrs (ctx , newDoc .ID , existingDoc .Body , existingDoc .Xattrs , existingDoc .Cas , DocUnmarshalRev )
@@ -1265,7 +1273,7 @@ func (db *DatabaseCollectionWithUser) PutExistingCurrentVersion(ctx context.Cont
1265
1273
// if incoming rev tree list is from a legacy pre upgraded doc, we should have new revID generation based
1266
1274
// off the previous current rev +1. If we have rev tree list filled from ISGR's rev tree property then we
1267
1275
// should use the current rev of inc
1268
- if ! revTreeISGRProperty {
1276
+ if ! alignRevTrees {
1269
1277
newGeneration = prevGeneration + 1
1270
1278
} else {
1271
1279
newGeneration = prevGeneration
@@ -1283,7 +1291,7 @@ func (db *DatabaseCollectionWithUser) PutExistingCurrentVersion(ctx context.Cont
1283
1291
if addNewerVersionsErr != nil {
1284
1292
return nil , nil , false , nil , addNewerVersionsErr
1285
1293
}
1286
- if revTreeISGRProperty {
1294
+ if alignRevTrees {
1287
1295
err = doc .alignRevTreeHistory (ctx , newDoc , revTreeHistory )
1288
1296
if err != nil {
1289
1297
return nil , nil , false , nil , err
@@ -1302,7 +1310,7 @@ func (db *DatabaseCollectionWithUser) PutExistingCurrentVersion(ctx context.Cont
1302
1310
}
1303
1311
// the new document has a dominating hlv, so we can ignore any legacy rev revtree information on the incoming document
1304
1312
revTreeConflictChecked = true
1305
- if ! revTreeISGRProperty {
1313
+ if ! alignRevTrees {
1306
1314
previousRevTreeID = doc .CurrentRev
1307
1315
} else {
1308
1316
// align rev tree here for ISGR replications
@@ -1313,14 +1321,14 @@ func (db *DatabaseCollectionWithUser) PutExistingCurrentVersion(ctx context.Cont
1313
1321
}
1314
1322
} else {
1315
1323
// if the legacy rev list is from ISGR property, we should not do a conflict check
1316
- if len (revTreeHistory ) > 0 && ! revTreeISGRProperty {
1324
+ if len (revTreeHistory ) > 0 && ! alignRevTrees {
1317
1325
// conflict check on rev tree history, if there is a rev in rev tree history we have the parent of locally we are not in conflict
1318
1326
parent , currentRevIndex , err = db .revTreeConflictCheck (ctx , revTreeHistory , doc , newDoc .Deleted )
1319
1327
if err != nil {
1320
1328
base .InfofCtx (ctx , base .KeyCRUD , "conflict detected between the two HLV's for doc %s, incoming version %s, local version %s, and conflict found in rev tree history" , base .UD (doc .ID ), newDocHLV .GetCurrentVersionString (), doc .HLV .GetCurrentVersionString ())
1321
1329
return nil , nil , false , nil , err
1322
1330
}
1323
- err = doc .addNewerRevisionsToHistory (newDoc , currentRevIndex , parent , revTreeHistory )
1331
+ _ , err = doc .addNewerRevisionsToRevTreeHistory (newDoc , currentRevIndex , parent , revTreeHistory )
1324
1332
if err != nil {
1325
1333
return nil , nil , false , nil , err
1326
1334
}
@@ -1342,13 +1350,15 @@ func (db *DatabaseCollectionWithUser) PutExistingCurrentVersion(ctx context.Cont
1342
1350
}
1343
1351
// rev tree conflict check if we have rev tree history to check against + finds current rev index to allow us
1344
1352
// to add any new revision to rev tree below.
1345
- // Only check for rev tree conflicts if we haven't already checked above
1346
- if ! revTreeConflictChecked && len (revTreeHistory ) > 0 && ! revTreeISGRProperty {
1353
+ // Only check for rev tree conflicts if we haven't already checked above AND if alignRevTrees is false given
1354
+ // alignRevTrees can only be true for non legacy rev writes meaning when this is true we should be doing our
1355
+ // conflict checking with incoming HLV
1356
+ if ! revTreeConflictChecked && len (revTreeHistory ) > 0 && ! alignRevTrees {
1347
1357
parent , currentRevIndex , err = db .revTreeConflictCheck (ctx , revTreeHistory , doc , newDoc .Deleted )
1348
1358
if err != nil {
1349
1359
return nil , nil , false , nil , err
1350
1360
}
1351
- err = doc .addNewerRevisionsToHistory (newDoc , currentRevIndex , parent , revTreeHistory )
1361
+ _ , err = doc .addNewerRevisionsToRevTreeHistory (newDoc , currentRevIndex , parent , revTreeHistory )
1352
1362
if err != nil {
1353
1363
return nil , nil , false , nil , err
1354
1364
}
@@ -1362,7 +1372,7 @@ func (db *DatabaseCollectionWithUser) PutExistingCurrentVersion(ctx context.Cont
1362
1372
1363
1373
// generate rev id for new arriving doc
1364
1374
var newRev string
1365
- if ! revTreeISGRProperty {
1375
+ if ! alignRevTrees {
1366
1376
// create a new revID for incoming write
1367
1377
strippedBody , _ := stripInternalProperties (newDoc ._body )
1368
1378
encoding , err := base .JSONMarshalCanonical (strippedBody )
@@ -3366,6 +3376,9 @@ func (db *DatabaseCollectionWithUser) CheckProposedVersion(ctx context.Context,
3366
3376
}
3367
3377
}
3368
3378
3379
+ // alignRevTreeHistory will take incoming rev tree list and add any newer revisions to the local document. If there is
3380
+ // history between the incoming rev tree and local rev tree differs then the local docs rev tree will be overwritten to
3381
+ // the incoming rev tree.
3369
3382
func (doc * Document ) alignRevTreeHistory (ctx context.Context , newDoc * Document , revTreeHistory []string ) error {
3370
3383
currentRevIndex := len (revTreeHistory )
3371
3384
parent := ""
@@ -3381,30 +3394,36 @@ func (doc *Document) alignRevTreeHistory(ctx context.Context, newDoc *Document,
3381
3394
base .DebugfCtx (ctx , base .KeyCRUD , "incoming rev tree history has different history than local doc %s, aligning local doc history with incoming rev tree history" , base .UD (doc .ID ))
3382
3395
// clean local history and make way for incoming history to replace it
3383
3396
doc .History = make (RevTree )
3397
+ // reset current rev index and parent given we are building a new rev tree now
3398
+ currentRevIndex = len (revTreeHistory )
3399
+ parent = ""
3384
3400
}
3385
3401
3386
- err := doc .addNewerRevisionsToHistory (newDoc , currentRevIndex , parent , revTreeHistory )
3402
+ newRev , err := doc .addNewerRevisionsToRevTreeHistory (newDoc , currentRevIndex , parent , revTreeHistory )
3387
3403
if err != nil {
3388
3404
return err
3389
3405
}
3406
+ doc .CurrentRev = newRev
3390
3407
return nil
3391
3408
}
3392
3409
3393
- func (doc * Document ) addNewerRevisionsToHistory (newDoc * Document , currentRevIndex int , parent string , docHistory []string ) error {
3410
+ // addNewerRevisionsToRevTreeHistory will add any newer rev tree id's to the local document history
3411
+ func (doc * Document ) addNewerRevisionsToRevTreeHistory (newDoc * Document , currentRevIndex int , parent string , docHistory []string ) (string , error ) {
3412
+ // currentRevIndex here is the index of the incoming rev tree list to start from.
3394
3413
for i := currentRevIndex - 1 ; i >= 0 ; i -- {
3395
3414
err := doc .History .addRevision (newDoc .ID ,
3396
3415
RevInfo {
3397
3416
ID : docHistory [i ],
3398
- Parent : parent ,
3417
+ Parent : parent , // set the parent of this revision to the element of docHistory from the last iteration
3399
3418
Deleted : i == 0 && newDoc .Deleted })
3400
3419
3401
3420
if err != nil {
3402
- return err
3421
+ return "" , err
3403
3422
}
3404
3423
parent = docHistory [i ]
3405
3424
}
3406
- doc . CurrentRev = parent
3407
- return nil
3425
+ // return last element added from docHistory, this will be the doc's new current rev for writes that are aligning rev tree
3426
+ return parent , nil
3408
3427
}
3409
3428
3410
3429
const (
0 commit comments