summaryrefslogtreecommitdiff
path: root/src/couchdb/couch_db_updater.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/couchdb/couch_db_updater.erl')
-rw-r--r--src/couchdb/couch_db_updater.erl45
1 files changed, 28 insertions, 17 deletions
diff --git a/src/couchdb/couch_db_updater.erl b/src/couchdb/couch_db_updater.erl
index b4faefee..d02464ca 100644
--- a/src/couchdb/couch_db_updater.erl
+++ b/src/couchdb/couch_db_updater.erl
@@ -54,6 +54,10 @@ handle_call({update_docs, DocActions, Options}, _From, Db) ->
throw: conflict ->
{reply, conflict, Db}
end;
+handle_call(full_commit, _From, #db{waiting_delayed_commit=nil}=Db) ->
+ {reply, ok, Db}; % no data waiting, return ok immediately
+handle_call(full_commit, _From, Db) ->
+ {reply, ok, commit_data(Db)}; % commit the data and return ok
handle_call(increment_update_seq, _From, Db) ->
Db2 = commit_data(Db#db{update_seq=Db#db.update_seq+1}),
ok = gen_server:call(Db2#db.main_pid, {db_updated, Db2}),
@@ -185,9 +189,8 @@ handle_cast({compact_done, CompactFilepath}, #db{filepath=Filepath}=Db) ->
{noreply, Db2}
end.
-handle_info(Msg, Db) ->
- ?LOG_ERROR("Bad message received for db ~s: ~p", [Db#db.name, Msg]),
- exit({error, Msg}).
+handle_info(delayed_commit, Db) ->
+ {noreply, commit_data(Db#db{waiting_delayed_commit=nil})}.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
@@ -456,13 +459,8 @@ update_docs_int(Db, DocsList, Options) ->
_ ->
Db4 = refresh_validate_doc_funs(Db3)
end,
-
- case lists:member(delay_commit, Options) of
- true ->
- {ok, Db4};
- false ->
- {ok, commit_data(Db4)}
- end.
+
+ {ok, commit_data(Db4, not lists:member(full_commit, Options))}.
update_local_docs(#db{local_docs_btree=Btree}=Db, Docs) ->
Ids = [Id || #doc{id=Id} <- Docs],
@@ -500,21 +498,34 @@ update_local_docs(#db{local_docs_btree=Btree}=Db, Docs) ->
{ok, Db#db{local_docs_btree = Btree2}}.
+commit_data(Db) ->
+ commit_data(Db, false).
-commit_data(#db{fd=Fd, header=Header} = Db) ->
- Header2 = Header#db_header{
+
+commit_data(#db{fd=Fd, header=Header} = Db, Delay) ->
+ Db2 = Db#db{header = Header#db_header{
update_seq = Db#db.update_seq,
summary_stream_state = couch_stream:get_state(Db#db.summary_stream),
docinfo_by_seq_btree_state = couch_btree:get_state(Db#db.docinfo_by_seq_btree),
fulldocinfo_by_id_btree_state = couch_btree:get_state(Db#db.fulldocinfo_by_id_btree),
local_docs_btree_state = couch_btree:get_state(Db#db.local_docs_btree),
admins_ptr = Db#db.admins_ptr
- },
- if Header == Header2 ->
- Db; % unchanged. nothing to do
+ }},
+ if Delay and (Db#db.waiting_delayed_commit == nil) ->
+ Db2#db{waiting_delayed_commit=
+ erlang:send_after(1000, self(), delayed_commit)};
+ Delay ->
+ Db2;
true ->
- ok = couch_file:write_header(Fd, ?HEADER_SIG, Header2),
- Db#db{header = Header2}
+ if Db#db.waiting_delayed_commit /= nil ->
+ case erlang:cancel_timer(Db#db.waiting_delayed_commit) of
+ false -> receive delayed_commit -> ok after 0 -> ok end;
+ _ -> ok
+ end;
+ true -> ok
+ end,
+ ok = couch_file:write_header(Fd, ?HEADER_SIG, Db2#db.header),
+ Db2#db{waiting_delayed_commit=nil}
end.
copy_raw_doc(SrcFd, SrcSp, DestFd, DestStream) ->