CBL-8390: Implement Parse and Compare Non-numeric checkpoint resolution#2496
CBL-8390: Implement Parse and Compare Non-numeric checkpoint resolution#2496jianminzhao wants to merge 2 commits into
Conversation
|
This is a release branch and commits are restricted. Please confirm this PR is one of the following:
|
|
Auto merged from master branch |
|
Code Coverage Results:
|
|
The ticket is assigned to release/3.4 |
There was a problem hiding this comment.
Pull request overview
This PR introduces support for parsing and ordering Sync Gateway compound (non-numeric) remote sequence IDs so checkpoint mismatch resolution can roll back/ignore correctly instead of resetting replication when sequences aren’t plain integers.
Changes:
- Add
ParsedSequenceIDtype withparse()andbefore()ordering rules aligned with Sync Gateway’s checkpoint comparison semantics. - Teach checkpoint validation to compare parsed remote sequences (including compound formats) and only roll back when the server checkpoint is actually earlier.
- Add a comprehensive unit test suite for parsing/classification/comparison rules, and wire it into the CMake test target.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| Replicator/tests/ParsedSequenceIDTest.cc | New unit tests covering parsing/classification and cross-format ordering semantics. |
| Replicator/RemoteSequence.hh | Adds conversion helper to parse remote sequence values into ParsedSequenceID. |
| Replicator/ParsedSequenceID.hh | New header implementing parsing + ordering rules for compound sequence IDs. |
| Replicator/Checkpoint.cc | Updates checkpoint mismatch logic to compare parsed sequences instead of only numeric sequences. |
| LiteCore/tests/CMakeLists.txt | Adds the new test file to the LiteCore test executable. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| /** Convert this RemoteSequence to a ParsedSequenceID. Returns false if unparseable. */ | ||
| [[nodiscard]] bool toParsedSequenceID(ParsedSequenceID& out) const { | ||
| if ( !*this ) return false; | ||
| if ( isInt() ) { | ||
| out = {intValue(), 0, 0}; | ||
| return true; | ||
| } | ||
| return ParsedSequenceID::parse(std::string(sliceValue()), out); | ||
| } |
| #include "ParsedSequenceID.hh" | ||
| #include "c4Test.hh" | ||
|
|
| ParsedSequenceID localParsed, remoteParsed; | ||
| bool localParseable = _remote.toParsedSequenceID(localParsed); | ||
| bool remoteParseable = remoteSequences._remote.toParsedSequenceID(remoteParsed); | ||
| if ( localParseable && remoteParseable ) { | ||
| if ( remoteParsed.before(localParsed) ) { | ||
| LogTo(SyncLog, "Rolling back to earlier remote sequence from server, some redundant changes may be " | ||
| "proposed..."); | ||
| _remote = remoteSequences._remote; | ||
| match = false; | ||
| } else { | ||
| LogTo(SyncLog, "Ignoring remote sequence on server since client side is older, some redundant " | ||
| "changes may be proposed..."); | ||
| LogTo(SyncLog, "Ignoring remote sequence on server since client side is older or equal, some " | ||
| "redundant changes may be proposed..."); | ||
| } | ||
| } else { | ||
| Warn("Non-numeric remote sequence detected, resetting replication back to start. Redundant changes " | ||
| "will be proposed..."); | ||
| Warn("Unparseable remote sequence: locally-saved remote seq '%s' is %s, " | ||
| "server-side remote seq '%s' is %s. Resetting replication.", | ||
| _remote.toJSONString().c_str(), localParseable ? "parseable" : "UNPARSEABLE", | ||
| remoteSequences._remote.toJSONString().c_str(), remoteParseable ? "parseable" : "UNPARSEABLE"); | ||
| _remote = {}; | ||
| match = false; |
| #pragma once | ||
| #include "StringUtil.hh" | ||
| #include "slice_stream.hh" | ||
| #include <cstdint> | ||
| #include <string> | ||
|
|
No description provided.