Skip to content

Commit

Permalink
CBL-6636: Rev message contains the full history in the revID field
Browse files Browse the repository at this point in the history
For the rev property of the rev message, We use the revID of the current version for Version Vector revisions and the rest of of the versions will be in the history property.
  • Loading branch information
jianminzhao committed Jan 15, 2025
1 parent fa290aa commit 9845c7d
Showing 1 changed file with 28 additions and 5 deletions.
33 changes: 28 additions & 5 deletions Replicator/Pusher+Revs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "HTTPTypes.hh"
#include "Increment.hh"
#include "StringUtil.hh"
#include "VersionVector.hh"
#include "fleece/Mutable.hh"
#include <cinttypes>

Expand Down Expand Up @@ -106,21 +107,43 @@ namespace litecore::repl {
}
}

auto fullRevID = alloc_slice(_db->convertVersionToAbsolute(request->revID));
auto fullRevID = alloc_slice(_db->convertVersionToAbsolute(request->revID));
alloc_slice currentRevID = fullRevID;
constexpr slice vvSeparator = ",;"_sl;
if ( currentRevID.findAnyByteOf(vvSeparator) ) {
try {
VersionVector vv = VersionVector::fromASCII(currentRevID);
currentRevID = vv.current().asASCII();
} catch ( ... ) {
// it's not a VV even with comma or semi-colon in it.
throw;
}
}

auto fullReplacementRevID =
replacementRevID ? alloc_slice(_db->convertVersionToAbsolute(replacementRevID)) : nullslice;
alloc_slice currentReplacementRevID = fullReplacementRevID;
if ( currentReplacementRevID && currentReplacementRevID.findAnyByteOf(vvSeparator) ) {
try {
VersionVector vv = VersionVector::fromASCII(currentReplacementRevID);
currentReplacementRevID = vv.current().asASCII();
} catch ( ... ) {
// it's not a VV even with comma or semi-colon in it.
throw;
}
}

// Now send the BLIP message. Normally it's "rev", but if this is an error we make it
// "norev" and include the error code:
MessageBuilder msg(root ? "rev"_sl : "norev"_sl);
assignCollectionToMsg(msg, collectionIndex());
msg.compressed = true;
msg["id"_sl] = request->docID;
if ( fullReplacementRevID ) {
msg["rev"_sl] = fullReplacementRevID;
if ( currentReplacementRevID ) {
msg["rev"_sl] = currentReplacementRevID;
msg["replacedRev"] = fullRevID;
} else
msg["rev"_sl] = fullRevID;
msg["rev"_sl] = currentRevID;
msg["sequence"_sl] = narrow_cast<int64_t>((uint64_t)request->sequence);
if ( root ) {
if ( request->noConflicts ) msg["noconflicts"_sl] = true;
Expand All @@ -129,7 +152,7 @@ namespace litecore::repl {

// Include the document history, but skip the current revision 'cause it's redundant
alloc_slice history = request->historyString(doc);
alloc_slice effectiveRevID = fullReplacementRevID ? fullReplacementRevID : fullRevID;
alloc_slice effectiveRevID = currentReplacementRevID ? currentReplacementRevID : currentRevID;
if ( history.hasPrefix(effectiveRevID) && history.size > effectiveRevID.size )
msg["history"_sl] = history.from(effectiveRevID.size + 1);

Expand Down

0 comments on commit 9845c7d

Please sign in to comment.