| // We fetch all leafs of the revision tree, and sort them based on tree length |
| // and whether they were deleted, undeleted documents with the longest revision |
| // tree (most edits) win |
| // The final sort algorithm is slightly documented in a sidebar here: |
| // http://guide.couchdb.org/draft/conflicts.html |
| function winningRev(metadata) { |
| var winningId; |
| var winningPos; |
| var winningDeleted; |
| var toVisit = metadata.rev_tree.slice(); |
| var node; |
| while ((node = toVisit.pop())) { |
| var tree = node.ids; |
| var branches = tree[2]; |
| var pos = node.pos; |
| if (branches.length) { // non-leaf |
| for (var i = 0, len = branches.length; i < len; i++) { |
| toVisit.push({pos: pos + 1, ids: branches[i]}); |
| } |
| continue; |
| } |
| var deleted = !!tree[1].deleted; |
| var id = tree[0]; |
| // sort by deleted, then pos, then id |
| if (!winningId || (winningDeleted !== deleted ? winningDeleted : |
| winningPos !== pos ? winningPos < pos : winningId < id)) { |
| winningId = id; |
| winningPos = pos; |
| winningDeleted = deleted; |
| } |
| } |
| |
| return winningPos + '-' + winningId; |
| } |
| |
| export default winningRev; |