Return-Path: X-Original-To: apmail-couchdb-commits-archive@www.apache.org Delivered-To: apmail-couchdb-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 8E44F11ED2 for ; Wed, 6 Aug 2014 11:54:40 +0000 (UTC) Received: (qmail 56869 invoked by uid 500); 6 Aug 2014 11:54:39 -0000 Delivered-To: apmail-couchdb-commits-archive@couchdb.apache.org Received: (qmail 56643 invoked by uid 500); 6 Aug 2014 11:54:39 -0000 Mailing-List: contact commits-help@couchdb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@couchdb.apache.org Delivered-To: mailing list commits@couchdb.apache.org Received: (qmail 56324 invoked by uid 99); 6 Aug 2014 11:54:39 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 06 Aug 2014 11:54:39 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 1CE0988AAB2; Wed, 6 Aug 2014 11:54:39 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: rnewson@apache.org To: commits@couchdb.apache.org Date: Wed, 06 Aug 2014 11:54:49 -0000 Message-Id: In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [12/48] couch commit: updated refs/heads/windsor-merge-300 to 2c2f53e Remove ets table scan on process exit This commit adds a new ets table for doing O(1) pid-to-db-name lookup. This is to remove the necessity for doing an ets table scan on the exit of a monitored process. BugzID: 19132 Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/caffc58f Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/caffc58f Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/caffc58f Branch: refs/heads/windsor-merge-300 Commit: caffc58f3cc62211294b39eda0e32b2ff230bde2 Parents: b7b20c9 Author: Benjamin Bastian Authored: Tue May 28 15:03:03 2013 -0700 Committer: Robert Newson Committed: Mon Aug 4 16:40:35 2014 +0100 ---------------------------------------------------------------------- src/couch_lru.erl | 1 + src/couch_server.erl | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/caffc58f/src/couch_lru.erl ---------------------------------------------------------------------- diff --git a/src/couch_lru.erl b/src/couch_lru.erl index 97f27f8..ad432ec 100644 --- a/src/couch_lru.erl +++ b/src/couch_lru.erl @@ -47,6 +47,7 @@ close_int({Lru, DbName, Iter}, {Tree, Dict} = Cache) -> [#db{main_pid = Pid} = Db] = ets:lookup(couch_dbs, DbName), case couch_db:is_idle(Db) of true -> true = ets:delete(couch_dbs, DbName), + true = ets:delete(couch_dbs_pid_to_name, Pid), exit(Pid, kill), {gb_trees:delete(Lru, Tree), dict:erase(DbName, Dict)}; false -> http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/caffc58f/src/couch_server.erl ---------------------------------------------------------------------- diff --git a/src/couch_server.erl b/src/couch_server.erl index 5a73877..a10fcd0 100644 --- a/src/couch_server.erl +++ b/src/couch_server.erl @@ -198,6 +198,7 @@ init([]) -> "(\\.[0-9]{10,})?$" % but allow an optional shard timestamp at the end ), ets:new(couch_dbs, [set, protected, named_table, {keypos, #db.name}]), + ets:new(couch_dbs_pid_to_name, [set, protected, named_table]), process_flag(trap_exit, true), {ok, #server{root_dir=RootDir, dbname_regexp=RegExp, @@ -312,6 +313,7 @@ open_async(Server, From, DbName, Filepath, Options) -> fd_monitor = locked, options = Options }), + true = ets:insert(couch_dbs_pid_to_name, {Opener, DbName}), db_opened(Server, Options). handle_call(close_lru, _From, #server{lru=Lru} = Server) -> @@ -326,8 +328,9 @@ handle_call({set_max_dbs_open, Max}, _From, Server) -> {reply, ok, Server#server{max_dbs_open=Max}}; handle_call(get_server, _From, Server) -> {reply, {ok, Server}, Server}; -handle_call({open_result, DbName, {ok, Db}}, _From, Server) -> +handle_call({open_result, DbName, {ok, Db}}, {FromPid, _Tag}, Server) -> link(Db#db.main_pid), + true = ets:delete(couch_dbs_pid_to_name, FromPid), case erase({async_open, DbName}) of undefined -> ok; T0 -> ?LOG_INFO("needed ~p ms to open new ~s", [timer:now_diff(os:timestamp(),T0)/1000, DbName]) @@ -344,6 +347,7 @@ handle_call({open_result, DbName, {ok, Db}}, _From, Server) -> ok end, true = ets:insert(couch_dbs, Db), + true = ets:insert(couch_dbs_pid_to_name, {Db#db.main_pid, DbName}), Lru = case couch_db:is_system_db(Db) of false -> Stat = {couchdb, open_databases}, @@ -355,12 +359,13 @@ handle_call({open_result, DbName, {ok, Db}}, _From, Server) -> {reply, ok, Server#server{lru = Lru}}; handle_call({open_result, DbName, {error, eexist}}, From, Server) -> handle_call({open_result, DbName, file_exists}, From, Server); -handle_call({open_result, DbName, Error}, _From, Server) -> +handle_call({open_result, DbName, Error}, {FromPid, _Tag}, Server) -> % icky hack of field values - compactor_pid used to store clients [#db{fd=ReqType, compactor_pid=Froms}=Db] = ets:lookup(couch_dbs, DbName), [gen_server:reply(From, Error) || From <- Froms], ?LOG_INFO("open_result error ~p for ~s", [Error, DbName]), true = ets:delete(couch_dbs, DbName), + true = ets:delete(couch_dbs_pid_to_name, FromPid), NewServer = case ReqType of {create, DbName, Filepath, Options, CrFrom} -> open_async(Server, CrFrom, DbName, Filepath, Options); @@ -435,11 +440,13 @@ handle_call({delete, DbName, Options}, _From, Server) -> [#db{main_pid=Pid, compactor_pid=Froms} = Db] when is_list(Froms) -> % icky hack of field values - compactor_pid used to store clients true = ets:delete(couch_dbs, DbName), + true = ets:delete(couch_dbs_pid_to_name, Pid), exit(Pid, kill), [gen_server:reply(F, not_found) || F <- Froms], db_closed(Server, Db#db.options); [#db{main_pid=Pid} = Db] -> true = ets:delete(couch_dbs, DbName), + true = ets:delete(couch_dbs_pid_to_name, Pid), exit(Pid, kill), db_closed(Server, Db#db.options) end, @@ -485,8 +492,10 @@ code_change(_, State, _) -> handle_info({'EXIT', _Pid, config_change}, Server) -> {stop, config_change, Server}; handle_info({'EXIT', Pid, Reason}, Server) -> - case ets:match_object(couch_dbs, #db{main_pid=Pid, _='_'}) of - [#db{name = DbName, compactor_pid=Froms} = Db] -> + case ets:lookup(couch_dbs_pid_to_name, Pid) of + [DbName] -> + [#db{compactor_pid=Froms}=Db] = + ets:match_object(couch_dbs, #db{name=DbName, _='_'}), if Reason /= snappy_nif_not_loaded -> ok; true -> Msg = io_lib:format("To open the database `~s`, Apache CouchDB " "must be built with Erlang OTP R13B04 or higher.", [DbName]), @@ -500,6 +509,7 @@ handle_info({'EXIT', Pid, Reason}, Server) -> ok end, true = ets:delete(couch_dbs, DbName), + true = ets:delete(couch_dbs_pid_to_name, Pid), {noreply, db_closed(Server, Db#db.options)}; [] -> {noreply, Server}