Author: damien Date: Sat Mar 21 12:27:40 2009 New Revision: 756925 URL: http://svn.apache.org/viewvc?rev=756925&view=rev Log: Fix for COUCHDB-300. Old seq were being removed when a conflict. An old bug, but recent changes made it much more likely to happen.
Modified: couchdb/trunk/etc/couchdb/local_dev.ini couchdb/trunk/share/www/script/test/conflicts.js couchdb/trunk/src/couchdb/couch_db_updater.erl Modified: couchdb/trunk/etc/couchdb/local_dev.ini URL: http://svn.apache.org/viewvc/couchdb/trunk/etc/couchdb/local_dev.ini?rev=756925&r1=756924&r2=756925&view=diff ============================================================================== --- couchdb/trunk/etc/couchdb/local_dev.ini (original) +++ couchdb/trunk/etc/couchdb/local_dev.ini Sat Mar 21 12:27:40 2009 @@ -12,7 +12,7 @@ ;bind_address = 127.0.0.1 [log] -; level = debug +level = error [update_notification] ;unique notifier name=/full/path/to/exe -with "cmd line arg" Modified: couchdb/trunk/share/www/script/test/conflicts.js URL: http://svn.apache.org/viewvc/couchdb/trunk/share/www/script/test/conflicts.js?rev=756925&r1=756924&r2=756925&view=diff ============================================================================== --- couchdb/trunk/share/www/script/test/conflicts.js (original) +++ couchdb/trunk/share/www/script/test/conflicts.js Sat Mar 21 12:27:40 2009 @@ -41,6 +41,10 @@ } catch (e) { T(e.error == "conflict"); } + + var bySeq = db.allDocsBySeq(); + + T( bySeq.rows.length == 1) // Now clear out the _rev member and save. This indicates this document is // new, not based on an existing revision. Modified: couchdb/trunk/src/couchdb/couch_db_updater.erl URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_db_updater.erl?rev=756925&r1=756924&r2=756925&view=diff ============================================================================== --- couchdb/trunk/src/couchdb/couch_db_updater.erl (original) +++ couchdb/trunk/src/couchdb/couch_db_updater.erl Sat Mar 21 12:27:40 2009 @@ -357,11 +357,12 @@ end, Unflushed), flush_trees(Db, RestUnflushed, [InfoUnflushed#full_doc_info{rev_tree=Flushed} | AccFlushed]). -merge_rev_trees(_MergeConflicts, [], [], AccNewInfos, AccConflicts, AccSeq) -> - {ok, lists:reverse(AccNewInfos), AccConflicts, AccSeq}; +merge_rev_trees(_MergeConflicts, [], [], AccNewInfos, AccRemoveSeqs, AccConflicts, AccSeq) -> + {ok, lists:reverse(AccNewInfos), AccRemoveSeqs, AccConflicts, AccSeq}; merge_rev_trees(MergeConflicts, [NewDocs|RestDocsList], - [OldDocInfo|RestOldInfo], AccNewInfos, AccConflicts, AccSeq) -> - #full_doc_info{id=Id,rev_tree=OldTree,deleted=OldDeleted}=OldDocInfo, + [OldDocInfo|RestOldInfo], AccNewInfos, AccRemoveSeqs, AccConflicts, AccSeq) -> + #full_doc_info{id=Id,rev_tree=OldTree,deleted=OldDeleted,update_seq=OldSeq} + = OldDocInfo, {NewRevTree, NewConflicts} = lists:foldl( fun(#doc{revs={Pos,[Rev|_]}}=NewDoc, {AccTree, AccConflicts2}) -> case couch_key_tree:merge(AccTree, [couch_db:doc_to_tree(NewDoc)]) of @@ -376,12 +377,16 @@ if NewRevTree == OldTree -> % nothing changed merge_rev_trees(MergeConflicts, RestDocsList, RestOldInfo, AccNewInfos, - NewConflicts, AccSeq); + AccRemoveSeqs, NewConflicts, AccSeq); true -> % we have updated the document, give it a new seq # NewInfo = #full_doc_info{id=Id,update_seq=AccSeq+1,rev_tree=NewRevTree}, - merge_rev_trees(MergeConflicts, RestDocsList,RestOldInfo, - [NewInfo|AccNewInfos], NewConflicts, AccSeq+1) + RemoveSeqs = case OldSeq of + 0 -> AccRemoveSeqs; + _ -> [OldSeq | AccRemoveSeqs] + end, + merge_rev_trees(MergeConflicts, RestDocsList, RestOldInfo, + [NewInfo|AccNewInfos], RemoveSeqs, NewConflicts, AccSeq+1) end. new_index_entries([], AccById, AccBySeq) -> @@ -428,15 +433,12 @@ Ids, OldDocLookups), % Merge the new docs into the revision trees. - {ok, NewDocInfos0, Conflicts, NewSeq} = merge_rev_trees( + {ok, NewDocInfos0, RemoveSeqs, Conflicts, NewSeq} = merge_rev_trees( lists:member(merge_conflicts, Options), - DocsList2, OldDocInfos, [], [], LastSeq), + DocsList2, OldDocInfos, [], [], [], LastSeq), NewDocInfos = stem_full_doc_infos(Db, NewDocInfos0), - RemoveSeqs = - [OldSeq || {ok, #full_doc_info{update_seq=OldSeq}} <- OldDocLookups], - % All documents are now ready to write. {ok, LocalConflicts, Db2} = update_local_docs(Db, NonRepDocs),