@@ -1282,7 +1282,7 @@ func (db *DatabaseCollectionWithUser) Put(ctx context.Context, docid string, bod
12821282// - NewDocHLV: new incoming doc's HLV
12831283// - ExistingDoc: existing doc in bucket (if present)
12841284// - RevTreeHistory: list of revID's from the incoming docs history (including docs current rev).
1285- // - AlignRevTrees : if this is true then we will align the new write with the incoming docs rev tree. If this is
1285+ // - ISGRWrite : if this is true then we will align the new write with the incoming docs rev tree. If this is
12861286// false and len(RevTreeHistory) > 0 then this means the local version of this doc does not have an HLV so this parameter
12871287// will be used to check for conflicts.
12881288func (db * DatabaseCollectionWithUser ) PutExistingCurrentVersion (ctx context.Context , opts PutDocOptions ) (doc * Document , cv * Version , newRevID string , err error ) {
@@ -1339,7 +1339,7 @@ func (db *DatabaseCollectionWithUser) PutExistingCurrentVersion(ctx context.Cont
13391339 // if incoming rev tree list is from a legacy pre upgraded doc, we should have new revID generation based
13401340 // off the previous current rev +1. If we have rev tree list filled from ISGR's rev tree property then we
13411341 // should use the current rev of inc
1342- if ! opts .AlignRevTrees {
1342+ if ! opts .ISGRWrite {
13431343 newGeneration = prevGeneration + 1
13441344 } else {
13451345 newGeneration = prevGeneration
@@ -1373,7 +1373,7 @@ func (db *DatabaseCollectionWithUser) PutExistingCurrentVersion(ctx context.Cont
13731373 doc .HLV = NewHybridLogicalVector ()
13741374 }
13751375 doc .HLV .UpdateWithIncomingHLV (opts .NewDocHLV )
1376- if opts .AlignRevTrees {
1376+ if opts .ISGRWrite {
13771377 err := doc .alignRevTreeHistoryForHLVWrite (ctx , db , opts .NewDoc , opts .RevTreeHistory , opts .ForceAllowConflictingTombstone )
13781378 if err != nil {
13791379 return nil , nil , false , nil , err
@@ -1393,7 +1393,7 @@ func (db *DatabaseCollectionWithUser) PutExistingCurrentVersion(ctx context.Cont
13931393 // update hlv for all newer incoming source version pairs
13941394 doc .HLV .UpdateWithIncomingHLV (opts .NewDocHLV )
13951395 // the new document has a dominating hlv, so we can just update local revtree with incoming revtree
1396- if ! opts .AlignRevTrees {
1396+ if ! opts .ISGRWrite {
13971397 previousRevTreeID = doc .GetRevTreeID ()
13981398 } else {
13991399 // align rev tree here for ISGR replications
@@ -1404,7 +1404,7 @@ func (db *DatabaseCollectionWithUser) PutExistingCurrentVersion(ctx context.Cont
14041404 }
14051405 case HLVConflict :
14061406 // if we have been supplied a rev tree from cbl, perform conflict check on rev tree history
1407- if len (opts .RevTreeHistory ) > 0 && ! opts .AlignRevTrees {
1407+ if len (opts .RevTreeHistory ) > 0 && ! opts .ISGRWrite {
14081408 parent , currentRevIndex , err := db .revTreeConflictCheck (ctx , opts .RevTreeHistory , doc , opts .NewDoc .Deleted )
14091409 if err != nil {
14101410 base .DebugfCtx (ctx , base .KeyCRUD , "conflict detected between the two HLV's for doc %s, and conflict found in rev tree history" , base .UD (doc .ID ))
@@ -1448,7 +1448,7 @@ func (db *DatabaseCollectionWithUser) PutExistingCurrentVersion(ctx context.Cont
14481448 // if we have revtree history available and we are communicating with CBL, we must update the rev tree
14491449 // to include the new to us revisions from the incoming rev tree history skipping history check given conflict
14501450 // check is done at this point.
1451- if len (opts .RevTreeHistory ) > 0 && ! opts .AlignRevTrees && ! revTreeAlignedForCBL {
1451+ if len (opts .RevTreeHistory ) > 0 && ! opts .ISGRWrite && ! revTreeAlignedForCBL {
14521452 addNewRevErr := doc .alignRevTreeHistoryForHLVWrite (ctx , db , opts .NewDoc , opts .RevTreeHistory , true )
14531453 if addNewRevErr != nil {
14541454 return nil , nil , false , nil , addNewRevErr
@@ -1463,7 +1463,7 @@ func (db *DatabaseCollectionWithUser) PutExistingCurrentVersion(ctx context.Cont
14631463
14641464 // generate rev id for new arriving doc
14651465 var newRev string
1466- if ! opts .AlignRevTrees {
1466+ if ! opts .ISGRWrite {
14671467 // create a new revID for incoming write
14681468 strippedBody , _ := StripInternalProperties (opts .NewDoc ._body )
14691469 encoding , err := base .JSONMarshalCanonical (strippedBody )
@@ -1521,7 +1521,7 @@ type PutDocOptions struct {
15211521 ConflictResolver * ConflictResolver // If provided, will be used to resolve conflicts if NoConflicts is false and a conflict is detected
15221522 ExistingDoc * sgbucket.BucketDocument // optional, prevents fetching the document from the bucket
15231523 NewDocHLV * HybridLogicalVector // incoming doc HLV if known
1524- AlignRevTrees bool // if true, the rev tree history is from ISGR only revTree replication message property (> v4 protocol only) and will use this to align rev trees
1524+ ISGRWrite bool // if true, the write is from ISGR and will use rev tree history to align rev trees
15251525}
15261526
15271527// PutExistingRevWithConflictResolution adds an existing revision to a document along with its history.
@@ -3455,38 +3455,42 @@ func (c *DatabaseCollection) checkForUpgrade(ctx context.Context, key string, un
34553455func legacyRevToHybridLogicalVector (docID , revID string ) (hlv * HybridLogicalVector , err error ) {
34563456 version , err := LegacyRevToRevTreeEncodedVersion (revID )
34573457 if err != nil {
3458- return nil , fmt . Errorf ("error parsing legacy revID %q to version for doc %s: %v" , revID , base .UD (docID ), err )
3458+ return nil , base . RedactErrorf ("error parsing legacy revID %q to version for doc %s: %v" , revID , base .UD (docID ), err )
34593459 }
34603460 hlv = NewHybridLogicalVector ()
34613461 err = hlv .AddVersion (version )
34623462 if err != nil {
3463- return nil , fmt . Errorf ("error adding version to hlv for doc %s: %v" , base .UD (docID ), err )
3463+ return nil , base . RedactErrorf ("error adding version to hlv for doc %s: %v" , base .UD (docID ), err )
34643464 }
34653465 return hlv , nil
34663466}
34673467
34683468// parseIncomingChange will parse incoming change version. If the change is legacy rev it will convert the revID to a CV
3469- // otherwise it will parse the version string.
3470- func parseIncomingChange (docid , rev string ) (cvValue Version , err error ) {
3469+ // otherwise it will parse the version string and will mark change as legacy rev .
3470+ func parseIncomingChange (docid , rev string ) (cvValue Version , legacyRev bool , err error ) {
34713471 if base .IsRevTreeID (rev ) {
34723472 cvValue , err = LegacyRevToRevTreeEncodedVersion (rev )
34733473 if err != nil {
3474- return Version {}, base .RedactErrorf ("error parsing legacy revID %q to version for doc %s: %v" , base .UD (rev ), base .UD (docid ), err )
3474+ return Version {}, legacyRev , base .RedactErrorf ("error parsing legacy revID %q to version for doc %s: %v" , base .UD (rev ), base .UD (docid ), err )
34753475 }
3476+ legacyRev = true
34763477 } else {
34773478 cvValue , err = ParseVersion (rev )
34783479 if err != nil {
3479- return Version {}, base .RedactErrorf ("error parsing change version for doc %s: %v" , base .UD (docid ), err )
3480+ return Version {}, legacyRev , base .RedactErrorf ("error parsing change version for doc %s: %v" , base .UD (docid ), err )
34803481 }
34813482 }
3482- return cvValue , nil
3483+ return cvValue , legacyRev , nil
34833484}
34843485
34853486func (db * DatabaseCollectionWithUser ) CheckChangeVersion (ctx context.Context , docid , rev string ) (missing , possible []string ) {
34863487 if strings .HasPrefix (docid , "_design/" ) && db .user != nil {
34873488 return // Users can't upload design docs, so ignore them
34883489 }
34893490
3491+ localIsLegacy := false
3492+ changeIsLegacy := false
3493+
34903494 syncData , hlv , err := db .GetDocSyncDataNoImport (ctx , docid , DocUnmarshalSync )
34913495 if err != nil {
34923496 if ! base .IsDocNotFoundError (err ) && ! base .IsXattrNotFoundError (err ) {
@@ -3503,10 +3507,15 @@ func (db *DatabaseCollectionWithUser) CheckChangeVersion(ctx context.Context, do
35033507 return
35043508 }
35053509 }
3510+ if hlv .HasRevEncodedCV () {
3511+ // if local hlv has revID encoded CV given to it mark it as legacy change for the purposes of sending back known revs
3512+ // in legacy format. This will ensure delta sync works correctly replicating legacy revs
3513+ localIsLegacy = true
3514+ }
35063515 // parse in coming version, if it's not known to local doc hlv then it is marked as missing, if it is and is a newer version
35073516 // then it is also marked as missing
35083517 var cvValue Version
3509- cvValue , err = parseIncomingChange (docid , rev )
3518+ cvValue , changeIsLegacy , err = parseIncomingChange (docid , rev )
35103519 if err != nil {
35113520 base .WarnfCtx (ctx , "%s" , err )
35123521 missing = append (missing , rev )
@@ -3520,8 +3529,11 @@ func (db *DatabaseCollectionWithUser) CheckChangeVersion(ctx context.Context, do
35203529
35213530 // return the local current rev as known rev, this will mean if you have rev 1,2,3 and remote has rev 1,2,3,4,5 then
35223531 // remote should only send rev 4,5 in rev tree property on the subsequent rev message for this document, we also need to
3523- // send cv as first element for delta sync purposes
3524- possible = append (possible , hlv .GetCurrentVersionString ())
3532+ // send cv as first element for delta sync purposes. Only send CV if this is not legacy rev change
3533+ if ! localIsLegacy && ! changeIsLegacy {
3534+ // we should only send CV in response when we are communicating with HLV's both sides of the replication
3535+ possible = append (possible , hlv .GetCurrentVersionString ())
3536+ }
35253537 possible = append (possible , syncData .GetRevTreeID ())
35263538
35273539 missing = append (missing , rev )
0 commit comments