summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/couchdb/couch_db.erl2
-rw-r--r--src/couchdb/couch_db_updater.erl2
-rw-r--r--src/couchdb/couch_file.erl13
-rw-r--r--src/couchdb/couch_httpd_view.erl19
-rw-r--r--src/couchdb/couch_server.erl3
-rw-r--r--src/couchdb/couch_server_sup.erl6
-rw-r--r--src/couchdb/couch_view.erl62
7 files changed, 61 insertions, 46 deletions
diff --git a/src/couchdb/couch_db.erl b/src/couchdb/couch_db.erl
index 6684156f..0e652b68 100644
--- a/src/couchdb/couch_db.erl
+++ b/src/couchdb/couch_db.erl
@@ -463,7 +463,7 @@ init({DbName, Filepath, Fd, Options}) ->
gen_server:call(UpdaterPid, get_db).
terminate(_Reason, Db) ->
- exit(Db#db.update_pid, kill).
+ ok.
handle_call({open_ref_counted_instance, OpenerPid}, _From, #db{fd=Fd}=Db) ->
ok = couch_file:add_ref(Fd, OpenerPid),
diff --git a/src/couchdb/couch_db_updater.erl b/src/couchdb/couch_db_updater.erl
index 68c3a1fc..b4faefee 100644
--- a/src/couchdb/couch_db_updater.erl
+++ b/src/couchdb/couch_db_updater.erl
@@ -179,9 +179,9 @@ handle_cast({compact_done, CompactFilepath}, #db{filepath=Filepath}=Db) ->
?LOG_INFO("Compaction file still behind main file "
"(update seq=~p. compact update seq=~p). Retrying.",
[Db#db.update_seq, NewSeq]),
+ couch_file:close(NewFd),
Pid = spawn_link(fun() -> start_copy_compact(Db) end),
Db2 = Db#db{compactor_pid=Pid},
- couch_file:close(NewFd),
{noreply, Db2}
end.
diff --git a/src/couchdb/couch_file.erl b/src/couchdb/couch_file.erl
index 06156324..9e60eb09 100644
--- a/src/couchdb/couch_file.erl
+++ b/src/couchdb/couch_file.erl
@@ -36,6 +36,7 @@ open(Filepath, Options) ->
case gen_server:start_link(couch_file,
{Filepath, Options, self(), Ref = make_ref()}, []) of
{ok, Fd} ->
+ couch_file_stats:track_file(Fd),
{ok, Fd};
ignore ->
% get the error
@@ -164,7 +165,9 @@ sync(Fd) ->
%% Returns: ok
%%----------------------------------------------------------------------
close(Fd) ->
- gen_server:cast(Fd, close).
+ Result = gen_server:cast(Fd, close),
+ catch unlink(Fd),
+ Result.
close_maybe(Fd) ->
gen_server:cast(Fd, {close_maybe, self()}).
@@ -185,6 +188,7 @@ add_ref(Fd, Pid) ->
num_refs(Fd) ->
gen_server:call(Fd, num_refs).
+
write_header(Fd, Prefix, Data) ->
TermBin = term_to_binary(Data),
% the size of all the bytes written to the header, including the md5 signature (16 bytes)
@@ -286,6 +290,7 @@ init_status_error(ReturnPid, Ref, Error) ->
% server functions
init({Filepath, Options, ReturnPid, Ref}) ->
+ process_flag(trap_exit, true),
case lists:member(create, Options) of
true ->
filelib:ensure_dir(Filepath),
@@ -325,8 +330,7 @@ init({Filepath, Options, ReturnPid, Ref}) ->
end.
-terminate(_Reason, Fd) ->
- file:close(Fd),
+terminate(_Reason, _Fd) ->
ok.
@@ -366,7 +370,6 @@ handle_call(num_refs, _From, Fd) ->
{reply, length(Monitors), Fd}.
-
handle_cast(close, Fd) ->
{stop,normal,Fd};
handle_cast({close_maybe, Pid}, Fd) ->
@@ -388,6 +391,8 @@ handle_cast({drop_ref, Pid}, Fd) ->
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
+handle_info({'EXIT', _Pid, Reason}, Fd) ->
+ {stop, Reason, Fd};
handle_info({'DOWN', MonitorRef, _Type, Pid, _Info}, Fd) ->
{MonitorRef, _RefCount} = erase(Pid),
maybe_close_async(Fd).
diff --git a/src/couchdb/couch_httpd_view.erl b/src/couchdb/couch_httpd_view.erl
index 13842149..35203ced 100644
--- a/src/couchdb/couch_httpd_view.erl
+++ b/src/couchdb/couch_httpd_view.erl
@@ -26,21 +26,20 @@ design_doc_view(Req, Db, Id, ViewName, Keys) ->
update = Update,
reduce = Reduce
} = QueryArgs = parse_view_query(Req, Keys),
- case couch_view:get_map_view({couch_db:name(Db),
- <<"_design/", Id/binary>>, ViewName, Update}) of
+ DesignId = <<"_design/", Id/binary>>,
+ case couch_view:get_map_view(Db, DesignId, ViewName, Update) of
{ok, View} ->
output_map_view(Req, View, Db, QueryArgs, Keys);
{not_found, Reason} ->
- case couch_view:get_reduce_view({couch_db:name(Db),
- <<"_design/", Id/binary>>, ViewName}) of
- {ok, View} ->
+ case couch_view:get_reduce_view(Db, DesignId, ViewName, Update) of
+ {ok, ReduceView} ->
parse_view_query(Req, Keys, true), % just for validation
case Reduce of
false ->
- {reduce, _N, _Lang, MapView} = View,
+ MapView = couch_view:extract_map_view(ReduceView),
output_map_view(Req, MapView, Db, QueryArgs, Keys);
_ ->
- output_reduce_view(Req, View, QueryArgs, Keys)
+ output_reduce_view(Req, ReduceView, QueryArgs, Keys)
end;
_ ->
throw({not_found, Reason})
@@ -72,11 +71,11 @@ handle_temp_view_req(#httpd{method='POST'}=Req, Db) ->
Keys = proplists:get_value(<<"keys">>, Props, nil),
case proplists:get_value(<<"reduce">>, Props, null) of
null ->
- {ok, View} = couch_view:get_map_view({temp, couch_db:name(Db), Language, MapSrc}),
+ {ok, View} = couch_view:get_temp_map_view(Db, Language, MapSrc),
output_map_view(Req, View, Db, QueryArgs, Keys);
RedSrc ->
- {ok, View} = couch_view:get_reduce_view(
- {temp, couch_db:name(Db), Language, MapSrc, RedSrc}),
+ {ok, View} = couch_view:get_temp_reduce_view(Db, Language, MapSrc,
+ RedSrc),
output_reduce_view(Req, View, QueryArgs, Keys)
end;
diff --git a/src/couchdb/couch_server.erl b/src/couchdb/couch_server.erl
index 2a2f51e2..f0e85734 100644
--- a/src/couchdb/couch_server.erl
+++ b/src/couchdb/couch_server.erl
@@ -270,9 +270,8 @@ handle_call({create, DbName, Options}, _From, Server) ->
Error ->
{reply, Error, Server}
end;
-handle_call({delete, DbName, Options}, _From, Server) ->
+handle_call({delete, DbName, _Options}, _From, Server) ->
DbNameList = binary_to_list(DbName),
- _UserCtx = proplists:get_value(user_ctx, Options, nil),
case check_dbname(Server, DbNameList) of
ok ->
FullFilepath = get_full_filename(Server, DbNameList),
diff --git a/src/couchdb/couch_server_sup.erl b/src/couchdb/couch_server_sup.erl
index 9c74a1a3..f0157864 100644
--- a/src/couchdb/couch_server_sup.erl
+++ b/src/couchdb/couch_server_sup.erl
@@ -139,6 +139,12 @@ start_primary_services() ->
brutal_kill,
supervisor,
[couch_server]},
+ {couch_file_stats,
+ {couch_file_stats, start_link, []},
+ permanent,
+ brutal_kill,
+ supervisor,
+ [couch_file_stats]},
{couch_db_update_event,
{gen_event, start_link, [{local, couch_db_update}]},
permanent,
diff --git a/src/couchdb/couch_view.erl b/src/couchdb/couch_view.erl
index 84f327e3..665cb6f7 100644
--- a/src/couchdb/couch_view.erl
+++ b/src/couchdb/couch_view.erl
@@ -13,9 +13,11 @@
-module(couch_view).
-behaviour(gen_server).
--export([start_link/0,fold/4,fold/5,less_json/2,less_json_keys/2,expand_dups/2,detuple_kvs/2]).
--export([init/1,terminate/2,handle_call/3,handle_cast/2,handle_info/2,code_change/3]).
--export([get_reduce_view/1, get_map_view/1,get_row_count/1,reduce_to_count/1, fold_reduce/7]).
+-export([start_link/0,fold/4,fold/5,less_json/2,less_json_keys/2,expand_dups/2,
+ detuple_kvs/2,init/1,terminate/2,handle_call/3,handle_cast/2,handle_info/2,
+ code_change/3,get_reduce_view/4,get_temp_reduce_view/4,get_temp_map_view/3,
+ get_map_view/4,get_row_count/1,reduce_to_count/1,fold_reduce/7,
+ extract_map_view/1]).
-include("couch_db.hrl").
@@ -23,7 +25,8 @@ start_link() ->
gen_server:start_link({local, couch_view}, couch_view, [], []).
get_temp_updater(DbName, Type, MapSrc, RedSrc) ->
- {ok, Pid} = gen_server:call(couch_view, {start_temp_updater, DbName, Type, MapSrc, RedSrc}),
+ {ok, Pid} = gen_server:call(couch_view,
+ {start_temp_updater, DbName, Type, MapSrc, RedSrc}),
Pid.
get_group_server(DbName, GroupId) ->
@@ -34,21 +37,28 @@ get_group_server(DbName, GroupId) ->
throw(Error)
end.
-get_updated_group(DbName, GroupId, Update) ->
- couch_view_group:request_group(get_group_server(DbName, GroupId), seq_for_update(DbName, Update)).
+get_group(Db, GroupId, Update) ->
+ couch_view_group:request_group(
+ get_group_server(couch_db:name(Db), GroupId),
+ if Update -> couch_db:get_update_seq(Db); true -> 0 end).
-get_updated_group(temp, DbName, Type, MapSrc, RedSrc, Update) ->
- couch_view_group:request_group(get_temp_updater(DbName, Type, MapSrc, RedSrc), seq_for_update(DbName, Update)).
+
+get_temp_group(Db, Type, MapSrc, RedSrc) ->
+ couch_view_group:request_group(
+ get_temp_updater(couch_db:name(Db), Type, MapSrc, RedSrc),
+ couch_db:get_update_seq(Db)).
get_row_count(#view{btree=Bt}) ->
{ok, {Count, _Reds}} = couch_btree:full_reduce(Bt),
{ok, Count}.
-get_reduce_view({temp, DbName, Type, MapSrc, RedSrc}) ->
- {ok, #group{views=[View]}} = get_updated_group(temp, DbName, Type, MapSrc, RedSrc, true),
- {ok, {temp_reduce, View}};
-get_reduce_view({DbName, GroupId, Name}) ->
- case get_updated_group(DbName, GroupId, true) of
+get_temp_reduce_view(Db, Type, MapSrc, RedSrc) ->
+ {ok, #group{views=[View]}} = get_temp_group(Db, Type, MapSrc, RedSrc),
+ {ok, {temp_reduce, View}}.
+
+
+get_reduce_view(Db, GroupId, Name, Update) ->
+ case get_group(Db, GroupId, Update) of
{ok, #group{views=Views,def_lang=Lang}} ->
get_reduce_view0(Name, Lang, Views);
Error ->
@@ -63,6 +73,9 @@ get_reduce_view0(Name, Lang, [#view{reduce_funs=RedFuns}=View|Rest]) ->
N -> {ok, {reduce, N, Lang, View}}
end.
+extract_map_view({reduce, _N, _Lang, View}) ->
+ View.
+
detuple_kvs([], Acc) ->
lists:reverse(Acc);
detuple_kvs([KV | Rest], Acc) ->
@@ -113,21 +126,14 @@ get_key_pos(Key, [{Key1,_Value}|_], N) when Key == Key1 ->
N + 1;
get_key_pos(Key, [_|Rest], N) ->
get_key_pos(Key, Rest, N+1).
-
-seq_for_update(DbName, Update) ->
- case Update of
- true ->
- {ok, #db{update_seq=CurrentSeq}} = couch_db:open(DbName, []),
- CurrentSeq;
- _Else ->
- 0
- end.
-
-get_map_view({temp, DbName, Type, Src}) ->
- {ok, #group{views=[View]}} = get_updated_group(temp, DbName, Type, Src, [], true),
- {ok, View};
-get_map_view({DbName, GroupId, Name, Update}) ->
- case get_updated_group(DbName, GroupId, Update) of
+
+
+get_temp_map_view(Db, Type, Src) ->
+ {ok, #group{views=[View]}} = get_temp_group(Db, Type, Src, []),
+ {ok, View}.
+
+get_map_view(Db, GroupId, Name, Update) ->
+ case get_group(Db, GroupId, Update) of
{ok, #group{views=Views}} ->
get_map_view0(Name, Views);
Error ->