Conflict winners are chosen dynamically, every time a request for the document arrives. The revision tree is sort of like a git repository: most updates are based on a parent update. In general, you have a tree of changes, but usually it works out to a linear linked list.
Anyway, the winner is the version with the longest revision history. (That is arbitrary but deterministic, so two couches with the same revision trees will pick the same winner.)
couch_doc:to_doc_info_path
does the main job: converting the revision tree into an array of paths from root to leaf. It returns this array sorted, with the longest path first. The diff here will print a log message every time the comparison function is called by lists:sort()
.
The execution path basically goes:
couch_http_db:db_doc_req()
couch_db:open_doc()
couch_db:open_doc_int(Db, Id, [])
(a kind of convenience function)couch_db:get_full_doc_info(Db, Id)
- dig it out of the id index (btree)
- Rerun
couch_db:open_doc_int(Db, FullDocInfo, [])
(this time with feeling) couch_doc:to_doc_info(FullDocInfo)
which basically wrapscouch_doc:to_doc_info_path(FullDocInfo)
- This is where revisions are sorted: longest history first (as long as it is not deleted)
- Pop back up the execution stack to step 4, where the code grabs the first array element--the one with the longest history and that will be the revision and document you get over HTTP