You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by da...@apache.org on 2016/10/17 21:35:53 UTC

[1/9] couch commit: updated refs/heads/HACK-benchmark-COUCHDB-3191-improve-couch-lru-performance to 4c4cebc

Repository: couchdb-couch
Updated Branches:
  refs/heads/HACK-benchmark-COUCHDB-3191-improve-couch-lru-performance [created] 4c4cebc00


Rewrite couch_lru

This changes couch_lru from using a gb_tree and dict to a pair of
khashes. Using these we can implement an approximation of a standard
linked list by using references as links and looking up each node in the
nodes khash.

COUCHDB-3191


Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/39357ed8
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/39357ed8
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/39357ed8

Branch: refs/heads/HACK-benchmark-COUCHDB-3191-improve-couch-lru-performance
Commit: 39357ed8102e9ea3367a012ed17c9a0940cdc38f
Parents: fb12795
Author: Paul J. Davis <pa...@gmail.com>
Authored: Thu Oct 13 10:13:20 2016 -0500
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Thu Oct 13 10:36:23 2016 -0500

----------------------------------------------------------------------
 src/couch_lru.erl | 314 +++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 277 insertions(+), 37 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/39357ed8/src/couch_lru.erl
----------------------------------------------------------------------
diff --git a/src/couch_lru.erl b/src/couch_lru.erl
index d58eb69..7f30513 100644
--- a/src/couch_lru.erl
+++ b/src/couch_lru.erl
@@ -11,52 +11,292 @@
 % the License.
 
 -module(couch_lru).
--export([new/0, insert/2, update/2, close/1]).
+
+
+-export([
+    new/0,
+    insert/2,
+    update/2,
+    close/1
+]).
+
+% Debugging
+-export([
+    to_list/1,
+    validate/1
+]).
 
 -include_lib("couch/include/couch_db.hrl").
 
+
+-record(lru, {
+    dbs,
+    nodes,
+    head,
+    tail
+}).
+
+
+-record(node, {
+    dbname,
+    prev,
+    next
+}).
+
+
 new() ->
-    {gb_trees:empty(), dict:new()}.
-
-insert(DbName, {Tree0, Dict0}) ->
-    Lru = erlang:now(),
-    {gb_trees:insert(Lru, DbName, Tree0), dict:store(DbName, Lru, Dict0)}.
-
-update(DbName, {Tree0, Dict0}) ->
-    case dict:find(DbName, Dict0) of
-    {ok, Old} ->
-        New = erlang:now(),
-        Tree = gb_trees:insert(New, DbName, gb_trees:delete(Old, Tree0)),
-        Dict = dict:store(DbName, New, Dict0),
-        {Tree, Dict};
-    error ->
-        % We closed this database before processing the update.  Ignore
-        {Tree0, Dict0}
+    {ok, Dbs} = khash:new(),
+    {ok, Nodes} = khash:new(),
+    #lru{
+        dbs = Dbs,
+        nodes = Nodes
+    }.
+
+
+insert(DbName, Lru) ->
+    #lru{
+        dbs = Dbs,
+        nodes = Nodes,
+        head = Head,
+        tail = Tail
+    } = Lru,
+    Node = #node{
+        dbname = DbName
+    },
+    Ref = erlang:make_ref(),
+    not_found = khash:lookup(Dbs, DbName),
+    ok = khash:put(Dbs, DbName, Ref),
+    ok = khash:put(Nodes, Ref, Node),
+    {NewHead, NewTail} = case {Head, Tail} of
+        {undefined, undefined} ->
+            {Ref, Ref};
+        {_, _} when is_reference(Head), is_reference(Tail) ->
+            set_next(Lru, Tail, Node),
+            set_prev(Lru, Node, Tail),
+            {Head, Node}
+    end,
+    Lru#lru{
+        head = NewHead,
+        tail = NewTail
+    }.
+
+
+update(DbName, Lru) ->
+    #lru{
+        dbs = Dbs,
+        head = Head,
+        tail = Tail
+    } = Lru,
+    case khash:get(Dbs, DbName) of
+        Tail ->
+            % This was already the LRU entry, ignore
+            Lru;
+        Ref when is_reference(Ref) ->
+            % Get neighbors of EntryPid
+            {Prev, Next} = get_links(Lru, Ref),
+
+            % Remove Ref from link order
+            set_next(Lru, Prev, Next),
+            set_prev(Lru, Next, Prev),
+
+            % Adjust Head if necessary
+            NewHead = if
+                Ref == Head -> Next;
+                true -> Head
+            end,
+
+            % Move Ref to end of link order
+            set_next(Lru, Tail, Ref),
+            set_links(Lru, Ref, Tail, undefined),
+
+            Lru#lru{
+                head = NewHead,
+                tail = Ref
+            };
+        undefined ->
+            % We closed this database before processing the update.  Ignore
+            Lru
+    end.
+
+
+close(Lru) ->
+    #lru{
+        head = Head
+    } = Lru,
+    close(Lru, Head).
+
+
+to_list(Lru) ->
+    #lru{
+        head = Head
+    } = Lru,
+    if Head == undefined -> []; true ->
+        to_list(Lru, Head)
     end.
 
-close({Tree, _} = Cache) ->
-    close_int(gb_trees:next(gb_trees:iterator(Tree)), Cache).
 
-%% internals
+validate(Lru) ->
+    #lru{
+        dbs = Dbs,
+        nodes = Nodes,
+        head = Head,
+        tail = Tail
+    } = Lru,
+    try
+        Size = khash:size(Dbs),
+        Size = khash:size(Nodes),
+        case {Head, Tail} of
+            {undefined, undefined} ->
+                0 = khash:size(Dbs);
+            {H, T} when is_reference(H), is_reference(T) ->
+                validate(Lru, H)
+        end,
+        true
+    catch _:_ ->
+        false
+    end.
+
 
-close_int(none, _) ->
+close(_, undefined) ->
     erlang:error(all_dbs_active);
-close_int({Lru, DbName, Iter}, {Tree, Dict} = Cache) ->
+
+close(Lru, Ref) ->
+    #lru{
+        nodes = Nodes
+    } = Lru,
+    #node{
+        dbname = DbName,
+        next = Next
+    } = khash:get(Nodes, Ref),
     case ets:update_element(couch_dbs, DbName, {#db.fd_monitor, locked}) of
-    true ->
-        [#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)};
+        true ->
+            [#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),
+                    remove_ref(Lru, Ref);
+                false ->
+                    Op = {#db.fd_monitor, nil},
+                    true = ets:update_element(couch_dbs, DbName, Op),
+                    couch_stats:increment_counter([
+                        couchdb,
+                        couch_server,
+                        lru_skip
+                    ]),
+                    NewLru = update(DbName, Lru),
+                    close(NewLru, Next)
+            end;
         false ->
-            true = ets:update_element(couch_dbs, DbName, {#db.fd_monitor, nil}),
-            couch_stats:increment_counter([couchdb, couch_server, lru_skip]),
-            close_int(gb_trees:next(Iter), update(DbName, Cache))
-        end;
-    false ->
-        NewTree = gb_trees:delete(Lru, Tree),
-        NewIter = gb_trees:iterator(NewTree),
-        close_int(gb_trees:next(NewIter), {NewTree, dict:erase(DbName, Dict)})
+            remove_ref(Lru, Ref),
+            close(Lru, Next)
     end.
+
+
+to_list(_Lru, undefined) ->
+    [];
+
+to_list(Lru, Ref) ->
+    #node{
+        dbname = DbName,
+        next = Next
+    } = khash:get(Lru#lru.nodes, Ref),
+    [DbName | to_list(Lru, Next)].
+
+
+validate(Lru, Ref) ->
+    #lru{
+        dbs = Dbs,
+        nodes = Nodes,
+        head = Head,
+        tail = Tail
+    } = Lru,
+    #node{
+        dbname = DbName,
+        prev = Prev,
+        next = Next
+    } = khash:get(Nodes, Ref),
+    Ref = khash:get(Dbs, DbName),
+    if
+        Prev == undefined ->
+            Ref = Head;
+        is_reference(Prev) ->
+            Ref = (khash:get(Nodes, Prev))#node.next
+    end,
+    if
+        Next == undefined ->
+            Ref = Tail;
+        is_reference(Next) ->
+            Ref = (khash:get(Nodes, Next))#node.prev
+    end,
+    validate(Lru, Next).
+
+
+remove_ref(Lru, Ref) ->
+    #lru{
+        dbs = Dbs,
+        nodes = Nodes,
+        head = Head,
+        tail = Tail
+    } = Lru,
+
+    #node{
+        dbname = DbName,
+        prev = Prev,
+        next = Next
+    } = khash:get(Nodes, Ref),
+
+    ok = khash:del(Dbs, DbName),
+    ok = khash:del(Nodes, Ref),
+
+    set_next(Lru, Prev, Next),
+    set_prev(Lru, Next, Prev),
+
+    NewHead = if
+        Ref == Head -> Next;
+        true -> Head
+    end,
+
+    NewTail = if
+        Ref == Tail -> Prev;
+        true -> Tail
+    end,
+
+    Lru#lru{
+        head = NewHead,
+        tail = NewTail
+    }.
+
+
+set_prev(_Lru, undefined, _) ->
+    ok;
+
+set_prev(Lru, Ref, Prev) ->
+    Node = khash:get(Lru#lru.nodes, Ref),
+    khash:put(Lru#lru.nodes, Ref, Node#node{
+        prev = Prev
+    }).
+
+
+set_next(_Lru, undefined, _) ->
+    ok;
+
+set_next(Lru, Ref, Next) ->
+    Node = khash:get(Lru#lru.nodes, Ref),
+    khash:put(Lru#lru.nodes, Ref, Node#node{
+        next = Next
+    }).
+
+
+set_links(Lru, Ref, Prev, Next) ->
+    Node = khash:get(Lru#lru.nodes, Ref),
+    khash:put(Lru#lru.nodes, Ref, Node#node{
+        prev = Prev,
+        next = Next
+    }).
+
+
+get_links(Lru, Ref) ->
+    Node = khash:get(Lru#lru.nodes, Ref),
+    {Node#node.prev, Node#node.next}.


[3/9] couch commit: updated refs/heads/HACK-benchmark-COUCHDB-3191-improve-couch-lru-performance to 4c4cebc

Posted by da...@apache.org.
Add couch_lru:debug/1


Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/0aa8c06e
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/0aa8c06e
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/0aa8c06e

Branch: refs/heads/HACK-benchmark-COUCHDB-3191-improve-couch-lru-performance
Commit: 0aa8c06e42a496a21b47a4b8805cac01645eb343
Parents: dc95df8
Author: Paul J. Davis <pa...@gmail.com>
Authored: Mon Oct 17 14:08:39 2016 -0500
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Mon Oct 17 14:08:39 2016 -0500

----------------------------------------------------------------------
 src/couch_lru.erl | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/0aa8c06e/src/couch_lru.erl
----------------------------------------------------------------------
diff --git a/src/couch_lru.erl b/src/couch_lru.erl
index dcb025f..7b66840 100644
--- a/src/couch_lru.erl
+++ b/src/couch_lru.erl
@@ -23,7 +23,8 @@
 % Debugging
 -export([
     to_list/1,
-    validate/1
+    validate/1,
+    debug/1
 ]).
 
 -include_lib("couch/include/couch_db.hrl").
@@ -157,6 +158,21 @@ validate(Lru) ->
     end.
 
 
+debug(Lru) ->
+    #lru{
+        dbs = Dbs,
+        nodes = Nodes,
+        head = Head,
+        tail = Tail
+    } = Lru,
+    [
+        {dbs, khash:to_list(Dbs)},
+        {nodes, khash:to_list(Nodes)},
+        {head, Head},
+        {tail, Tail}
+    ].
+
+
 close(_, undefined) ->
     erlang:error(all_dbs_active);
 


[6/9] couch commit: updated refs/heads/HACK-benchmark-COUCHDB-3191-improve-couch-lru-performance to 4c4cebc

Posted by da...@apache.org.
Fix validation recursion termination


Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/6e52fe80
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/6e52fe80
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/6e52fe80

Branch: refs/heads/HACK-benchmark-COUCHDB-3191-improve-couch-lru-performance
Commit: 6e52fe80684bcfcaeba56ab8fc5da771f1e92d82
Parents: 0daf2dc
Author: Paul J. Davis <pa...@gmail.com>
Authored: Mon Oct 17 14:11:13 2016 -0500
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Mon Oct 17 14:11:13 2016 -0500

----------------------------------------------------------------------
 src/couch_lru.erl | 3 +++
 1 file changed, 3 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/6e52fe80/src/couch_lru.erl
----------------------------------------------------------------------
diff --git a/src/couch_lru.erl b/src/couch_lru.erl
index 3ecf0f6..c5c13e8 100644
--- a/src/couch_lru.erl
+++ b/src/couch_lru.erl
@@ -222,6 +222,9 @@ to_list(Lru, Ref) ->
     [DbName | to_list(Lru, Next)].
 
 
+validate(_Lru, undefined) ->
+    ok;
+
 validate(Lru, Ref) ->
     #lru{
         dbs = Dbs,


[4/9] couch commit: updated refs/heads/HACK-benchmark-COUCHDB-3191-improve-couch-lru-performance to 4c4cebc

Posted by da...@apache.org.
Include the reason for failure when validating


Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/e114191e
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/e114191e
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/e114191e

Branch: refs/heads/HACK-benchmark-COUCHDB-3191-improve-couch-lru-performance
Commit: e114191e43a79378001dbafc96d0d6226e433795
Parents: 0aa8c06
Author: Paul J. Davis <pa...@gmail.com>
Authored: Mon Oct 17 14:09:12 2016 -0500
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Mon Oct 17 14:09:12 2016 -0500

----------------------------------------------------------------------
 src/couch_lru.erl | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/e114191e/src/couch_lru.erl
----------------------------------------------------------------------
diff --git a/src/couch_lru.erl b/src/couch_lru.erl
index 7b66840..a321a80 100644
--- a/src/couch_lru.erl
+++ b/src/couch_lru.erl
@@ -153,8 +153,9 @@ validate(Lru) ->
                 validate(Lru, H)
         end,
         true
-    catch _:_ ->
-        false
+    catch Type:Reason ->
+        Stack = erlang:get_stacktrace(),
+        {false, {Type, Reason, Stack}}
     end.
 
 


[9/9] couch commit: updated refs/heads/HACK-benchmark-COUCHDB-3191-improve-couch-lru-performance to 4c4cebc

Posted by da...@apache.org.
HACK: For performance benchmarking only

This is just cause its easier for us to run benchmarks repeatedly while
we can change the config between runs. Otherwise we'd have to create two
releases and swap back and forth between them. Dynamic dispatch may have
a bit of a cost here but theoretically it should be a constant cost
between the two implementations.


Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/4c4cebc0
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/4c4cebc0
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/4c4cebc0

Branch: refs/heads/HACK-benchmark-COUCHDB-3191-improve-couch-lru-performance
Commit: 4c4cebc008915951a3638419be39fda95723a568
Parents: 3a04035
Author: Paul J. Davis <pa...@gmail.com>
Authored: Mon Oct 17 16:22:01 2016 -0500
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Mon Oct 17 16:22:01 2016 -0500

----------------------------------------------------------------------
 src/couch_server.erl | 74 ++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 57 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/4c4cebc0/src/couch_server.erl
----------------------------------------------------------------------
diff --git a/src/couch_server.erl b/src/couch_server.erl
index b1273e1..b012478 100644
--- a/src/couch_server.erl
+++ b/src/couch_server.erl
@@ -36,7 +36,8 @@
     dbs_open=0,
     start_time="",
     update_lru_on_read=true,
-    lru = couch_lru:new()
+    lru,
+    lru_mod = couch_lru
     }).
 
 dev_start() ->
@@ -191,10 +192,18 @@ init([]) ->
     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),
+    LruMod = case config:get("couchdb", "lru_mod", "couch_lru") of
+        "couch_lru2" ->
+            couch_lru2;
+        _ ->
+            couch_lru
+    end,
     {ok, #server{root_dir=RootDir,
                 max_dbs_open=MaxDbsOpen,
                 update_lru_on_read=UpdateLruOnRead,
-                start_time=couch_util:rfc1123_date()}}.
+                start_time=couch_util:rfc1123_date(),
+                lru = LruMod:new(),
+                lru_mod = LruMod}}.
 
 terminate(Reason, Srv) ->
     couch_log:error("couch_server terminating with ~p, state ~2048p",
@@ -281,9 +290,9 @@ make_room(Server, Options) ->
 maybe_close_lru_db(#server{dbs_open=NumOpen, max_dbs_open=MaxOpen}=Server)
         when NumOpen < MaxOpen ->
     {ok, Server};
-maybe_close_lru_db(#server{lru=Lru}=Server) ->
+maybe_close_lru_db(Server) ->
     try
-        {ok, db_closed(Server#server{lru = couch_lru:close(Lru)}, [])}
+        {ok, db_closed(lru_close(Server)), [])}
     catch error:all_dbs_active ->
         {error, all_dbs_active}
     end.
@@ -319,9 +328,9 @@ open_async(Server, From, DbName, Filepath, Options) ->
     true = ets:insert(couch_dbs_pid_to_name, {Opener, DbName}),
     db_opened(Server, Options).
 
-handle_call(close_lru, _From, #server{lru=Lru} = Server) ->
+handle_call(close_lru, _From, #server{} = Server) ->
     try
-        {reply, ok, db_closed(Server#server{lru = couch_lru:close(Lru)}, [])}
+        {reply, ok, db_closed(Server, [])}
     catch error:all_dbs_active ->
         {reply, {error, all_dbs_active}, Server}
     end;
@@ -357,13 +366,12 @@ handle_call({open_result, T0, DbName, {ok, Db}}, {FromPid, _Tag}, Server) ->
     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
+    case couch_db:is_system_db(Db) of
         false ->
-            couch_lru:insert(DbName, Server#server.lru);
+            {reply, ok, lru_insert(Server, DbName)};
         true ->
-            Server#server.lru
-    end,
-    {reply, ok, Server#server{lru = Lru}};
+            {reply, ok, Server}
+    end;
 handle_call({open_result, T0, DbName, {error, eexist}}, From, Server) ->
     handle_call({open_result, T0, DbName, file_exists}, From, Server);
 handle_call({open_result, _T0, DbName, Error}, {FromPid, _Tag}, Server) ->
@@ -486,11 +494,10 @@ handle_call({db_updated, #db{}=Db}, _From, Server0) ->
     Server = try ets:lookup_element(couch_dbs, DbName, #db.instance_start_time) of
         StartTime ->
             true = ets:insert(couch_dbs, Db),
-            Lru = case couch_db:is_system_db(Db) of
-                false -> couch_lru:update(DbName, Server0#server.lru);
-                true -> Server0#server.lru
-            end,
-            Server0#server{lru = Lru};
+            case couch_db:is_system_db(Db) of
+                false -> lru_update(Server0, DbName);
+                true -> Server0
+            end;
         _ ->
             Server0
     catch _:_ ->
@@ -499,7 +506,7 @@ handle_call({db_updated, #db{}=Db}, _From, Server0) ->
     {reply, ok, Server}.
 
 handle_cast({update_lru, DbName}, #server{lru = Lru, update_lru_on_read=true} = Server) ->
-    {noreply, Server#server{lru = couch_lru:update(DbName, Lru)}};
+    {noreply, lru_update(Server, DbName)};
 handle_cast({update_lru, _DbName}, Server) ->
     {noreply, Server};
 handle_cast(Msg, Server) ->
@@ -550,6 +557,39 @@ db_closed(Server, Options) ->
         true -> Server
     end.
 
+
+lru_insert(Server, DbName) ->
+    #server{
+        lru = Lru,
+        lru_mod = LruMod
+    } = Server,
+    NewLru = LruMod:insert(DbName, Lru),
+    Server#server{
+        lru = NewLru
+    }.
+
+
+lru_update(Server, DbName) ->
+    #server{
+        lru = Lru,
+        lru_mod = LruMod
+    } = Server,
+    NewLru = LruMod:update(DbName, Lru),
+    Server#server{
+        lru = NewLru
+    }.
+
+
+lru_close(Server) ->
+    #server{
+        lru = Lru,
+        lru_mod = LruMod
+    } = Server,
+    NewLru = LruMod:close(Lru),
+    Server#server{
+        lru = NewLru
+    }.
+
 -ifdef(TEST).
 -include_lib("eunit/include/eunit.hrl").
 


[5/9] couch commit: updated refs/heads/HACK-benchmark-COUCHDB-3191-improve-couch-lru-performance to 4c4cebc

Posted by da...@apache.org.
Don't mutate the Lru during close

This swaps the logic to only mutate the Lru while unwinding the stack.
Since the Lru is mutable now if we update while descending then we end
up in an infinite loop.


Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/0daf2dc0
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/0daf2dc0
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/0daf2dc0

Branch: refs/heads/HACK-benchmark-COUCHDB-3191-improve-couch-lru-performance
Commit: 0daf2dc055fcb8b230365f0b9a48bc066ef4c200
Parents: e114191
Author: Paul J. Davis <pa...@gmail.com>
Authored: Mon Oct 17 14:09:30 2016 -0500
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Mon Oct 17 14:09:30 2016 -0500

----------------------------------------------------------------------
 src/couch_lru.erl | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/0daf2dc0/src/couch_lru.erl
----------------------------------------------------------------------
diff --git a/src/couch_lru.erl b/src/couch_lru.erl
index a321a80..3ecf0f6 100644
--- a/src/couch_lru.erl
+++ b/src/couch_lru.erl
@@ -202,12 +202,12 @@ close(Lru, Ref) ->
                         couch_server,
                         lru_skip
                     ]),
-                    NewLru = update(DbName, Lru),
-                    close(NewLru, Next)
+                    NewLru = close(Lru, Next),
+                    update(DbName, NewLru)
             end;
         false ->
-            remove_ref(Lru, Ref),
-            close(Lru, Next)
+            NewLru = close(Lru, Next),
+            remove_ref(NewLru, Ref)
     end.
 
 


[8/9] couch commit: updated refs/heads/HACK-benchmark-COUCHDB-3191-improve-couch-lru-performance to 4c4cebc

Posted by da...@apache.org.
Make insert an upsert

The old couch_lru would blindly overwrite entries in the LRU possibly
leaving old entries in the gb_tree instance. This detects the situation
and accounts for it.


Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/3a040351
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/3a040351
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/3a040351

Branch: refs/heads/HACK-benchmark-COUCHDB-3191-improve-couch-lru-performance
Commit: 3a04035128835dc333614a65c7ee274ff6925678
Parents: 8ca26a8
Author: Paul J. Davis <pa...@gmail.com>
Authored: Mon Oct 17 15:30:19 2016 -0500
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Mon Oct 17 15:30:19 2016 -0500

----------------------------------------------------------------------
 src/couch_lru.erl | 36 ++++++++++++++++++++----------------
 1 file changed, 20 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/3a040351/src/couch_lru.erl
----------------------------------------------------------------------
diff --git a/src/couch_lru.erl b/src/couch_lru.erl
index c5c13e8..fa68733 100644
--- a/src/couch_lru.erl
+++ b/src/couch_lru.erl
@@ -64,22 +64,26 @@ insert(DbName, Lru) ->
     Node = #node{
         dbname = DbName
     },
-    Ref = erlang:make_ref(),
-    not_found = khash:lookup(Dbs, DbName),
-    ok = khash:put(Dbs, DbName, Ref),
-    ok = khash:put(Nodes, Ref, Node),
-    {NewHead, NewTail} = case {Head, Tail} of
-        {undefined, undefined} ->
-            {Ref, Ref};
-        {_, _} when is_reference(Head), is_reference(Tail) ->
-            set_next(Lru, Tail, Ref),
-            set_prev(Lru, Ref, Tail),
-            {Head, Ref}
-    end,
-    Lru#lru{
-        head = NewHead,
-        tail = NewTail
-    }.
+    case khash:lookup(Dbs, DbName) of
+        {value, Ref} when is_reference(Ref) ->
+            update(DbName, Lru);
+        not_found ->
+            Ref = erlang:make_ref(),
+            ok = khash:put(Dbs, DbName, Ref),
+            ok = khash:put(Nodes, Ref, Node),
+            {NewHead, NewTail} = case {Head, Tail} of
+                {undefined, undefined} ->
+                    {Ref, Ref};
+                {_, _} when is_reference(Head), is_reference(Tail) ->
+                    set_next(Lru, Tail, Ref),
+                    set_prev(Lru, Ref, Tail),
+                    {Head, Ref}
+            end,
+            Lru#lru{
+                head = NewHead,
+                tail = NewTail
+            }
+    end.
 
 
 update(DbName, Lru) ->


[2/9] couch commit: updated refs/heads/HACK-benchmark-COUCHDB-3191-improve-couch-lru-performance to 4c4cebc

Posted by da...@apache.org.
Fix setting prev/next refs on insert

Obviously this needs to be the ref, not the `node` record.


Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/dc95df88
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/dc95df88
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/dc95df88

Branch: refs/heads/HACK-benchmark-COUCHDB-3191-improve-couch-lru-performance
Commit: dc95df88c65094cd26c60a186cdd1c285451369a
Parents: 39357ed
Author: Paul J. Davis <pa...@gmail.com>
Authored: Mon Oct 17 14:06:18 2016 -0500
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Mon Oct 17 14:06:18 2016 -0500

----------------------------------------------------------------------
 src/couch_lru.erl | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/dc95df88/src/couch_lru.erl
----------------------------------------------------------------------
diff --git a/src/couch_lru.erl b/src/couch_lru.erl
index 7f30513..dcb025f 100644
--- a/src/couch_lru.erl
+++ b/src/couch_lru.erl
@@ -71,9 +71,9 @@ insert(DbName, Lru) ->
         {undefined, undefined} ->
             {Ref, Ref};
         {_, _} when is_reference(Head), is_reference(Tail) ->
-            set_next(Lru, Tail, Node),
-            set_prev(Lru, Node, Tail),
-            {Head, Node}
+            set_next(Lru, Tail, Ref),
+            set_prev(Lru, Ref, Tail),
+            {Head, Ref}
     end,
     Lru#lru{
         head = NewHead,


[7/9] couch commit: updated refs/heads/HACK-benchmark-COUCHDB-3191-improve-couch-lru-performance to 4c4cebc

Posted by da...@apache.org.
Expose LRU test functions


Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/8ca26a84
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/8ca26a84
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/8ca26a84

Branch: refs/heads/HACK-benchmark-COUCHDB-3191-improve-couch-lru-performance
Commit: 8ca26a840042ecd64c0bc9771e7c291c619e09ef
Parents: 6e52fe8
Author: Paul J. Davis <pa...@gmail.com>
Authored: Mon Oct 17 14:11:31 2016 -0500
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Mon Oct 17 14:11:31 2016 -0500

----------------------------------------------------------------------
 src/couch_server.erl | 6 ++++++
 1 file changed, 6 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/8ca26a84/src/couch_server.erl
----------------------------------------------------------------------
diff --git a/src/couch_server.erl b/src/couch_server.erl
index 417c791..b1273e1 100644
--- a/src/couch_server.erl
+++ b/src/couch_server.erl
@@ -333,6 +333,12 @@ 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(lru_to_list, _From, #server{lru = Lru} = Server) ->
+    {reply, couch_lru:to_list(Lru), Server};
+handle_call(lru_validate, _From, #server{lru = Lru} = Server) ->
+    {reply, couch_lru:validate(Lru), Server};
+handle_call(lru_debug, _From, #server{lru = Lru} = Server) ->
+    {reply, couch_lru:debug(Lru), Server};
 handle_call({open_result, T0, DbName, {ok, Db}}, {FromPid, _Tag}, Server) ->
     link(Db#db.main_pid),
     true = ets:delete(couch_dbs_pid_to_name, FromPid),