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 2014/02/13 00:28:56 UTC

[01/25] couch-mrview commit: updated refs/heads/1994-merge-rcouch to 7775266

Updated Branches:
  refs/heads/1994-merge-rcouch 725894562 -> 777526603 (forced update)


remove Makefile.am from apps/ and fix couchspawnkillable


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

Branch: refs/heads/1994-merge-rcouch
Commit: 866ed59b9aa8ae203ed68455720ffcaaa6db573e
Parents: a630923
Author: benoitc <be...@apache.org>
Authored: Tue Jan 7 19:15:43 2014 +0100
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Wed Feb 12 17:27:38 2014 -0600

----------------------------------------------------------------------
 Makefile.am | 73 --------------------------------------------------------
 1 file changed, 73 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/866ed59b/Makefile.am
----------------------------------------------------------------------
diff --git a/Makefile.am b/Makefile.am
deleted file mode 100644
index 2b9ef86..0000000
--- a/Makefile.am
+++ /dev/null
@@ -1,73 +0,0 @@
-## Licensed under the Apache License, Version 2.0 (the "License"); you may not
-## use this file except in compliance with the License. You may obtain a copy of
-## the License at
-##
-##   http://www.apache.org/licenses/LICENSE-2.0
-##
-## Unless required by applicable law or agreed to in writing, software
-## distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-## WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-## License for the specific language governing permissions and limitations under
-## the License.
-
-couch_mrviewlibdir = $(localerlanglibdir)/couch_mrview-0.1
-couch_mrviewincludedir = $(couch_mrviewlibdir)/include
-couch_mrviewebindir = $(couch_mrviewlibdir)/ebin
-
-couch_mrviewinclude_DATA = $(include_files)
-couch_mrviewebin_DATA = $(compiled_files)
-
-include_files = \
-    include/couch_mrview.hrl
-
-source_files = \
-    src/couch_mrview.app.src \
-    src/couch_mrview.erl \
-    src/couch_mrview_cleanup.erl \
-    src/couch_mrview_compactor.erl \
-    src/couch_mrview_http.erl \
-    src/couch_mrview_index.erl \
-    src/couch_mrview_show.erl \
-    src/couch_mrview_test_util.erl \
-    src/couch_mrview_updater.erl \
-    src/couch_mrview_util.erl
-
-test_files = \
-    test/01-load.t \
-    test/02-map-views.t \
-    test/03-red-views.t \
-    test/04-index-info.t \
-    test/05-collation.t \
-    test/06-all-docs.t \
-	test/07-compact-swap.t
-
-compiled_files = \
-    ebin/couch_mrview.app \
-    ebin/couch_mrview.beam \
-    ebin/couch_mrview_cleanup.beam \
-    ebin/couch_mrview_compactor.beam \
-    ebin/couch_mrview_http.beam \
-    ebin/couch_mrview_index.beam \
-    ebin/couch_mrview_show.beam \
-    ebin/couch_mrview_test_util.beam \
-    ebin/couch_mrview_updater.beam \
-    ebin/couch_mrview_util.beam
-
-EXTRA_DIST = $(include_files) $(source_files) $(test_files)
-CLEANFILES = $(compiled_files)
-
-check:
-if TESTS
-	$(abs_top_builddir)/test/etap/run $(abs_top_srcdir)/src/couch_mrview/test
-endif
-
-ebin/%.app: src/%.app.src
-	@mkdir -p ebin/
-	sed -e "s|%version%|@version@|g" \
-	< $< > $@
-
-ebin/%.beam: src/%.erl $(include_files)
-	@mkdir -p ebin/
-	$(ERLC) -Wall -I$(top_srcdir)/src -I$(top_srcdir)/src/couchdb \
-        -o ebin/ $(ERLC_FLAGS) ${TEST} $<;
-


[11/25] couch-mrview commit: updated refs/heads/1994-merge-rcouch to 7775266

Posted by da...@apache.org.
add index update events notifications


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

Branch: refs/heads/1994-merge-rcouch
Commit: d7fed236a1b309abba62fb15b120b3b74100306c
Parents: fcfc8d2
Author: benoitc <be...@apache.org>
Authored: Thu Jan 30 09:21:06 2014 +0100
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Wed Feb 12 17:27:39 2014 -0600

----------------------------------------------------------------------
 src/couch_mrview_updater.erl |  7 +++++-
 test/09-index-events.t       | 46 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 52 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/d7fed236/src/couch_mrview_updater.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_updater.erl b/src/couch_mrview_updater.erl
index be1055c..a23def6 100644
--- a/src/couch_mrview_updater.erl
+++ b/src/couch_mrview_updater.erl
@@ -182,7 +182,7 @@ map_docs(Parent, State0) ->
     end.
 
 
-write_results(Parent, State) ->
+write_results(Parent, #mrst{db_name=DbName, idx_name=IdxName}=State) ->
     case couch_work_queue:dequeue(State#mrst.write_queue) of
         closed ->
             Parent ! {new_state, State};
@@ -192,6 +192,11 @@ write_results(Parent, State) ->
                                                            [], dict:new()),
             NewState = write_kvs(State, Seq, ViewKVs, DocIdKeys, Log),
             send_partial(NewState#mrst.partial_resp_pid, NewState),
+
+            % notifify the view update
+            couch_index_event:notify({index_update, {DbName, IdxName,
+                                                     couch_mrview_index}}),
+
             write_results(Parent, NewState)
     end.
 

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/d7fed236/test/09-index-events.t
----------------------------------------------------------------------
diff --git a/test/09-index-events.t b/test/09-index-events.t
new file mode 100644
index 0000000..90654b8
--- /dev/null
+++ b/test/09-index-events.t
@@ -0,0 +1,46 @@
+#!/usr/bin/env escript
+%% -*- erlang -*-
+%%! -pa ./deps/*/ebin -pa ./apps/*/ebin -pa ./test/etap
+
+% Licensed under the Apache License, Version 2.0 (the "License"); you may not
+% use this file except in compliance with the License. You may obtain a copy of
+% the License at
+%
+%   http://www.apache.org/licenses/LICENSE-2.0
+%
+% Unless required by applicable law or agreed to in writing, software
+% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+% License for the specific language governing permissions and limitations under
+% the License.
+
+main(_) ->
+    etap:plan(2),
+    case (catch test()) of
+        ok ->
+            etap:end_tests();
+        Other ->
+            etap:diag(io_lib:format("Test died abnormally: ~p", [Other])),
+            etap:bail(Other)
+    end,
+    timer:sleep(300),
+    ok.
+
+test() ->
+    test_util:start_couch(),
+    {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, changes),
+    test_update_event(Db),
+    test_util:stop_couch(),
+    ok.
+
+test_update_event(Db) ->
+    {ok, Pid} = couch_index_event:start_link(self()),
+    etap:ok(is_pid(Pid), "event handler added"),
+    ok = couch_mrview:refresh(Db, <<"_design/bar">>),
+    Expect = {index_update, {<<"foo">>, <<"_design/bar">>,
+                             couch_mrview_index}},
+    receive
+        Event ->
+            etap:is(Event, Expect, "index update events OK")
+    end,
+    couch_index_event:stop(Pid).


[05/25] couch-mrview commit: updated refs/heads/1994-merge-rcouch to 7775266

Posted by da...@apache.org.
couch_mrview: fix changes log

This changes make sure we pass correct keys to remove to the seq and
key_byseq btrees in views.


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

Branch: refs/heads/1994-merge-rcouch
Commit: 26d16a6ae266e70c2f6ddb9cdd59f55c16c619ab
Parents: 880103a
Author: benoitc <be...@apache.org>
Authored: Mon Jan 27 10:24:25 2014 +0100
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Wed Feb 12 17:27:39 2014 -0600

----------------------------------------------------------------------
 src/couch_mrview_updater.erl | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/26d16a6a/src/couch_mrview_updater.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_updater.erl b/src/couch_mrview_updater.erl
index 782502a..58ee9d2 100644
--- a/src/couch_mrview_updater.erl
+++ b/src/couch_mrview_updater.erl
@@ -279,13 +279,15 @@ write_kvs(State, UpdateSeq, ViewKVs, DocIdKeys, Log) ->
             true ->
                 SToRem = couch_util:dict_find(ViewId, SeqsToRemove, []),
                 SToAdd = couch_util:dict_find(ViewId, SeqsToAdd, []),
+                RemSKs = [{Seq, Key} || {Key, Seq, _} <- SToRem],
+                RemKSs = [{[Seq, Key], DocId} || {Key, Seq, DocId} <- SToRem],
                 SKVs1 = SKVs ++ SToAdd,
                 {ok, SBt} = couch_btree:add_remove(View#mrview.seq_btree,
-                                                   SKVs1, SToRem),
+                                                   SKVs1, RemSKs),
 
                 {ok, KSbt} = couch_btree:add_remove(View#mrview.key_byseq_btree,
                                                     couch_mrview_util:to_key_seq(SKVs1),
-                                                    couch_mrview_util:to_key_seq(SToRem)),
+                                                    RemKSs),
                 {SBt, KSbt};
             _ -> {nil, nil}
         end,
@@ -350,8 +352,9 @@ update_log(Btree, Log, UpdatedSeq, _) ->
                                 true ->
                                     %% the log is updated, deleted old
                                     %% record from the view
-                                    DelAcc5 = dict:append(ViewId, {Seq, Key},
-                                                        DelAcc4),
+                                    DelAcc5 = dict:append(ViewId,
+                                                          {Key, Seq, DocId},
+                                                          DelAcc4),
                                     {Log4, AddAcc4, DelAcc5};
                                 false when Op /= del ->
                                     %% an update operation has been
@@ -364,8 +367,9 @@ update_log(Btree, Log, UpdatedSeq, _) ->
                                                        {ViewId,
                                                         {Key,UpdatedSeq, del}},
                                                        Log4),
-                                    DelAcc5 = dict:append(ViewId, {Seq, Key},
-                                                        DelAcc4),
+                                    DelAcc5 = dict:append(ViewId,
+                                                          {Key, Seq, DocId},
+                                                          DelAcc4),
                                     AddAcc5 = dict:append(ViewId,
                                                           {{UpdatedSeq, Key},
                                                            {DocId, RemValue}},


[04/25] couch-mrview commit: updated refs/heads/1994-merge-rcouch to 7775266

Posted by da...@apache.org.
couch_mrview: add couch_mrview:count_view_changes_since/{4,5}

Add function to couch changes in a view index, similar to
couch_db:count_changes_since/2 .


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

Branch: refs/heads/1994-merge-rcouch
Commit: 188b30f7f2289613350dca67b8c8b71c0a58f518
Parents: 26d16a6
Author: benoitc <be...@apache.org>
Authored: Mon Jan 27 11:51:11 2014 +0100
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Wed Feb 12 17:27:39 2014 -0600

----------------------------------------------------------------------
 src/couch_mrview.erl      | 30 ++++++++++++++++++++++++++++++
 src/couch_mrview_util.erl |  8 ++++++--
 2 files changed, 36 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/188b30f7/src/couch_mrview.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview.erl b/src/couch_mrview.erl
index eb929a6..d8f092c 100644
--- a/src/couch_mrview.erl
+++ b/src/couch_mrview.erl
@@ -15,6 +15,7 @@
 -export([query_all_docs/2, query_all_docs/4]).
 -export([query_view/3, query_view/4, query_view/6]).
 -export([view_changes_since/6, view_changes_since/7]).
+-export([count_view_changes_since/4, count_view_changes_since/5]).
 -export([get_info/2]).
 -export([compact/2, compact/3, cancel_compaction/2]).
 -export([cleanup/1]).
@@ -111,6 +112,35 @@ view_changes_since(Db, DDoc, VName, StartSeq, Fun, Options, Acc) ->
             {error, seqs_not_indexed}
     end.
 
+
+count_view_changes_since(Db, DDoc, VName, SinceSeq) ->
+    count_view_changes_since(Db, DDoc, VName, SinceSeq, []).
+
+count_view_changes_since(Db, DDoc, VName, SinceSeq, Options) ->
+    Args0 = make_view_changes_args(Options),
+    {ok, {_, View}, _, Args} = couch_mrview_util:get_view(Db, DDoc, VName,
+                                                          Args0),
+    case View#mrview.seq_indexed of
+        true ->
+            OptList = make_view_changes_opts(SinceSeq, Options, Args),
+            Btree = case is_key_byseq(Options) of
+                true -> View#mrview.key_byseq_btree;
+                _ -> View#mrview.seq_btree
+            end,
+            lists:foldl(fun(Opts, Acc0) ->
+                            {ok, N} = couch_btree:fold_reduce(
+                                    Btree, fun(_SeqStart, PartialReds, 0) ->
+                                        {ok, couch_btree:final_reduce(
+                                                    Btree, PartialReds)}
+                                    end,
+                                0, Opts),
+                            Acc0 + N
+                    end, 0, OptList);
+        _ ->
+            {error, seqs_not_indexed}
+    end.
+
+
 get_info(Db, DDoc) ->
     {ok, Pid} = couch_index_server:get_index(couch_mrview_index, Db, DDoc),
     couch_index:get_info(Pid).

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/188b30f7/src/couch_mrview_util.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_util.erl b/src/couch_mrview_util.erl
index 673265a..8cb4fae 100644
--- a/src/couch_mrview_util.erl
+++ b/src/couch_mrview_util.erl
@@ -236,7 +236,6 @@ less_json_seqs({SeqA, JsonA}, {SeqB, JsonB}) ->
             Result < 0
     end.
 
-
 open_view(Db, Fd, Lang, {BTState, SeqBTState, KSeqBTState, USeq, PSeq}, View) ->
     FunSrcs = [FunSrc || {_Name, FunSrc} <- View#mrview.reduce_funs],
     ReduceFun =
@@ -265,10 +264,15 @@ open_view(Db, Fd, Lang, {BTState, SeqBTState, KSeqBTState, USeq, PSeq}, View) ->
 
     {SeqBtree, KeyBySeqBtree} = case View#mrview.seq_indexed of
         true ->
+            BySeqReduceFun = fun couch_db_updater:btree_by_seq_reduce/2,
             ViewSeqBtOpts = [{less, fun less_json_seqs/2},
+                             {reduce, BySeqReduceFun},
                              {compression, couch_db:compression(Db)}],
+            KeyBySeqBtOpts = [{less, Less},
+                              {reduce, BySeqReduceFun},
+                              {compression, couch_db:compression(Db)}],
             {ok, SBt} = couch_btree:open(SeqBTState, Fd, ViewSeqBtOpts),
-            {ok, KSBt} = couch_btree:open(KSeqBTState, Fd, ViewBtOpts),
+            {ok, KSBt} = couch_btree:open(KSeqBTState, Fd, KeyBySeqBtOpts),
             {SBt, KSBt};
         false ->
             {nil, nil}


[02/25] couch-mrview commit: updated refs/heads/1994-merge-rcouch to 7775266

Posted by da...@apache.org.
working release


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

Branch: refs/heads/1994-merge-rcouch
Commit: a6309235c6b2a5273d4baac142bd32356ced2716
Parents: 674800b
Author: benoitc <be...@apache.org>
Authored: Tue Jan 7 16:14:56 2014 +0100
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Wed Feb 12 17:27:38 2014 -0600

----------------------------------------------------------------------
 src/couch_mrview.app.src | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/a6309235/src/couch_mrview.app.src
----------------------------------------------------------------------
diff --git a/src/couch_mrview.app.src b/src/couch_mrview.app.src
index 52898a6..cce2c97 100644
--- a/src/couch_mrview.app.src
+++ b/src/couch_mrview.app.src
@@ -12,7 +12,7 @@
 
 {application, couch_mrview, [
     {description, "CouchDB Map/Reduce Views"},
-    {vsn, "%version%"},
+    {vsn, "1.3.0"},
     {modules, [
         couch_mrview,
         couch_mrview_compactor,


[09/25] couch-mrview commit: updated refs/heads/1994-merge-rcouch to 7775266

Posted by da...@apache.org.
couch_index_sup should be started by the couch application

I had this patch landing in a custommer repository for awhile. Since
couch_index is always dependent of couch it's better to add it to the
couch application supervision rather than on its own.


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

Branch: refs/heads/1994-merge-rcouch
Commit: 7d5f76504f217b0150ae5dc2ee58419116b25b30
Parents: 145ef45
Author: benoitc <be...@apache.org>
Authored: Thu Jan 9 23:29:54 2014 +0100
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Wed Feb 12 17:27:39 2014 -0600

----------------------------------------------------------------------
 test/02-map-views.t    | 2 --
 test/03-red-views.t    | 1 -
 test/04-index-info.t   | 1 -
 test/05-collation.t    | 1 -
 test/06-all-docs.t     | 1 -
 test/07-compact-swap.t | 1 -
 6 files changed, 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/7d5f7650/test/02-map-views.t
----------------------------------------------------------------------
diff --git a/test/02-map-views.t b/test/02-map-views.t
index ed1b1cc..567042d 100644
--- a/test/02-map-views.t
+++ b/test/02-map-views.t
@@ -30,8 +30,6 @@ main(_) ->
 
 test() ->
     couch_server_sup:start_link(test_util:config_files()),
-    couch_index_sup:start_link(),
-
     {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, map),
 
     test_basic(Db),

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/7d5f7650/test/03-red-views.t
----------------------------------------------------------------------
diff --git a/test/03-red-views.t b/test/03-red-views.t
index 17b9148..7f52f75 100644
--- a/test/03-red-views.t
+++ b/test/03-red-views.t
@@ -20,7 +20,6 @@ main(_) ->
 
 test() ->
     couch_server_sup:start_link(test_util:config_files()),
-    couch_index_sup:start_link(),
 
     {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, red),
 

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/7d5f7650/test/04-index-info.t
----------------------------------------------------------------------
diff --git a/test/04-index-info.t b/test/04-index-info.t
index 73c4dcc..834b7d2 100644
--- a/test/04-index-info.t
+++ b/test/04-index-info.t
@@ -32,7 +32,6 @@ sig() -> <<"276df562b152b3c4e5d34024f62672ed">>.
 
 test() ->
     couch_server_sup:start_link(test_util:config_files()),
-    couch_index_sup:start_link(),
 
     {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, map),
     couch_mrview:query_view(Db, <<"_design/bar">>, <<"baz">>),

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/7d5f7650/test/05-collation.t
----------------------------------------------------------------------
diff --git a/test/05-collation.t b/test/05-collation.t
index d476601..f98e88d 100644
--- a/test/05-collation.t
+++ b/test/05-collation.t
@@ -20,7 +20,6 @@ main(_) ->
 
 test() ->
     couch_server_sup:start_link(test_util:config_files()),
-    couch_index_sup:start_link(),
 
     {ok, Db0} = couch_mrview_test_util:new_db(<<"foo">>, map),
     {ok, Db1} = couch_mrview_test_util:save_docs(Db0, docs()),

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/7d5f7650/test/06-all-docs.t
----------------------------------------------------------------------
diff --git a/test/06-all-docs.t b/test/06-all-docs.t
index a19cd7e..370825e 100644
--- a/test/06-all-docs.t
+++ b/test/06-all-docs.t
@@ -20,7 +20,6 @@ main(_) ->
 
 test() ->
     couch_server_sup:start_link(test_util:config_files()),
-    couch_index_sup:start_link(),
 
     {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, map),
 

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/7d5f7650/test/07-compact-swap.t
----------------------------------------------------------------------
diff --git a/test/07-compact-swap.t b/test/07-compact-swap.t
index a74d273..f7ebca2 100644
--- a/test/07-compact-swap.t
+++ b/test/07-compact-swap.t
@@ -21,7 +21,6 @@ main(_) ->
 
 test() ->
     couch_server_sup:start_link(test_util:config_files()),
-    couch_index_sup:start_link(),
 
     {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, map, 1000),
     couch_mrview:query_view(Db, <<"_design/bar">>, <<"baz">>),


[15/25] couch-mrview commit: updated refs/heads/1994-merge-rcouch to 7775266

Posted by da...@apache.org.
couch_mrview: fix purge when seq_indexed=true

This change makes tsure to also purge the log btree and related btrees
in views when seqs_indexed is set to true.


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

Branch: refs/heads/1994-merge-rcouch
Commit: 880103a7a261702a015a12dba014047d9fc53861
Parents: eaa87ee
Author: benoitc <be...@apache.org>
Authored: Mon Jan 27 10:14:59 2014 +0100
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Wed Feb 12 17:27:39 2014 -0600

----------------------------------------------------------------------
 src/couch_mrview.erl         |  1 -
 src/couch_mrview_updater.erl | 57 ++++++++++++++++++++++++++++-----------
 2 files changed, 41 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/880103a7/src/couch_mrview.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview.erl b/src/couch_mrview.erl
index ca15457..eb929a6 100644
--- a/src/couch_mrview.erl
+++ b/src/couch_mrview.erl
@@ -101,7 +101,6 @@ view_changes_since(Db, DDoc, VName, StartSeq, Fun, Options, Acc) ->
                 true -> View#mrview.key_byseq_btree;
                 _ -> View#mrview.seq_btree
             end,
-            io:format("opt list ~p~n", [OptList]),
             AccOut = lists:foldl(fun(Opts, Acc0) ->
                         {ok, _R, A} = couch_mrview_util:fold_changes(
                                     Btree, Fun, Acc0, Opts),

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/880103a7/src/couch_mrview_updater.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_updater.erl b/src/couch_mrview_updater.erl
index 03a0561..782502a 100644
--- a/src/couch_mrview_updater.erl
+++ b/src/couch_mrview_updater.erl
@@ -55,40 +55,66 @@ start_update(Partial, State, NumChanges) ->
 purge(_Db, PurgeSeq, PurgedIdRevs, State) ->
     #mrst{
         id_btree=IdBtree,
+        log_btree=LogBtree,
         views=Views
     } = State,
 
     Ids = [Id || {Id, _Revs} <- PurgedIdRevs],
-    {ok, Lookups, IdBtree2} = couch_btree:query_modify(IdBtree, Ids, [], Ids),
+    {ok, Lookups, LLookups, LogBtree2, IdBtree2} = case LogBtree of
+        nil ->
+            {ok, L, Bt} = couch_btree:query_modify(IdBtree, Ids, [], Ids),
+            {ok, L, [], nil, Bt};
+        _ ->
+            {ok, L, Bt} = couch_btree:query_modify(IdBtree, Ids, [], Ids),
+            {ok, LL, LBt} = couch_btree:query_modify(LogBtree, Ids, [], Ids),
+            {ok, L, LL, LBt, Bt}
+    end,
 
     MakeDictFun = fun
         ({ok, {DocId, ViewNumRowKeys}}, DictAcc) ->
-            FoldFun = fun({ViewNum, RowKey}, DictAcc2) ->
-                dict:append(ViewNum, {RowKey, DocId}, DictAcc2)
+            FoldFun = fun
+                ({ViewNum, {Key, Seq, _Op}}, DictAcc2) ->
+                    dict:append(ViewNum, {Key, Seq, DocId}, DictAcc2);
+                ({ViewNum, RowKey}, DictAcc2) ->
+                    dict:append(ViewNum, {RowKey, DocId}, DictAcc2)
             end,
             lists:foldl(FoldFun, DictAcc, ViewNumRowKeys);
         ({not_found, _}, DictAcc) ->
             DictAcc
     end,
     KeysToRemove = lists:foldl(MakeDictFun, dict:new(), Lookups),
+    SeqsToRemove = lists:foldl(MakeDictFun, dict:new(), LLookups),
+
+    RemKeysFun = fun(#mrview{id_num=ViewId}=View) ->
+        ToRem = couch_util:dict_find(ViewId, KeysToRemove, []),
+        {ok, VBtree2} = couch_btree:add_remove(View#mrview.btree, [], ToRem),
+        NewPurgeSeq = case VBtree2 =/= View#mrview.btree of
+            true -> PurgeSeq;
+            _ -> View#mrview.purge_seq
+        end,
+        {SeqBtree2, KeyBySeqBtree2} = case View#mrview.seq_indexed of
+            true ->
+                SToRem = couch_util:dict_find(ViewId, SeqsToRemove, []),
+                SKs = [{Seq, Key} || {Key, Seq, _} <- SToRem],
+                KSs = [{[Seq, Key], DocId} || {Key, Seq, DocId} <- SToRem],
+                {ok, SBt} = couch_btree:add_remove(View#mrview.seq_btree,
+                                                   [], SKs),
+                {ok, KSbt} = couch_btree:add_remove(View#mrview.key_byseq_btree,
+                                                    [], KSs),
+                {SBt, KSbt};
+            _ -> {nil, nil}
+        end,
+        View#mrview{btree=VBtree2,
+                    seq_btree=SeqBtree2,
+                    key_byseq_btree=KeyBySeqBtree2,
+                    purge_seq=NewPurgeSeq}
 
-    RemKeysFun = fun(#mrview{id_num=Num, btree=Btree}=View) ->
-        case dict:find(Num, KeysToRemove) of
-            {ok, RemKeys} ->
-                {ok, Btree2} = couch_btree:add_remove(Btree, [], RemKeys),
-                NewPurgeSeq = case Btree2 /= Btree of
-                    true -> PurgeSeq;
-                    _ -> View#mrview.purge_seq
-                end,
-                View#mrview{btree=Btree2, purge_seq=NewPurgeSeq};
-            error ->
-                View
-        end
     end,
 
     Views2 = lists:map(RemKeysFun, Views),
     {ok, State#mrst{
         id_btree=IdBtree2,
+        log_btree=LogBtree2,
         views=Views2,
         purge_seq=PurgeSeq
     }}.
@@ -313,7 +339,6 @@ update_log(Btree, Log, UpdatedSeq, _) ->
                             end, KeysAcc, DIKeys),
                 {[Id | IdsAcc], KeysAcc1} end, {[], []}, Log),
 
-    io:format("updated ~p~n", [Updated]),
     RemValue = {[{<<"_removed">>, true}]},
     {Log1, AddAcc, DelAcc} = walk_log(Btree, fun({DocId, VIdKeys},
                                                           {Log2, AddAcc2, DelAcc2}) ->


[17/25] couch-mrview commit: updated refs/heads/1994-merge-rcouch to 7775266

Posted by da...@apache.org.
add couch_mrview:view_changes_since/{6,7} function

This function add the possibility to get changes in a view since the
last upddated sequence. You can all changes in a view since a sequence
or all changes for a key or a range in a view.

The following new secondaries are created to allows this feature:

- a generic log index to log the latest changes in views for a docid :
{DocId, [{ViewId, {Key, Seq, OP}}]} where OP can be del or add. This
index allows us to mark a key as removed if needed. It will be useful
later to help us to chain map/reduces operations or such things.

- a seq index associated to a view id : {ViewId, [{Seq, Key}, {DocId, Val}]} to look for all changes in a view

- an index indexing keys by seq: {ViewId, [{[Key, Seq], DocId}, Val}]},
  to looks for changes associated to a key or a ranhge

Note: all deleted keys are marked as deleted in the log index and their
value is {[{<<"_removed">>, true}]}.

To start to index changes you need to pass the options {seq_indexed:
true} to the design document.

Caveat: when the changes are indexed the size of the index is significantly higher.

Example of usage:  https://www.friendpaste.com/5Y6gihQReaxd8ERqbDom3y


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

Branch: refs/heads/1994-merge-rcouch
Commit: eaa87ee5e4fed035ac34d12328f3433a14ba1942
Parents: 5c5c5cf
Author: benoitc <be...@apache.org>
Authored: Sun Jan 26 23:56:09 2014 +0100
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Wed Feb 12 17:27:39 2014 -0600

----------------------------------------------------------------------
 include/couch_mrview.hrl     |   7 +-
 src/couch_mrview.erl         |  48 ++++++++++
 src/couch_mrview_index.erl   |   7 +-
 src/couch_mrview_updater.erl | 179 +++++++++++++++++++++++++++++-------
 src/couch_mrview_util.erl    | 186 ++++++++++++++++++++++++++++++++------
 test/04-index-info.t         |   2 +-
 6 files changed, 363 insertions(+), 66 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/eaa87ee5/include/couch_mrview.hrl
----------------------------------------------------------------------
diff --git a/include/couch_mrview.hrl b/include/couch_mrview.hrl
index e4ec66d..8c51932 100644
--- a/include/couch_mrview.hrl
+++ b/include/couch_mrview.hrl
@@ -18,12 +18,13 @@
     idx_name,
     language,
     design_opts=[],
+    seq_indexed=false,
     lib,
     views,
     id_btree=nil,
+    log_btree=nil,
     update_seq=0,
     purge_seq=0,
-
     first_build,
     partial_resp_pid,
     doc_acc,
@@ -41,6 +42,9 @@
     reduce_funs=[],
     def,
     btree=nil,
+    seq_btree=nil,
+    key_byseq_btree=nil,
+    seq_indexed=false,
     options=[]
 }).
 
@@ -49,6 +53,7 @@
     seq=0,
     purge_seq=0,
     id_btree_state=nil,
+    log_btree_state=nil,
     view_states=nil
 }).
 

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/eaa87ee5/src/couch_mrview.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview.erl b/src/couch_mrview.erl
index d31ed18..ca15457 100644
--- a/src/couch_mrview.erl
+++ b/src/couch_mrview.erl
@@ -14,6 +14,7 @@
 
 -export([query_all_docs/2, query_all_docs/4]).
 -export([query_view/3, query_view/4, query_view/6]).
+-export([view_changes_since/6, view_changes_since/7]).
 -export([get_info/2]).
 -export([compact/2, compact/3, cancel_compaction/2]).
 -export([cleanup/1]).
@@ -86,6 +87,30 @@ query_view(Db, {Type, View}, Args, Callback, Acc) ->
         red -> red_fold(Db, View, Args, Callback, Acc)
     end.
 
+view_changes_since(Db, DDoc, VName, StartSeq, Fun, Acc) ->
+    view_changes_since(Db, DDoc, VName, StartSeq, Fun, [], Acc).
+
+view_changes_since(Db, DDoc, VName, StartSeq, Fun, Options, Acc) ->
+    Args0 = make_view_changes_args(Options),
+    {ok, {_, View}, _, Args} = couch_mrview_util:get_view(Db, DDoc, VName,
+                                                          Args0),
+    case View#mrview.seq_indexed of
+        true ->
+            OptList = make_view_changes_opts(StartSeq, Options, Args),
+            Btree = case is_key_byseq(Options) of
+                true -> View#mrview.key_byseq_btree;
+                _ -> View#mrview.seq_btree
+            end,
+            io:format("opt list ~p~n", [OptList]),
+            AccOut = lists:foldl(fun(Opts, Acc0) ->
+                        {ok, _R, A} = couch_mrview_util:fold_changes(
+                                    Btree, Fun, Acc0, Opts),
+                        A
+                end, Acc, OptList),
+            {ok, AccOut};
+        _ ->
+            {error, seqs_not_indexed}
+    end.
 
 get_info(Db, DDoc) ->
     {ok, Pid} = couch_index_server:get_index(couch_mrview_index, Db, DDoc),
@@ -385,3 +410,26 @@ lookup_index(Key) ->
         record_info(fields, mrargs), lists:seq(2, record_info(size, mrargs))
     ),
     couch_util:get_value(Key, Index).
+
+
+is_key_byseq(Options) ->
+    lists:any(fun({K, _}) ->
+                lists:member(K, [start_key, end_key, start_key_docid,
+                                 end_key_docid, keys])
+        end, Options).
+
+make_view_changes_args(Options) ->
+    case is_key_byseq(Options) of
+        true ->
+            to_mrargs(Options);
+        false ->
+            #mrargs{}
+    end.
+
+make_view_changes_opts(StartSeq, Options, Args) ->
+    case is_key_byseq(Options) of
+        true ->
+            couch_mrview_util:changes_key_opts(StartSeq, Args);
+        false ->
+            [[{start_key, {StartSeq+1, <<>>}}] ++ Options]
+    end.

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/eaa87ee5/src/couch_mrview_index.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_index.erl b/src/couch_mrview_index.erl
index 7506f34..0835f44 100644
--- a/src/couch_mrview_index.erl
+++ b/src/couch_mrview_index.erl
@@ -44,14 +44,17 @@ get(Property, State) ->
             #mrst{
                 fd = Fd,
                 sig = Sig,
-                id_btree = Btree,
+                id_btree = IdBtree,
+                log_btree = LogBtree,
                 language = Lang,
                 update_seq = UpdateSeq,
                 purge_seq = PurgeSeq,
                 views = Views
             } = State,
             {ok, Size} = couch_file:bytes(Fd),
-            {ok, DataSize} = couch_mrview_util:calculate_data_size(Btree,Views),
+            {ok, DataSize} = couch_mrview_util:calculate_data_size(IdBtree,
+                                                                   LogBtree,
+                                                                   Views),
             {ok, [
                 {signature, list_to_binary(couch_index_util:hexsig(Sig))},
                 {language, Lang},

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/eaa87ee5/src/couch_mrview_updater.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_updater.erl b/src/couch_mrview_updater.erl
index 980b5cf..03a0561 100644
--- a/src/couch_mrview_updater.erl
+++ b/src/couch_mrview_updater.erl
@@ -141,10 +141,10 @@ map_docs(Parent, State0) ->
                 ({nil, Seq, _}, {SeqAcc, Results}) ->
                     {erlang:max(Seq, SeqAcc), Results};
                 ({Id, Seq, deleted}, {SeqAcc, Results}) ->
-                    {erlang:max(Seq, SeqAcc), [{Id, []} | Results]};
+                    {erlang:max(Seq, SeqAcc), [{Id, Seq, []} | Results]};
                 ({Id, Seq, Doc}, {SeqAcc, Results}) ->
                     {ok, Res} = couch_query_servers:map_doc_raw(QServer, Doc),
-                    {erlang:max(Seq, SeqAcc), [{Id, Res} | Results]}
+                    {erlang:max(Seq, SeqAcc), [{Id, Seq, Res} | Results]}
             end,
             FoldFun = fun(Docs, Acc) ->
                 update_task(length(Docs)),
@@ -161,9 +161,10 @@ write_results(Parent, State) ->
         closed ->
             Parent ! {new_state, State};
         {ok, Info} ->
-            EmptyKVs = [{V#mrview.id_num, []} || V <- State#mrst.views],
-            {Seq, ViewKVs, DocIdKeys} = merge_results(Info, 0, EmptyKVs, []),
-            NewState = write_kvs(State, Seq, ViewKVs, DocIdKeys),
+            EmptyKVs = [{V#mrview.id_num, {[], []}} || V <- State#mrst.views],
+            {Seq, ViewKVs, DocIdKeys, Log} = merge_results(Info, 0, EmptyKVs,
+                                                           [], dict:new()),
+            NewState = write_kvs(State, Seq, ViewKVs, DocIdKeys, Log),
             send_partial(NewState#mrst.partial_resp_pid, NewState),
             write_results(Parent, NewState)
     end.
@@ -180,65 +181,99 @@ start_query_server(State) ->
     State#mrst{qserver=QServer}.
 
 
-merge_results([], SeqAcc, ViewKVs, DocIdKeys) ->
-    {SeqAcc, ViewKVs, DocIdKeys};
-merge_results([{Seq, Results} | Rest], SeqAcc, ViewKVs, DocIdKeys) ->
-    Fun = fun(RawResults, {VKV, DIK}) ->
-        merge_results(RawResults, VKV, DIK)
+merge_results([], SeqAcc, ViewKVs, DocIdKeys, Log) ->
+    {SeqAcc, ViewKVs, DocIdKeys, Log};
+merge_results([{Seq, Results} | Rest], SeqAcc, ViewKVs, DocIdKeys, Log) ->
+    Fun = fun(RawResults, {VKV, DIK, Log2}) ->
+        merge_results(RawResults, VKV, DIK, Log2)
     end,
-    {ViewKVs1, DocIdKeys1} = lists:foldl(Fun, {ViewKVs, DocIdKeys}, Results),
-    merge_results(Rest, erlang:max(Seq, SeqAcc), ViewKVs1, DocIdKeys1).
+    {ViewKVs1, DocIdKeys1, Log1} = lists:foldl(Fun, {ViewKVs, DocIdKeys, Log},
+                                               Results),
+    merge_results(Rest, erlang:max(Seq, SeqAcc), ViewKVs1, DocIdKeys1,
+                  Log1).
 
 
-merge_results({DocId, []}, ViewKVs, DocIdKeys) ->
-    {ViewKVs, [{DocId, []} | DocIdKeys]};
-merge_results({DocId, RawResults}, ViewKVs, DocIdKeys) ->
+merge_results({DocId, _Seq, []}, ViewKVs, DocIdKeys, Log) ->
+    {ViewKVs, [{DocId, []} | DocIdKeys], dict:store(DocId, [], Log)};
+merge_results({DocId, Seq, RawResults}, ViewKVs, DocIdKeys, Log) ->
     JsonResults = couch_query_servers:raw_to_ejson(RawResults),
     Results = [[list_to_tuple(Res) || Res <- FunRs] || FunRs <- JsonResults],
-    {ViewKVs1, ViewIdKeys} = insert_results(DocId, Results, ViewKVs, [], []),
-    {ViewKVs1, [ViewIdKeys | DocIdKeys]}.
+    {ViewKVs1, ViewIdKeys, Log1} = insert_results(DocId, Seq, Results, ViewKVs, [],
+                                            [], Log),
+    {ViewKVs1, [ViewIdKeys | DocIdKeys], Log1}.
 
 
-insert_results(DocId, [], [], ViewKVs, ViewIdKeys) ->
-    {lists:reverse(ViewKVs), {DocId, ViewIdKeys}};
-insert_results(DocId, [KVs | RKVs], [{Id, VKVs} | RVKVs], VKVAcc, VIdKeys) ->
+insert_results(DocId, _Seq, [], [], ViewKVs, ViewIdKeys, Log) ->
+    {lists:reverse(ViewKVs), {DocId, ViewIdKeys}, Log};
+insert_results(DocId, Seq, [KVs | RKVs], [{Id, {VKVs, SKVs}} | RVKVs], VKVAcc,
+               VIdKeys, Log) ->
     CombineDupesFun = fun
-        ({Key, Val}, {[{Key, {dups, Vals}} | Rest], IdKeys}) ->
-            {[{Key, {dups, [Val | Vals]}} | Rest], IdKeys};
-        ({Key, Val1}, {[{Key, Val2} | Rest], IdKeys}) ->
-            {[{Key, {dups, [Val1, Val2]}} | Rest], IdKeys};
-        ({Key, _}=KV, {Rest, IdKeys}) ->
-            {[KV | Rest], [{Id, Key} | IdKeys]}
+        ({Key, Val}, {[{Key, {dups, Vals}} | Rest], IdKeys, Log2}) ->
+            {[{Key, {dups, [Val | Vals]}} | Rest], IdKeys, Log2};
+        ({Key, Val1}, {[{Key, Val2} | Rest], IdKeys, Log2}) ->
+            {[{Key, {dups, [Val1, Val2]}} | Rest], IdKeys, Log2};
+        ({Key, _}=KV, {Rest, IdKeys, Log2}) ->
+            {[KV | Rest], [{Id, Key} | IdKeys],
+             dict:append(DocId, {Id, {Key, Seq, add}}, Log2)}
     end,
-    InitAcc = {[], VIdKeys},
-    {Duped, VIdKeys0} = lists:foldl(CombineDupesFun, InitAcc, lists:sort(KVs)),
+    InitAcc = {[], VIdKeys, Log},
+    {Duped, VIdKeys0, Log1} = lists:foldl(CombineDupesFun, InitAcc,
+                                          lists:sort(KVs)),
     FinalKVs = [{{Key, DocId}, Val} || {Key, Val} <- Duped] ++ VKVs,
-    insert_results(DocId, RKVs, RVKVs, [{Id, FinalKVs} | VKVAcc], VIdKeys0).
+    FinalSKVs = [{{Seq, Key}, {DocId, Val}} || {Key, Val} <- Duped] ++ SKVs,
+    insert_results(DocId, Seq, RKVs, RVKVs,
+                  [{Id, {FinalKVs, FinalSKVs}} | VKVAcc], VIdKeys0, Log1).
 
 
-write_kvs(State, UpdateSeq, ViewKVs, DocIdKeys) ->
+write_kvs(State, UpdateSeq, ViewKVs, DocIdKeys, Log) ->
     #mrst{
         id_btree=IdBtree,
+        log_btree=LogBtree,
         first_build=FirstBuild
     } = State,
 
     {ok, ToRemove, IdBtree2} = update_id_btree(IdBtree, DocIdKeys, FirstBuild),
     ToRemByView = collapse_rem_keys(ToRemove, dict:new()),
 
-    UpdateView = fun(#mrview{id_num=ViewId}=View, {ViewId, KVs}) ->
+    {ok, SeqsToAdd, SeqsToRemove, LogBtree2} = case LogBtree of
+        nil -> {ok, undefined, undefined, nil};
+        _ -> update_log(LogBtree, Log, UpdateSeq, FirstBuild)
+    end,
+
+    UpdateView = fun(#mrview{id_num=ViewId}=View, {ViewId, {KVs, SKVs}}) ->
         ToRem = couch_util:dict_find(ViewId, ToRemByView, []),
         {ok, VBtree2} = couch_btree:add_remove(View#mrview.btree, KVs, ToRem),
         NewUpdateSeq = case VBtree2 =/= View#mrview.btree of
             true -> UpdateSeq;
             _ -> View#mrview.update_seq
         end,
-        View#mrview{btree=VBtree2, update_seq=NewUpdateSeq}
+
+        %% store the view changes.
+        {SeqBtree2, KeyBySeqBtree2} = case View#mrview.seq_indexed of
+            true ->
+                SToRem = couch_util:dict_find(ViewId, SeqsToRemove, []),
+                SToAdd = couch_util:dict_find(ViewId, SeqsToAdd, []),
+                SKVs1 = SKVs ++ SToAdd,
+                {ok, SBt} = couch_btree:add_remove(View#mrview.seq_btree,
+                                                   SKVs1, SToRem),
+
+                {ok, KSbt} = couch_btree:add_remove(View#mrview.key_byseq_btree,
+                                                    couch_mrview_util:to_key_seq(SKVs1),
+                                                    couch_mrview_util:to_key_seq(SToRem)),
+                {SBt, KSbt};
+            _ -> {nil, nil}
+        end,
+        View#mrview{btree=VBtree2,
+                    seq_btree=SeqBtree2,
+                    key_byseq_btree=KeyBySeqBtree2,
+                    update_seq=NewUpdateSeq}
     end,
 
     State#mrst{
         views=lists:zipwith(UpdateView, State#mrst.views, ViewKVs),
         update_seq=UpdateSeq,
-        id_btree=IdBtree2
+        id_btree=IdBtree2,
+        log_btree=LogBtree2
     }.
 
 
@@ -251,6 +286,84 @@ update_id_btree(Btree, DocIdKeys, _) ->
     ToRem = [Id || {Id, DIKeys} <- DocIdKeys, DIKeys == []],
     couch_btree:query_modify(Btree, ToFind, ToAdd, ToRem).
 
+walk_log(BTree, Fun, Acc, Ids) ->
+    WrapFun = fun(KV, _Offset, Acc2) ->
+            Fun(KV, Acc2)
+    end,
+    lists:foldl(fun(Id, Acc1) ->
+                Opt = [{start_key, Id}, {end_key, Id}],
+                {ok, _, A} = couch_btree:fold(BTree, WrapFun, Acc1, Opt),
+                A
+        end, Acc, Ids).
+
+update_log(Btree, Log, _UpdatedSeq, true) ->
+    ToAdd = [{Id, DIKeys} || {Id, DIKeys} <- dict:to_list(Log),
+                             DIKeys /= []],
+    {ok, LogBtree2} = couch_btree:add_remove(Btree, ToAdd, []),
+    {ok, dict:new(), dict:new(), LogBtree2};
+update_log(Btree, Log, UpdatedSeq, _) ->
+    %% build list of updated keys and Id
+    {ToLook, Updated} = dict:fold(fun
+                (Id, [], {IdsAcc, KeysAcc}) ->
+                    {[Id | IdsAcc], KeysAcc};
+                (Id, DIKeys, {IdsAcc, KeysAcc}) ->
+                    KeysAcc1 = lists:foldl(fun({ViewId, {Key, _Seq, _Op}},
+                                               KeysAcc2) ->
+                                    [{Id, ViewId, Key} | KeysAcc2]
+                            end, KeysAcc, DIKeys),
+                {[Id | IdsAcc], KeysAcc1} end, {[], []}, Log),
+
+    io:format("updated ~p~n", [Updated]),
+    RemValue = {[{<<"_removed">>, true}]},
+    {Log1, AddAcc, DelAcc} = walk_log(Btree, fun({DocId, VIdKeys},
+                                                          {Log2, AddAcc2, DelAcc2}) ->
+
+                {Log3, AddAcc3, DelAcc3} = lists:foldl(fun({ViewId,{Key, Seq, Op}},
+                                                           {Log4, AddAcc4, DelAcc4}) ->
+
+                            case lists:member({DocId, ViewId, Key}, Updated) of
+                                true ->
+                                    %% the log is updated, deleted old
+                                    %% record from the view
+                                    DelAcc5 = dict:append(ViewId, {Seq, Key},
+                                                        DelAcc4),
+                                    {Log4, AddAcc4, DelAcc5};
+                                false when Op /= del ->
+                                    %% an update operation has been
+                                    %% logged for this key. We must now
+                                    %% record it as deleted in the
+                                    %% log, remove the old record in
+                                    %% the view and update the view
+                                    %% with a removed record.
+                                    Log5 = dict:append(DocId,
+                                                       {ViewId,
+                                                        {Key,UpdatedSeq, del}},
+                                                       Log4),
+                                    DelAcc5 = dict:append(ViewId, {Seq, Key},
+                                                        DelAcc4),
+                                    AddAcc5 = dict:append(ViewId,
+                                                          {{UpdatedSeq, Key},
+                                                           {DocId, RemValue}},
+                                                          AddAcc4),
+                                    {Log5, AddAcc5, DelAcc5};
+                                false ->
+                                    %% the key has already been
+                                    %% registered in the view as
+                                    %% deleted, make sure to add it
+                                    %% to the new log.
+                                    Log5 = dict:append(DocId,
+                                                       {ViewId,
+                                                        {Key, Seq, del}}, Log4),
+                                    {Log5, AddAcc4, DelAcc4}
+                            end
+                    end, {Log2, AddAcc2, DelAcc2}, VIdKeys),
+                    {ok, {Log3, AddAcc3, DelAcc3}}
+            end, {Log, dict:new(), dict:new()}, ToLook),
+
+    ToAdd = [{Id, DIKeys} || {Id, DIKeys} <- dict:to_list(Log1), DIKeys /= []],
+    %% store the new logs
+    {ok, LogBtree2} = couch_btree:add_remove(Btree, ToAdd, []),
+    {ok, AddAcc, DelAcc, LogBtree2}.
 
 collapse_rem_keys([], Acc) ->
     Acc;

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/eaa87ee5/src/couch_mrview_util.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_util.erl b/src/couch_mrview_util.erl
index f7946d1..673265a 100644
--- a/src/couch_mrview_util.erl
+++ b/src/couch_mrview_util.erl
@@ -21,10 +21,13 @@
 -export([all_docs_key_opts/1, all_docs_key_opts/2, key_opts/1, key_opts/2]).
 -export([fold/4, fold_reduce/4]).
 -export([temp_view_to_ddoc/1]).
--export([calculate_data_size/2]).
+-export([calculate_data_size/3]).
 -export([validate_args/1]).
 -export([maybe_load_doc/3, maybe_load_doc/4]).
 -export([maybe_update_index_file/1]).
+-export([changes_key_opts/2]).
+-export([fold_changes/4]).
+-export([to_key_seq/1]).
 
 -define(MOD, couch_mrview_index).
 
@@ -84,15 +87,18 @@ ddoc_to_mrst(DbName, #doc{id=Id, body={Fields}}) ->
                 DictBySrcAcc
         end
     end,
+    {DesignOpts} = proplists:get_value(<<"options">>, Fields, {[]}),
+    SeqIndexed = proplists:get_value(<<"seq_indexed">>, DesignOpts, false),
+
     {RawViews} = couch_util:get_value(<<"views">>, Fields, {[]}),
     BySrc = lists:foldl(MakeDict, dict:new(), RawViews),
 
-    NumViews = fun({_, View}, N) -> {View#mrview{id_num=N}, N+1} end,
+    NumViews = fun({_, View}, N) ->
+            {View#mrview{id_num=N, seq_indexed=SeqIndexed}, N+1}
+    end,
     {Views, _} = lists:mapfoldl(NumViews, 0, lists:sort(dict:to_list(BySrc))),
 
     Language = couch_util:get_value(<<"language">>, Fields, <<"javascript">>),
-    {DesignOpts} = couch_util:get_value(<<"options">>, Fields, {[]}),
-    {RawViews} = couch_util:get_value(<<"views">>, Fields, {[]}),
     Lib = couch_util:get_value(<<"lib">>, RawViews, {[]}),
 
     IdxState = #mrst{
@@ -101,7 +107,8 @@ ddoc_to_mrst(DbName, #doc{id=Id, body={Fields}}) ->
         lib=Lib,
         views=Views,
         language=Language,
-        design_opts=DesignOpts
+        design_opts=DesignOpts,
+        seq_indexed=SeqIndexed
     },
     SigInfo = {Views, Language, DesignOpts, couch_index_util:sort_lib(Lib)},
     {ok, IdxState#mrst{sig=couch_util:md5(term_to_binary(SigInfo))}}.
@@ -145,7 +152,8 @@ view_sig(Db, State, View, #mrargs{include_docs=true}=Args) ->
     BaseSig = view_sig(Db, State, View, Args#mrargs{include_docs=false}),
     UpdateSeq = couch_db:get_update_seq(Db),
     PurgeSeq = couch_db:get_purge_seq(Db),
-    Bin = term_to_binary({BaseSig, UpdateSeq, PurgeSeq}),
+    Bin = term_to_binary({BaseSig, UpdateSeq, PurgeSeq,
+                          State#mrst.seq_indexed}),
     couch_index_util:hexsig(couch_util:md5(Bin));
 view_sig(Db, State, {_Nth, _Lang, View}, Args) ->
     view_sig(Db, State, View, Args);
@@ -153,11 +161,12 @@ view_sig(_Db, State, View, Args0) ->
     Sig = State#mrst.sig,
     UpdateSeq = View#mrview.update_seq,
     PurgeSeq = View#mrview.purge_seq,
+    SeqIndexed = View#mrview.seq_indexed,
     Args = Args0#mrargs{
         preflight_fun=undefined,
         extra=[]
     },
-    Bin = term_to_binary({Sig, UpdateSeq, PurgeSeq, Args}),
+    Bin = term_to_binary({Sig, UpdateSeq, PurgeSeq, SeqIndexed, Args}),
     couch_index_util:hexsig(couch_util:md5(Bin)).
 
 
@@ -166,7 +175,8 @@ init_state(Db, Fd, #mrst{views=Views}=State, nil) ->
         seq=0,
         purge_seq=couch_db:get_purge_seq(Db),
         id_btree_state=nil,
-        view_states=[{nil, 0, 0} || _ <- Views]
+        log_btree_state=nil,
+        view_states=[{nil, nil, nil, 0, 0} || _ <- Views]
     },
     init_state(Db, Fd, State, Header);
 % read <= 1.2.x header record and transpile it to >=1.3.x
@@ -180,25 +190,31 @@ init_state(Db, Fd, State, #index_header{
         seq=Seq,
         purge_seq=PurgeSeq,
         id_btree_state=IdBtreeState,
-        view_states=ViewStates
+        log_btree_state=nil,
+        view_states=[{Bt, nil, nil, USeq, PSeq} || {Bt, USeq, PSeq} <- ViewStates]
         });
 init_state(Db, Fd, State, Header) ->
-    #mrst{language=Lang, views=Views} = State,
+    #mrst{language=Lang, views=Views, seq_indexed=SeqIndexed} = State,
     #mrheader{
         seq=Seq,
         purge_seq=PurgeSeq,
         id_btree_state=IdBtreeState,
+        log_btree_state=LogBtreeState,
         view_states=ViewStates
     } = Header,
 
     StateUpdate = fun
-        ({_, _, _}=St) -> St;
-        (St) -> {St, 0, 0}
+        ({_, _, _, _, _}=St) -> St;
+        (St) -> {St, nil, nil, 0, 0}
     end,
     ViewStates2 = lists:map(StateUpdate, ViewStates),
 
     IdBtOpts = [{compression, couch_db:compression(Db)}],
     {ok, IdBtree} = couch_btree:open(IdBtreeState, Fd, IdBtOpts),
+    {ok, LogBtree} = case SeqIndexed of
+        true -> couch_btree:open(LogBtreeState, Fd, IdBtOpts);
+        false -> {ok, nil}
+    end,
 
     OpenViewFun = fun(St, View) -> open_view(Db, Fd, Lang, St, View) end,
     Views2 = lists:zipwith(OpenViewFun, ViewStates2, Views),
@@ -208,11 +224,20 @@ init_state(Db, Fd, State, Header) ->
         update_seq=Seq,
         purge_seq=PurgeSeq,
         id_btree=IdBtree,
+        log_btree=LogBtree,
         views=Views2
     }.
 
+less_json_seqs({SeqA, JsonA}, {SeqB, JsonB}) ->
+    case couch_ejson_compare:less(SeqA, SeqB) of
+        0 ->
+            couch_ejson_compare:less_json(JsonA, JsonB);
+        Result ->
+            Result < 0
+    end.
+
 
-open_view(Db, Fd, Lang, {BTState, USeq, PSeq}, View) ->
+open_view(Db, Fd, Lang, {BTState, SeqBTState, KSeqBTState, USeq, PSeq}, View) ->
     FunSrcs = [FunSrc || {_Name, FunSrc} <- View#mrview.reduce_funs],
     ReduceFun =
         fun(reduce, KVs) ->
@@ -237,7 +262,23 @@ open_view(Db, Fd, Lang, {BTState, USeq, PSeq}, View) ->
         {compression, couch_db:compression(Db)}
     ],
     {ok, Btree} = couch_btree:open(BTState, Fd, ViewBtOpts),
-    View#mrview{btree=Btree, update_seq=USeq, purge_seq=PSeq}.
+
+    {SeqBtree, KeyBySeqBtree} = case View#mrview.seq_indexed of
+        true ->
+            ViewSeqBtOpts = [{less, fun less_json_seqs/2},
+                             {compression, couch_db:compression(Db)}],
+            {ok, SBt} = couch_btree:open(SeqBTState, Fd, ViewSeqBtOpts),
+            {ok, KSBt} = couch_btree:open(KSeqBTState, Fd, ViewBtOpts),
+            {SBt, KSBt};
+        false ->
+            {nil, nil}
+    end,
+
+    View#mrview{btree=Btree,
+                seq_btree=SeqBtree,
+                key_byseq_btree=KeyBySeqBtree,
+                update_seq=USeq,
+                purge_seq=PSeq}.
 
 
 temp_view_to_ddoc({Props}) ->
@@ -292,7 +333,6 @@ fold(#mrview{btree=Bt}, Fun, Acc, Opts) ->
     end,
     {ok, _LastRed, _Acc} = couch_btree:fold(Bt, WrapperFun, Acc, Opts).
 
-
 fold_fun(_Fun, [], _, Acc) ->
     {ok, Acc};
 fold_fun(Fun, [KV|Rest], {KVReds, Reds}, Acc) ->
@@ -303,6 +343,12 @@ fold_fun(Fun, [KV|Rest], {KVReds, Reds}, Acc) ->
             {stop, Acc2}
     end.
 
+fold_changes(Bt, Fun, Acc, Opts) ->
+    WrapperFun = fun(KV, _Reds, Acc2) ->
+        Fun(changes_expand_dups([KV], []), Acc2)
+    end,
+    {ok, _LastRed, _Acc} = couch_btree:fold(Bt, WrapperFun, Acc, Opts).
+
 
 fold_reduce({NthRed, Lang, View}, Fun,  Acc, Options) ->
     #mrview{
@@ -492,21 +538,34 @@ make_header(State) ->
         update_seq=Seq,
         purge_seq=PurgeSeq,
         id_btree=IdBtree,
+        log_btree=LogBtree,
         views=Views
     } = State,
-    ViewStates = [
-        {
-            couch_btree:get_state(V#mrview.btree),
-            V#mrview.update_seq,
-            V#mrview.purge_seq
-        }
-        ||
-        V <- Views
-    ],
+
+    ViewStates = lists:foldr(fun(V, Acc) ->
+                    {SeqBtState, KSeqBtState} = case V#mrview.seq_indexed of
+                        true ->
+                            {couch_btree:get_state(V#mrview.seq_btree),
+                             couch_btree:get_state(V#mrview.key_byseq_btree)};
+                        _ -> {nil, nil}
+                    end,
+                    [{couch_btree:get_state(V#mrview.btree),
+                      SeqBtState,
+                      KSeqBtState,
+                      V#mrview.update_seq,
+                      V#mrview.purge_seq} | Acc]
+            end, [], Views),
+
+    LogBtreeState = case LogBtree of
+        nil -> nil;
+        _ -> couch_btree:get_state(LogBtree)
+    end,
+
     #mrheader{
         seq=Seq,
         purge_seq=PurgeSeq,
         id_btree_state=couch_btree:get_state(IdBtree),
+        log_btree_state= LogBtreeState,
         view_states=ViewStates
     }.
 
@@ -564,7 +623,9 @@ reset_state(State) ->
         qserver=nil,
         update_seq=0,
         id_btree=nil,
-        views=[View#mrview{btree=nil} || View <- State#mrst.views]
+        log_btree=nil,
+        views=[View#mrview{btree=nil, seq_btree=nil, key_byseq_btree=nil}
+               || View <- State#mrst.views]
     }.
 
 
@@ -633,11 +694,62 @@ reverse_key_default(<<255>>) -> <<>>;
 reverse_key_default(Key) -> Key.
 
 
-calculate_data_size(IdBt, Views) ->
-    SumFun = fun(#mrview{btree=Bt}, Acc) ->
-        sum_btree_sizes(Acc, couch_btree:size(Bt))
+changes_key_opts(StartSeq, Args) ->
+    changes_key_opts(StartSeq, Args, []).
+
+
+changes_key_opts(StartSeq, #mrargs{keys=undefined, direction=Dir}=Args, Extra) ->
+    [[{dir, Dir}] ++ changes_skey_opts(StartSeq, Args) ++
+     changes_ekey_opts(StartSeq, Args) ++ Extra];
+changes_key_opts(StartSeq, #mrargs{keys=Keys, direction=Dir}=Args, Extra) ->
+    lists:map(fun(K) ->
+        [{dir, Dir}]
+        ++ changes_skey_opts(StartSeq, Args#mrargs{start_key=K})
+        ++ changes_ekey_opts(StartSeq, Args#mrargs{end_key=K})
+        ++ Extra
+    end, Keys).
+
+
+changes_skey_opts(StartSeq, #mrargs{start_key=undefined}) ->
+    [{start_key, [<<>>, StartSeq+1]}];
+changes_skey_opts(StartSeq, #mrargs{start_key=SKey,
+                                    start_key_docid=SKeyDocId}) ->
+    [{start_key, {[SKey, StartSeq+1], SKeyDocId}}].
+
+
+changes_ekey_opts(_StartSeq, #mrargs{end_key=undefined}) ->
+    [];
+changes_ekey_opts(_StartSeq, #mrargs{end_key=EKey,
+                                    end_key_docid=EKeyDocId,
+                                    direction=Dir}=Args) ->
+    EndSeq = case Dir of
+        fwd -> 16#10000000;
+        rev -> 0
+    end,
+
+    case Args#mrargs.inclusive_end of
+        true -> [{end_key, {[EKey, EndSeq], EKeyDocId}}];
+        false -> [{end_key_gt, {[EKey, EndSeq], EKeyDocId}}]
+    end.
+
+
+
+calculate_data_size(IdBt, LogBt, Views) ->
+    SumFun = fun
+        (#mrview{btree=Bt, seq_btree=nil}, Acc) ->
+            sum_btree_sizes(Acc, couch_btree:size(Bt));
+        (#mrview{btree=Bt, seq_btree=SBt, key_byseq_btree=KSBt}, Acc) ->
+            Acc1 = sum_btree_sizes(Acc, couch_btree:size(Bt)),
+            Acc2 = sum_btree_sizes(Acc1, couch_btree:size(SBt)),
+            sum_btree_sizes(Acc2, couch_btree:size(KSBt))
+    end,
+    Size = case LogBt of
+        nil ->
+            lists:foldl(SumFun, couch_btree:size(IdBt), Views);
+        _ ->
+            lists:foldl(SumFun, couch_btree:size(IdBt) +
+                        couch_btree:size(LogBt), Views)
     end,
-    Size = lists:foldl(SumFun, couch_btree:size(IdBt), Views),
     {ok, Size}.
 
 
@@ -666,6 +778,19 @@ expand_dups([KV | Rest], Acc) ->
     expand_dups(Rest, [KV | Acc]).
 
 
+changes_expand_dups([], Acc) ->
+    lists:reverse(Acc);
+changes_expand_dups([{{[Key, Seq], DocId}, {dups, Vals}} | Rest], Acc) ->
+    Expanded = [{{Key, Seq, DocId}, Val} || Val <- Vals],
+    changes_expand_dups(Rest, Expanded ++ Acc);
+changes_expand_dups([{{Key, Seq}, {DocId, {dups, Vals}}} | Rest], Acc) ->
+    Expanded = [{{Key, Seq, DocId}, Val} || Val <- Vals],
+    changes_expand_dups(Rest, Expanded ++ Acc);
+changes_expand_dups([{{[Key, Seq], DocId}, Val} | Rest], Acc) ->
+    changes_expand_dups(Rest, [{{Key, Seq, DocId}, Val} | Acc]);
+changes_expand_dups([{{Key, Seq}, {DocId, Val}} | Rest], Acc) ->
+    changes_expand_dups(Rest, [{{Key, Seq, DocId}, Val} | Acc]).
+
 maybe_load_doc(_Db, _DI, #mrargs{include_docs=false}) ->
     [];
 maybe_load_doc(Db, #doc_info{}=DI, #mrargs{conflicts=true, doc_options=Opts}) ->
@@ -715,6 +840,9 @@ mrverror(Mesg) ->
     throw({query_parse_error, Mesg}).
 
 
+to_key_seq(L) ->
+    [{{[Key, Seq], DocId}, Val} || {{Seq, Key}, {DocId, Val}} <- L].
+
 %% Updates 1.2.x or earlier view files to 1.3.x or later view files
 %% transparently, the first time the 1.2.x view file is opened by
 %% 1.3.x or later.

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/eaa87ee5/test/04-index-info.t
----------------------------------------------------------------------
diff --git a/test/04-index-info.t b/test/04-index-info.t
index d7e1de1..34fb192 100644
--- a/test/04-index-info.t
+++ b/test/04-index-info.t
@@ -26,7 +26,7 @@ main(_) ->
     timer:sleep(300),
     ok.
 
-sig() -> <<"276df562b152b3c4e5d34024f62672ed">>.
+sig() -> <<"fdf04ef29c4a471f150acad075bdf47f">>.
 
 test() ->
     test_util:start_couch(),


[10/25] couch-mrview commit: updated refs/heads/1994-merge-rcouch to 7775266

Posted by da...@apache.org.
move src/* to the root

There is no need of an src/ folder except for an aesthetic reason, we
are obviously distributing a source. This layout is alos more common in
the Erlang world, and most editor and package manager understand it.


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

Branch: refs/heads/1994-merge-rcouch
Commit: 0ce0e964c1a67d74e01e4094ab3f7297025ef830
Parents: f53c063
Author: benoitc <be...@apache.org>
Authored: Sun Jan 12 10:17:31 2014 +0100
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Wed Feb 12 17:27:39 2014 -0600

----------------------------------------------------------------------
 test/01-load.t         | 2 +-
 test/02-map-views.t    | 2 +-
 test/03-red-views.t    | 2 +-
 test/04-index-info.t   | 2 +-
 test/05-collation.t    | 2 +-
 test/06-all-docs.t     | 2 +-
 test/07-compact-swap.t | 2 +-
 7 files changed, 7 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/0ce0e964/test/01-load.t
----------------------------------------------------------------------
diff --git a/test/01-load.t b/test/01-load.t
index ae66525..cd49785 100644
--- a/test/01-load.t
+++ b/test/01-load.t
@@ -1,6 +1,6 @@
 #!/usr/bin/env escript
 %% -*- erlang -*-
-%%! -pa ./src/deps/*/ebin -pa ./src/apps/*/ebin -pa ./src/test/etap
+%%! -pa ./deps/*/ebin -pa ./apps/*/ebin -pa ./test/etap
 
 % Licensed under the Apache License, Version 2.0 (the "License"); you may not
 % use this file except in compliance with the License. You may obtain a copy of

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/0ce0e964/test/02-map-views.t
----------------------------------------------------------------------
diff --git a/test/02-map-views.t b/test/02-map-views.t
index 98d6a8f..3b55462 100644
--- a/test/02-map-views.t
+++ b/test/02-map-views.t
@@ -1,6 +1,6 @@
 #!/usr/bin/env escript
 %% -*- erlang -*-
-%%! -pa ./src/deps/*/ebin -pa ./src/apps/*/ebin -pa ./src/test/etap
+%%! -pa ./deps/*/ebin -pa ./apps/*/ebin -pa ./test/etap
 
 % Licensed under the Apache License, Version 2.0 (the "License"); you may not
 % use this file except in compliance with the License. You may obtain a copy of

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/0ce0e964/test/03-red-views.t
----------------------------------------------------------------------
diff --git a/test/03-red-views.t b/test/03-red-views.t
index e478521..9491882 100644
--- a/test/03-red-views.t
+++ b/test/03-red-views.t
@@ -1,6 +1,6 @@
 #!/usr/bin/env escript
 %% -*- erlang -*-
-%%! -pa ./src/deps/*/ebin -pa ./src/apps/*/ebin -pa ./src/test/etap
+%%! -pa ./deps/*/ebin -pa ./apps/*/ebin -pa ./test/etap
 
 
 % Licensed under the Apache License, Version 2.0 (the "License"); you may not

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/0ce0e964/test/04-index-info.t
----------------------------------------------------------------------
diff --git a/test/04-index-info.t b/test/04-index-info.t
index 3f47436..8ed6170 100644
--- a/test/04-index-info.t
+++ b/test/04-index-info.t
@@ -1,6 +1,6 @@
 #!/usr/bin/env escript
 %% -*- erlang -*-
-%%! -pa ./src/deps/*/ebin -pa ./src/apps/*/ebin -pa ./src/test/etap
+%%! -pa ./deps/*/ebin -pa ./apps/*/ebin -pa ./test/etap
 
 % Licensed under the Apache License, Version 2.0 (the "License"); you may not
 % use this file except in compliance with the License. You may obtain a copy of

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/0ce0e964/test/05-collation.t
----------------------------------------------------------------------
diff --git a/test/05-collation.t b/test/05-collation.t
index f0c4f0d..4c13bb7 100644
--- a/test/05-collation.t
+++ b/test/05-collation.t
@@ -1,6 +1,6 @@
 #!/usr/bin/env escript
 %% -*- erlang -*-
-%%! -pa ./src/deps/*/ebin -pa ./src/apps/*/ebin -pa ./src/test/etap
+%%! -pa ./deps/*/ebin -pa ./apps/*/ebin -pa ./test/etap
 
 % Licensed under the Apache License, Version 2.0 (the "License"); you may not
 % use this file except in compliance with the License. You may obtain a copy of

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/0ce0e964/test/06-all-docs.t
----------------------------------------------------------------------
diff --git a/test/06-all-docs.t b/test/06-all-docs.t
index 3a08b59..a031f58 100644
--- a/test/06-all-docs.t
+++ b/test/06-all-docs.t
@@ -1,6 +1,6 @@
 #!/usr/bin/env escript
 %% -*- erlang -*-
-%%! -pa ./src/deps/*/ebin -pa ./src/apps/*/ebin -pa ./src/test/etap
+%%! -pa ./deps/*/ebin -pa ./apps/*/ebin -pa ./test/etap
 
 % Licensed under the Apache License, Version 2.0 (the "License"); you may not
 % use this file except in compliance with the License. You may obtain a copy of

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/0ce0e964/test/07-compact-swap.t
----------------------------------------------------------------------
diff --git a/test/07-compact-swap.t b/test/07-compact-swap.t
index 9185a19..34a5fb7 100644
--- a/test/07-compact-swap.t
+++ b/test/07-compact-swap.t
@@ -1,6 +1,6 @@
 #!/usr/bin/env escript
 %% -*- erlang -*-
-%%! -pa ./src/deps/*/ebin -pa ./src/apps/*/ebin -pa ./src/test/etap
+%%! -pa ./deps/*/ebin -pa ./apps/*/ebin -pa ./test/etap
 
 
 % Licensed under the Apache License, Version 2.0 (the "License"); you may not


[08/25] couch-mrview commit: updated refs/heads/1994-merge-rcouch to 7775266

Posted by da...@apache.org.
couch_mrview: fix compaction with seqs_indexed=true

This change smakes sure to compact the view indexes when using the view
changes.


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

Branch: refs/heads/1994-merge-rcouch
Commit: 3d27c6be52aada0bfd16b484e820e6df49626ca7
Parents: 188b30f
Author: benoitc <be...@apache.org>
Authored: Mon Jan 27 15:29:10 2014 +0100
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Wed Feb 12 17:27:39 2014 -0600

----------------------------------------------------------------------
 src/couch_mrview_compactor.erl | 84 +++++++++++++++++++++++++++++++++----
 src/couch_mrview_util.erl      | 12 +++++-
 2 files changed, 88 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/3d27c6be/src/couch_mrview_compactor.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_compactor.erl b/src/couch_mrview_compactor.erl
index 4ab8dd1..a7e594f 100644
--- a/src/couch_mrview_compactor.erl
+++ b/src/couch_mrview_compactor.erl
@@ -40,6 +40,8 @@ compact(State) ->
         sig=Sig,
         update_seq=Seq,
         id_btree=IdBtree,
+        log_btree=LogBtree,
+        seq_indexed=SeqIndexed,
         views=Views
     } = State,
 
@@ -56,15 +58,28 @@ compact(State) ->
 
     #mrst{
         id_btree = EmptyIdBtree,
+        log_btree = EmptyLogBtree,
         views = EmptyViews
     } = EmptyState,
 
+    TotalChanges0 = case SeqIndexed of
+        true -> NumDocIds * 2;
+        _ -> NumDocIds
+    end,
+
     TotalChanges = lists:foldl(
         fun(View, Acc) ->
             {ok, Kvs} = couch_mrview_util:get_row_count(View),
-            Acc + Kvs
+            case SeqIndexed of
+                true ->
+                    {ok, SKvs} = couch_mrview_util:get_view_changes_count(View),
+                    Acc + Kvs + SKvs * 2;
+                false ->
+                    Acc + Kvs
+            end
         end,
-        NumDocIds, Views),
+        TotalChanges0, Views),
+
     couch_task_status:add_task([
         {type, view_compaction},
         {database, DbName},
@@ -106,13 +121,25 @@ compact(State) ->
     {ok, NewIdBtree} = couch_btree:add(Bt3, lists:reverse(Uncopied)),
     FinalAcc2 = update_task(FinalAcc, length(Uncopied)),
 
+
+    {NewLogBtree, FinalAcc3} = case SeqIndexed of
+        true ->
+            compact_log(LogBtree, BufferSize,
+                        FinalAcc2#acc{kvs=[],
+                                      kvs_size=0,
+                                      btree=EmptyLogBtree});
+        _ ->
+            {nil, FinalAcc2}
+    end,
+
     {NewViews, _} = lists:mapfoldl(fun({View, EmptyView}, Acc) ->
         compact_view(View, EmptyView, BufferSize, Acc)
-    end, FinalAcc2, lists:zip(Views, EmptyViews)),
+    end, FinalAcc3, lists:zip(Views, EmptyViews)),
 
     unlink(EmptyState#mrst.fd),
     {ok, EmptyState#mrst{
         id_btree=NewIdBtree,
+        log_btree=NewLogBtree,
         views=NewViews,
         update_seq=Seq
     }}.
@@ -129,9 +156,53 @@ recompact(State) ->
             {ok, State2}
     end.
 
+compact_log(LogBtree, BufferSize, Acc0) ->
+    FoldFun = fun({DocId, _} = KV, Acc) ->
+        #acc{btree = Bt, kvs = Kvs, kvs_size = KvsSize} = Acc,
+        KvsSize2 = KvsSize + ?term_size(KV),
+        case KvsSize2 >= BufferSize of
+            true ->
+                {ok, Bt2} = couch_btree:add(Bt, lists:reverse([KV | Kvs])),
+                Acc2 = update_task(Acc, 1 + length(Kvs)),
+                {ok, Acc2#acc{
+                    btree = Bt2, kvs = [], kvs_size = 0}};
+            _ ->
+                {ok, Acc#acc{
+                    kvs = [KV | Kvs], kvs_size = KvsSize2}}
+        end
+    end,
+
+    {ok, _, FinalAcc} = couch_btree:foldl(LogBtree, FoldFun, Acc0),
+    #acc{btree = Bt3, kvs = Uncopied} = FinalAcc,
+    {ok, NewLogBtree} = couch_btree:add(Bt3, lists:reverse(Uncopied)),
+    FinalAcc2 = update_task(FinalAcc, length(Uncopied)),
+    {NewLogBtree, FinalAcc2}.
 
 %% @spec compact_view(View, EmptyView, Retry, Acc) -> {CompactView, NewAcc}
 compact_view(View, EmptyView, BufferSize, Acc0) ->
+
+    {NewBt, Acc1} = compact_view_btree(View#mrview.btree,
+                                       EmptyView#mrview.btree,
+                                       BufferSize, Acc0),
+
+    %% are we indexing changes by sequences?
+    {NewSeqBt, NewKeyBySeqBt, FinalAcc} = case View#mrview.seq_indexed of
+        true ->
+            {SBt, Acc2} = compact_view_btree(View#mrview.seq_btree,
+                                             EmptyView#mrview.seq_btree,
+                                             BufferSize, Acc1),
+            {KSBt, Acc3} = compact_view_btree(View#mrview.key_byseq_btree,
+                                              EmptyView#mrview.key_byseq_btree,
+                                              BufferSize, Acc2),
+            {SBt, KSBt, Acc3};
+        _ ->
+            {nil, nil, Acc1}
+    end,
+    {EmptyView#mrview{btree=NewBt,
+                      seq_btree=NewSeqBt,
+                      key_byseq_btree=NewKeyBySeqBt}, FinalAcc}.
+
+compact_view_btree(Btree, EmptyBtree, BufferSize, Acc0) ->
     Fun = fun(KV, #acc{btree = Bt, kvs = Kvs, kvs_size = KvsSize} = Acc) ->
         KvsSize2 = KvsSize + ?term_size(KV),
         if KvsSize2 >= BufferSize ->
@@ -143,13 +214,12 @@ compact_view(View, EmptyView, BufferSize, Acc0) ->
         end
     end,
 
-    InitAcc = Acc0#acc{kvs = [], kvs_size = 0, btree = EmptyView#mrview.btree},
-    {ok, _, FinalAcc} = couch_btree:foldl(View#mrview.btree, Fun, InitAcc),
+    InitAcc = Acc0#acc{kvs = [], kvs_size = 0, btree = EmptyBtree},
+    {ok, _, FinalAcc} = couch_btree:foldl(Btree, Fun, InitAcc),
     #acc{btree = Bt3, kvs = Uncopied} = FinalAcc,
     {ok, NewBt} = couch_btree:add(Bt3, lists:reverse(Uncopied)),
     FinalAcc2 = update_task(FinalAcc, length(Uncopied)),
-    {EmptyView#mrview{btree=NewBt}, FinalAcc2}.
-
+    {NewBt, FinalAcc2}.
 
 update_task(#acc{changes = Changes, total_changes = Total} = Acc, ChangesInc) ->
     Changes2 = Changes + ChangesInc,

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/3d27c6be/src/couch_mrview_util.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_util.erl b/src/couch_mrview_util.erl
index 8cb4fae..7c42de8 100644
--- a/src/couch_mrview_util.erl
+++ b/src/couch_mrview_util.erl
@@ -18,6 +18,7 @@
 -export([index_file/2, compaction_file/2, open_file/1]).
 -export([delete_files/2, delete_index_file/2, delete_compaction_file/2]).
 -export([get_row_count/1, all_docs_reduce_to_count/1, reduce_to_count/1]).
+-export([get_view_changes_count/1]).
 -export([all_docs_key_opts/1, all_docs_key_opts/2, key_opts/1, key_opts/2]).
 -export([fold/4, fold_reduce/4]).
 -export([temp_view_to_ddoc/1]).
@@ -330,6 +331,12 @@ reduce_to_count(Reductions) ->
     {Count, _} = couch_btree:final_reduce(Reduce, Reductions),
     Count.
 
+%% @doc get all changes for a view
+get_view_changes_count(#mrview{seq_btree=Btree}) ->
+    couch_btree:fold_reduce(
+            Btree, fun(_SeqStart, PartialReds, 0) ->
+                    {ok, couch_btree:final_reduce(Btree, PartialReds)}
+            end,0, []).
 
 fold(#mrview{btree=Bt}, Fun, Acc, Opts) ->
     WrapperFun = fun(KV, Reds, Acc2) ->
@@ -625,10 +632,13 @@ reset_state(State) ->
     State#mrst{
         fd=nil,
         qserver=nil,
+        seq_indexed=State#mrst.seq_indexed,
         update_seq=0,
         id_btree=nil,
         log_btree=nil,
-        views=[View#mrview{btree=nil, seq_btree=nil, key_byseq_btree=nil}
+        views=[View#mrview{btree=nil, seq_btree=nil,
+                           key_byseq_btree=nil,
+                           seq_indexed=View#mrview.seq_indexed}
                || View <- State#mrst.views]
     }.
 


[24/25] couch-mrview commit: updated refs/heads/1994-merge-rcouch to 7775266

Posted by da...@apache.org.
couch_mrview: couch_mrview_changes:handle_changes

Similar to couch_changes:handle_changes but for view changes. It add
support for longpolling, normal and continuous stream The API differs
from the one for doc by beeing independant from the transport: the
support of HTTP will be added on top for example.

This API will be also used to replace the view filter in the current _changes
API.

Also add unittests.


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

Branch: refs/heads/1994-merge-rcouch
Commit: dcaadec7907aec4e8338c69db96b5f4aacad67de
Parents: d7fed23
Author: benoitc <be...@apache.org>
Authored: Fri Jan 31 13:13:23 2014 +0100
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Wed Feb 12 17:27:40 2014 -0600

----------------------------------------------------------------------
 src/couch_mrview_changes.erl   | 173 ++++++++++++++++++++++++++++++++
 src/couch_mrview_test_util.erl |   2 +
 test/09-index-events.t         |  17 +++-
 test/10-index-changes.t        | 194 ++++++++++++++++++++++++++++++++++++
 4 files changed, 385 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/dcaadec7/src/couch_mrview_changes.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_changes.erl b/src/couch_mrview_changes.erl
new file mode 100644
index 0000000..2b8f910
--- /dev/null
+++ b/src/couch_mrview_changes.erl
@@ -0,0 +1,173 @@
+% Licensed under the Apache License, Version 2.0 (the "License"); you may not
+% use this file except in compliance with the License. You may obtain a copy of
+% the License at
+%
+%   http://www.apache.org/licenses/LICENSE-2.0
+%
+% Unless required by applicable law or agreed to in writing, software
+% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+% License for the specific language governing permissions and limitations under
+% the License.
+%
+-module(couch_mrview_changes).
+
+-export([handle_changes/6]).
+
+-include_lib("couch/include/couch_db.hrl").
+
+-record(vst, {dbname,
+              ddoc,
+              view,
+              view_options,
+              since,
+              callback,
+              acc,
+              user_timeout,
+              timeout,
+              heartbeat,
+              timeout_acc=0,
+              notifier,
+              stream}).
+
+-type changes_stream() :: true | false | once.
+-type changes_options() :: [{stream, changes_stream()} |
+                            {since, integer()} |
+                            {view_options, list()} |
+                            {timeout, integer()} |
+                            {heartbeat, true | integer()}].
+
+-export_type([changes_stream/0]).
+-export_type([changes_options/0]).
+
+%% @doc function returning changes in a streaming fashion if needed.
+-spec handle_changes(binary(), binary(), binary(), function(), term(),
+                     changes_options()) -> ok | {error, term()}.
+handle_changes(DbName, DDocId, View, Fun, Acc, Options) ->
+    Since = proplists:get_value(since, Options, 0),
+    Stream = proplists:get_value(stream, Options, false),
+    ViewOptions = proplists:get_value(view_options, Options, []),
+
+    State0 = #vst{dbname=DbName,
+                  ddoc=DDocId,
+                  view=View,
+                  view_options=ViewOptions,
+                  since=Since,
+                  callback=Fun,
+                  acc=Acc},
+
+    case view_changes_since(State0) of
+        {ok, #vst{since=LastSeq, acc=Acc2}=State} ->
+            case Stream of
+                true ->
+                    start_loop(State#vst{stream=true}, Options);
+                once when LastSeq =:= Since ->
+                    start_loop(State#vst{stream=once}, Options);
+                _ ->
+                    Fun(stop, {LastSeq, Acc2})
+            end;
+        {stop, #vst{since=LastSeq, acc=Acc2}} ->
+            Fun(stop, {LastSeq, Acc2});
+        Error ->
+            Error
+    end.
+
+start_loop(#vst{dbname=DbName, ddoc=DDocId}=State, Options) ->
+    {UserTimeout, Timeout, Heartbeat} = changes_timeout(Options),
+    Notifier = index_update_notifier(DbName, DDocId),
+    try
+        loop(State#vst{notifier=Notifier,
+                       user_timeout=UserTimeout,
+                       timeout=Timeout,
+                       heartbeat=Heartbeat})
+    after
+        couch_index_event:stop(Notifier)
+    end.
+
+loop(#vst{since=Since, callback=Callback, acc=Acc,
+          user_timeout=UserTimeout, timeout=Timeout,
+          heartbeat=Heartbeat, timeout_acc=TimeoutAcc,
+          stream=Stream}=State) ->
+    receive
+        index_update ->
+            case view_changes_since(State) of
+                {ok, State2} when Stream =:= true ->
+                    loop(State2#vst{timeout_acc=0});
+                {ok, #vst{since=LastSeq, acc=Acc2}} ->
+                    Callback(stop, {LastSeq, Acc2});
+                {stop, #vst{since=LastSeq, acc=Acc2}} ->
+                    Callback(stop, {LastSeq, Acc2})
+            end;
+        index_delete ->
+            Callback(stop, {Since, Acc})
+    after Timeout ->
+            TimeoutAcc2 = TimeoutAcc + Timeout,
+            case UserTimeout =< TimeoutAcc2 of
+                true ->
+                    Callback(stop, {Since, Acc});
+                false when Heartbeat =:= true ->
+                    case Callback(heartbeat, Acc) of
+                        {ok, Acc2} ->
+                            loop(State#vst{acc=Acc2, timeout_acc=TimeoutAcc2});
+                        {stop, Acc2} ->
+                            Callback(stop, {Since, Acc2})
+                    end;
+                _ ->
+                    Callback(stop, {Since, Acc})
+            end
+    end.
+
+changes_timeout(Options) ->
+    DefaultTimeout = list_to_integer(
+            couch_config:get("httpd", "changes_timeout", "60000")
+    ),
+    UserTimeout = proplists:get_value(timeout, Options, DefaultTimeout),
+    {Timeout, Heartbeat} = case proplists:get_value(heartbeat, Options) of
+        undefined -> {UserTimeout, false};
+        true ->
+            T = erlang:min(DefaultTimeout, UserTimeout),
+            {T, true};
+        H ->
+            T = erlang:min(H, UserTimeout),
+            {T, true}
+    end,
+    {UserTimeout, Timeout, Heartbeat}.
+
+view_changes_since(#vst{dbname=DbName, ddoc=DDocId, view=View,
+                        view_options=Options, since=Since,
+                        callback=Callback, acc=UserAcc}=State) ->
+    Wrapper = fun ({{Seq, _Key, _DocId}, _Val}=KV, {Go, Acc2, OldSeq}) ->
+            LastSeq = if OldSeq < Seq -> Seq;
+                true -> OldSeq
+            end,
+
+            case Callback(KV, Acc2) of
+                {ok, Acc3} -> {ok, {Go, Acc3, LastSeq}};
+                {stop, Acc3} -> {stop, {stop, Acc3, LastSeq}}
+            end
+    end,
+
+    Acc0 = {ok, UserAcc, Since},
+    case couch_mrview:view_changes_since(DbName, DDocId, View, Since,
+                                         Wrapper, Options, Acc0) of
+        {ok, {Go, UserAcc2, Since2}}->
+            {Go, State#vst{since=Since2, acc=UserAcc2}};
+        Error ->
+            Error
+    end.
+
+index_update_notifier(#db{name=DbName}, DDocId) ->
+    index_update_notifier(DbName, DDocId);
+index_update_notifier(DbName, DDocId) ->
+    Self = self(),
+    {ok, NotifierPid} = couch_index_event:start_link(fun
+                ({index_update, {Name, Id, couch_mrview_index}})
+                        when Name =:= DbName, Id =:= DDocId ->
+                    Self ! index_update;
+                ({index_delete, {Name, Id, couch_mrview_index}})
+                        when Name =:= DbName, Id =:= DDocId ->
+                    Self ! index_delete;
+                (_) ->
+                    ok
+            end),
+    NotifierPid.

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/dcaadec7/src/couch_mrview_test_util.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_test_util.erl b/src/couch_mrview_test_util.erl
index c67f24f..bcf8a87 100644
--- a/src/couch_mrview_test_util.erl
+++ b/src/couch_mrview_test_util.erl
@@ -34,6 +34,8 @@ new_db(Name, Type) ->
     {ok, Db} = couch_db:create(Name, [{user_ctx, ?ADMIN}]),
     save_docs(Db, [ddoc(Type)]).
 
+delete_db(Name) ->
+    couch_server:delete(Name, [{user_ctx, ?ADMIN}]).
 
 save_docs(Db, Docs) ->
     {ok, _} = couch_db:update_docs(Db, Docs, []),

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/dcaadec7/test/09-index-events.t
----------------------------------------------------------------------
diff --git a/test/09-index-events.t b/test/09-index-events.t
index 90654b8..1489e4e 100644
--- a/test/09-index-events.t
+++ b/test/09-index-events.t
@@ -15,7 +15,7 @@
 % the License.
 
 main(_) ->
-    etap:plan(2),
+    etap:plan(4),
     case (catch test()) of
         ok ->
             etap:end_tests();
@@ -30,6 +30,7 @@ test() ->
     test_util:start_couch(),
     {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, changes),
     test_update_event(Db),
+    test_delete_event(Db),
     test_util:stop_couch(),
     ok.
 
@@ -44,3 +45,17 @@ test_update_event(Db) ->
             etap:is(Event, Expect, "index update events OK")
     end,
     couch_index_event:stop(Pid).
+
+test_delete_event(Db) ->
+     ok = couch_mrview:refresh(Db, <<"_design/bar">>),
+    {ok, Pid} = couch_index_event:start_link(self()),
+
+    etap:ok(is_pid(Pid), "event handler added"),
+    couch_mrview_test_util:delete_db(<<"foo">>),
+    Expect = {index_delete, {<<"foo">>, <<"_design/bar">>,
+                             couch_mrview_index}},
+    receive
+        Event ->
+            etap:is(Event, Expect, "index delete events OK")
+    end,
+    couch_index_event:stop(Pid).

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/dcaadec7/test/10-index-changes.t
----------------------------------------------------------------------
diff --git a/test/10-index-changes.t b/test/10-index-changes.t
new file mode 100644
index 0000000..627376f
--- /dev/null
+++ b/test/10-index-changes.t
@@ -0,0 +1,194 @@
+#!/usr/bin/env escript
+%% -*- erlang -*-
+%%! -pa ./deps/*/ebin -pa ./apps/*/ebin -pa ./test/etap
+
+% Licensed under the Apache License, Version 2.0 (the "License"); you may not
+% use this file except in compliance with the License. You may obtain a copy of
+% the License at
+%
+%   http://www.apache.org/licenses/LICENSE-2.0
+%
+% Unless required by applicable law or agreed to in writing, software
+% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+% License for the specific language governing permissions and limitations under
+% the License.
+
+main(_) ->
+    etap:plan(6),
+    case (catch test()) of
+        ok ->
+            etap:end_tests();
+        Other ->
+            etap:diag(io_lib:format("Test died abnormally: ~p", [Other])),
+            etap:bail(Other)
+    end,
+    timer:sleep(300),
+    ok.
+
+test() ->
+    test_util:start_couch(),
+    {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, changes),
+    test_normal_changes(Db),
+    test_stream_once(Db),
+    test_stream_once_since(Db),
+    test_stream_once_timeout(Db),
+    test_stream_once_heartbeat(Db),
+    test_stream(Db),
+    test_util:stop_couch(),
+    ok.
+
+test_normal_changes(Db) ->
+    Result = run_query(Db, []),
+    Expect = {ok, 11, [
+                {{2, 1, <<"1">>}, 1},
+                {{3, 10, <<"10">>}, 10},
+                {{4, 2, <<"2">>}, 2},
+                {{5, 3, <<"3">>}, 3},
+                {{6, 4, <<"4">>}, 4},
+                {{7, 5, <<"5">>}, 5},
+                {{8, 6, <<"6">>}, 6},
+                {{9, 7, <<"7">>}, 7},
+                {{10, 8, <<"8">>}, 8},
+                {{11, 9, <<"9">>}, 9}
+    ]},
+    etap:is(Result, Expect, "normal changes worked.").
+
+test_stream_once(Db) ->
+    Result = run_query(Db, [{stream, once}]),
+    Expect = {ok, 11, [
+                {{2, 1, <<"1">>}, 1},
+                {{3, 10, <<"10">>}, 10},
+                {{4, 2, <<"2">>}, 2},
+                {{5, 3, <<"3">>}, 3},
+                {{6, 4, <<"4">>}, 4},
+                {{7, 5, <<"5">>}, 5},
+                {{8, 6, <<"6">>}, 6},
+                {{9, 7, <<"7">>}, 7},
+                {{10, 8, <<"8">>}, 8},
+                {{11, 9, <<"9">>}, 9}
+    ]},
+    etap:is(Result, Expect, "stream once since 0 worked.").
+
+
+test_stream_once_since(Db) ->
+    Self = self(),
+    spawn(fun() ->
+                Result = run_query(Db, [{since, 11},
+                                        {stream, once}]),
+                Self ! {result, Result}
+        end),
+
+    spawn(fun() ->
+                timer:sleep(1000),
+                {ok, Db1} = save_doc(Db, 11),
+                couch_mrview:refresh(Db1, <<"_design/bar">>)
+        end),
+
+    Expect = {ok,12,[{{12,11,<<"11">>},11}]},
+
+    receive
+        {result, Result} ->
+            etap:is(Result, Expect, "normal changes worked.")
+    after 5000 ->
+            io:format("never got the change", [])
+    end.
+
+
+test_stream_once_timeout(Db) ->
+    Self = self(),
+    spawn(fun() ->
+                Result = run_query(Db, [{since, 12},
+                                        {stream, once},
+                                        {timeout, 3000}]),
+                Self ! {result, Result}
+        end),
+
+
+
+    Expect = {ok, 12, []},
+
+    receive
+        {result, Result} ->
+            etap:is(Result, Expect, "got timeout.")
+    after 5000 ->
+            io:format("never got the change", [])
+    end.
+
+test_stream_once_heartbeat(Db) ->
+    Self = self(),
+    spawn(fun() ->
+                Result = run_query(Db, [{since, 12},
+                                        {stream, once},
+                                        {heartbeat, 1000}]),
+                Self ! {result, Result}
+        end),
+
+    spawn(fun() ->
+                timer:sleep(3000),
+                {ok, Db1} = save_doc(Db, 12),
+                couch_mrview:refresh(Db1, <<"_design/bar">>)
+        end),
+
+    Expect = {ok,13,[heartbeat,
+                     heartbeat,
+                     heartbeat,
+                     {{13,12,<<"12">>},12}]},
+
+
+
+    receive
+        {result, Result} ->
+            etap:is(Result, Expect, "heartbeat OK.")
+    after 5000 ->
+            io:format("never got the change", [])
+    end.
+
+
+test_stream(Db) ->
+    Self = self(),
+    spawn(fun() ->
+                Result = run_query(Db, [{since, 13},
+                                        stream,
+                                        {timeout, 3000}]),
+                Self ! {result, Result}
+        end),
+
+    spawn(fun() ->
+                timer:sleep(1000),
+                {ok, Db1} = save_doc(Db, 13),
+                couch_mrview:refresh(Db1, <<"_design/bar">>),
+                {ok, Db2} = save_doc(Db1, 14),
+                couch_mrview:refresh(Db2, <<"_design/bar">>)
+        end),
+
+    Expect = {ok, 15,[{{14,13,<<"13">>},13},
+                     {{15,14,<<"14">>},14}]},
+
+    receive
+        {result, Result} ->
+            etap:is(Result, Expect, "stream OK.")
+    after 5000 ->
+            io:format("never got the change", [])
+    end.
+
+
+save_doc(Db, Id) ->
+    Doc = couch_mrview_test_util:doc(Id),
+    {ok, _Rev} = couch_db:update_doc(Db, Doc, []),
+    {ok, _} =  couch_db:ensure_full_commit(Db),
+    couch_db:reopen(Db).
+
+run_query(Db, Opts) ->
+    Fun = fun
+        (stop, {LastSeq, Acc}) ->
+            {ok, LastSeq, Acc};
+        (heartbeat, Acc) ->
+            {ok, [heartbeat | Acc]};
+        (Event, Acc) ->
+            {ok, [Event | Acc]}
+    end,
+    couch_mrview:refresh(Db, <<"_design/bar">>),
+    {ok, LastSeq, R} = couch_mrview_changes:handle_changes(Db, <<"_design/bar">>,
+                                                  <<"baz">>, Fun, [], Opts),
+    {ok, LastSeq, lists:reverse(R)}.


[19/25] couch-mrview commit: updated refs/heads/1994-merge-rcouch to 7775266

Posted by da...@apache.org.
couch_replicator: add replication using changes in a view

Instead of a database, the replicator can now filter the documents using
a view index. All documents having a key emitted in the view can be
replicated.

View parameters can be used. Which means that you can replicate results
corresponding to a key in a view or a range.


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

Branch: refs/heads/1994-merge-rcouch
Commit: 777526603520229e184d1e75e79c7c01b99fce60
Parents: a18c041
Author: benoitc <be...@apache.org>
Authored: Sun Feb 9 00:43:23 2014 +0100
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Wed Feb 12 17:27:40 2014 -0600

----------------------------------------------------------------------
 src/couch_mrview_http.erl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/77752660/src/couch_mrview_http.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_http.erl b/src/couch_mrview_http.erl
index c5ba622..64c9fb1 100644
--- a/src/couch_mrview_http.erl
+++ b/src/couch_mrview_http.erl
@@ -50,7 +50,7 @@ handle_all_docs_req(Req, _Db) ->
 
 handle_view_req(#httpd{method='GET',
                       path_parts=[_, _, DDocName, _, VName, <<"_info">>]}=Req,
-                Db, DDoc) ->
+                Db, _DDoc) ->
 
     DDocId = <<"_design/", DDocName/binary >>,
     {ok, Info} = couch_mrview:get_view_info(Db#db.name, DDocId, VName),


[03/25] couch-mrview commit: updated refs/heads/1994-merge-rcouch to 7775266

Posted by da...@apache.org.
inital move to rebar compilation

- move src/apps
- download dependencies using rebar
- replace ejson by jiffy
- replace couch_drv & couch_ejson_compare by couch_collate


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

Branch: refs/heads/1994-merge-rcouch
Commit: 674800bbb8276db05f8f62cd971496acc5a46d10
Parents: 9f59339
Author: benoitc <be...@apache.org>
Authored: Mon Jan 6 21:12:45 2014 +0100
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Wed Feb 12 17:27:38 2014 -0600

----------------------------------------------------------------------
 src/couch_mrview.erl           | 2 +-
 src/couch_mrview_cleanup.erl   | 4 +---
 src/couch_mrview_compactor.erl | 4 ++--
 src/couch_mrview_http.erl      | 3 +--
 src/couch_mrview_index.erl     | 2 +-
 src/couch_mrview_show.erl      | 2 +-
 src/couch_mrview_test_util.erl | 3 ++-
 src/couch_mrview_updater.erl   | 2 +-
 src/couch_mrview_util.erl      | 2 +-
 9 files changed, 11 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/674800bb/src/couch_mrview.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview.erl b/src/couch_mrview.erl
index 2964fe9..d31ed18 100644
--- a/src/couch_mrview.erl
+++ b/src/couch_mrview.erl
@@ -18,7 +18,7 @@
 -export([compact/2, compact/3, cancel_compaction/2]).
 -export([cleanup/1]).
 
--include("couch_db.hrl").
+-include_lib("couch/include/couch_db.hrl").
 -include_lib("couch_mrview/include/couch_mrview.hrl").
 
 -record(mracc, {

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/674800bb/src/couch_mrview_cleanup.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_cleanup.erl b/src/couch_mrview_cleanup.erl
index d48de6f..c94b9f8 100644
--- a/src/couch_mrview_cleanup.erl
+++ b/src/couch_mrview_cleanup.erl
@@ -14,11 +14,9 @@
 
 -export([run/1]).
 
-
--include("couch_db.hrl").
+-include_lib("couch/include/couch_db.hrl").
 -include_lib("couch_mrview/include/couch_mrview.hrl").
 
-
 run(Db) ->
     RootDir = couch_index_util:root_dir(),
     DbName = couch_db:name(Db),

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/674800bb/src/couch_mrview_compactor.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_compactor.erl b/src/couch_mrview_compactor.erl
index fe718ca..4ab8dd1 100644
--- a/src/couch_mrview_compactor.erl
+++ b/src/couch_mrview_compactor.erl
@@ -12,7 +12,7 @@
 
 -module(couch_mrview_compactor).
 
--include("couch_db.hrl").
+-include_lib("couch/include/couch_db.hrl").
 -include_lib("couch_mrview/include/couch_mrview.hrl").
 
 -export([compact/3, swap_compacted/2]).
@@ -174,5 +174,5 @@ swap_compacted(OldState, NewState) ->
     unlink(OldState#mrst.fd),
     couch_ref_counter:drop(OldState#mrst.refc),
     {ok, NewRefCounter} = couch_ref_counter:start([NewState#mrst.fd]),
-    
+
     {ok, NewState#mrst{refc=NewRefCounter}}.

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/674800bb/src/couch_mrview_http.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_http.erl b/src/couch_mrview_http.erl
index 7b92034..22e0dc3 100644
--- a/src/couch_mrview_http.erl
+++ b/src/couch_mrview_http.erl
@@ -22,8 +22,7 @@
     parse_qs/2
 ]).
 
-
--include("couch_db.hrl").
+-include_lib("couch/include/couch_db.hrl").
 -include_lib("couch_mrview/include/couch_mrview.hrl").
 
 

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/674800bb/src/couch_mrview_index.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_index.erl b/src/couch_mrview_index.erl
index 7466dbc..7506f34 100644
--- a/src/couch_mrview_index.erl
+++ b/src/couch_mrview_index.erl
@@ -18,7 +18,7 @@
 -export([start_update/3, purge/4, process_doc/3, finish_update/1, commit/1]).
 -export([compact/3, swap_compacted/2]).
 
--include("couch_db.hrl").
+-include_lib("couch/include/couch_db.hrl").
 -include_lib("couch_mrview/include/couch_mrview.hrl").
 
 

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/674800bb/src/couch_mrview_show.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_show.erl b/src/couch_mrview_show.erl
index f8fa837..4ab8e17 100644
--- a/src/couch_mrview_show.erl
+++ b/src/couch_mrview_show.erl
@@ -18,7 +18,7 @@
     handle_view_list_req/3
 ]).
 
--include("couch_db.hrl").
+-include_lib("couch/include/couch_db.hrl").
 -include_lib("couch_mrview/include/couch_mrview.hrl").
 
 -record(lacc, {

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/674800bb/src/couch_mrview_test_util.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_test_util.erl b/src/couch_mrview_test_util.erl
index 338ae38..adc2675 100644
--- a/src/couch_mrview_test_util.erl
+++ b/src/couch_mrview_test_util.erl
@@ -14,7 +14,8 @@
 
 -compile(export_all).
 
--include("couch_db.hrl").
+-include_lib("couch/include/couch_db.hrl").
+
 -define(ADMIN, #user_ctx{roles=[<<"_admin">>]}).
 
 

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/674800bb/src/couch_mrview_updater.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_updater.erl b/src/couch_mrview_updater.erl
index 9604ea9..980b5cf 100644
--- a/src/couch_mrview_updater.erl
+++ b/src/couch_mrview_updater.erl
@@ -14,7 +14,7 @@
 
 -export([start_update/3, purge/4, process_doc/3, finish_update/1]).
 
--include("couch_db.hrl").
+-include_lib("couch/include/couch_db.hrl").
 -include_lib("couch_mrview/include/couch_mrview.hrl").
 
 

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/674800bb/src/couch_mrview_util.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_util.erl b/src/couch_mrview_util.erl
index c4272f8..f7946d1 100644
--- a/src/couch_mrview_util.erl
+++ b/src/couch_mrview_util.erl
@@ -28,7 +28,7 @@
 
 -define(MOD, couch_mrview_index).
 
--include("couch_db.hrl").
+-include_lib("couch/include/couch_db.hrl").
 -include_lib("couch_mrview/include/couch_mrview.hrl").
 
 


[07/25] couch-mrview commit: updated refs/heads/1994-merge-rcouch to 7775266

Posted by da...@apache.org.
couch_mrview: add view changes test

test view changes and fix errors.


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

Branch: refs/heads/1994-merge-rcouch
Commit: 3b6903e4cc0bdb0a039f817047646975f38b013d
Parents: 3d27c6b
Author: benoitc <be...@apache.org>
Authored: Mon Jan 27 17:24:54 2014 +0100
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Wed Feb 12 17:27:39 2014 -0600

----------------------------------------------------------------------
 src/couch_mrview_test_util.erl |  31 +++++++--
 src/couch_mrview_updater.erl   |   2 +-
 src/couch_mrview_util.erl      |  34 ++++++----
 test/08-changes_since.t        | 123 ++++++++++++++++++++++++++++++++++++
 4 files changed, 168 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/3b6903e4/src/couch_mrview_test_util.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_test_util.erl b/src/couch_mrview_test_util.erl
index adc2675..c67f24f 100644
--- a/src/couch_mrview_test_util.erl
+++ b/src/couch_mrview_test_util.erl
@@ -41,14 +41,31 @@ save_docs(Db, Docs) ->
 
 
 make_docs(Count) ->
-    make_docs(Count, []).
-
-make_docs(Count, Acc) when Count =< 0 ->
-    Acc;
-make_docs(Count, Acc) ->
-    make_docs(Count-1, [doc(Count) | Acc]).
-
+    [doc(I) || I <- lists:seq(1, Count)].
 
+ddoc(changes) ->
+    couch_doc:from_json_obj({[
+        {<<"_id">>, <<"_design/bar">>},
+        {<<"options">>, {[
+            {<<"seq_indexed">>, true}
+        ]}},
+        {<<"views">>, {[
+            {<<"baz">>, {[
+                {<<"map">>, <<"function(doc) {emit(doc.val, doc.val);}">>}
+            ]}},
+            {<<"bing">>, {[
+                {<<"map">>, <<"function(doc) {}">>}
+            ]}},
+            {<<"zing">>, {[
+                {<<"map">>, <<
+                    "function(doc) {\n"
+                    "  if(doc.foo !== undefined)\n"
+                    "    emit(doc.foo, 0);\n"
+                    "}"
+                >>}
+            ]}}
+        ]}}
+    ]});
 ddoc(map) ->
     couch_doc:from_json_obj({[
         {<<"_id">>, <<"_design/bar">>},

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/3b6903e4/src/couch_mrview_updater.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_updater.erl b/src/couch_mrview_updater.erl
index 58ee9d2..be1055c 100644
--- a/src/couch_mrview_updater.erl
+++ b/src/couch_mrview_updater.erl
@@ -280,7 +280,7 @@ write_kvs(State, UpdateSeq, ViewKVs, DocIdKeys, Log) ->
                 SToRem = couch_util:dict_find(ViewId, SeqsToRemove, []),
                 SToAdd = couch_util:dict_find(ViewId, SeqsToAdd, []),
                 RemSKs = [{Seq, Key} || {Key, Seq, _} <- SToRem],
-                RemKSs = [{[Seq, Key], DocId} || {Key, Seq, DocId} <- SToRem],
+                RemKSs = [{[Key, Seq], DocId} || {Key, Seq, DocId} <- SToRem],
                 SKVs1 = SKVs ++ SToAdd,
                 {ok, SBt} = couch_btree:add_remove(View#mrview.seq_btree,
                                                    SKVs1, RemSKs),

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/3b6903e4/src/couch_mrview_util.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_util.erl b/src/couch_mrview_util.erl
index 7c42de8..a98f042 100644
--- a/src/couch_mrview_util.erl
+++ b/src/couch_mrview_util.erl
@@ -229,13 +229,8 @@ init_state(Db, Fd, State, Header) ->
         views=Views2
     }.
 
-less_json_seqs({SeqA, JsonA}, {SeqB, JsonB}) ->
-    case couch_ejson_compare:less(SeqA, SeqB) of
-        0 ->
-            couch_ejson_compare:less_json(JsonA, JsonB);
-        Result ->
-            Result < 0
-    end.
+less_json_seqs({SeqA, _JsonA}, {SeqB, _JsonB}) ->
+    couch_ejson_compare:less(SeqA, SeqB) < 0.
 
 open_view(Db, Fd, Lang, {BTState, SeqBTState, KSeqBTState, USeq, PSeq}, View) ->
     FunSrcs = [FunSrc || {_Name, FunSrc} <- View#mrview.reduce_funs],
@@ -354,12 +349,23 @@ fold_fun(Fun, [KV|Rest], {KVReds, Reds}, Acc) ->
             {stop, Acc2}
     end.
 
+
 fold_changes(Bt, Fun, Acc, Opts) ->
     WrapperFun = fun(KV, _Reds, Acc2) ->
-        Fun(changes_expand_dups([KV], []), Acc2)
+        fold_changes_fun(Fun, changes_expand_dups([KV], []), Acc2)
     end,
     {ok, _LastRed, _Acc} = couch_btree:fold(Bt, WrapperFun, Acc, Opts).
 
+fold_changes_fun(_Fun, [], Acc) ->
+    {ok, Acc};
+fold_changes_fun(Fun, [KV|Rest],  Acc) ->
+    case Fun(KV, Acc) of
+        {ok, Acc2} ->
+            fold_changes_fun(Fun, Rest, Acc2);
+        {stop, Acc2} ->
+            {stop, Acc2}
+    end.
+
 
 fold_reduce({NthRed, Lang, View}, Fun,  Acc, Options) ->
     #mrview{
@@ -795,15 +801,15 @@ expand_dups([KV | Rest], Acc) ->
 changes_expand_dups([], Acc) ->
     lists:reverse(Acc);
 changes_expand_dups([{{[Key, Seq], DocId}, {dups, Vals}} | Rest], Acc) ->
-    Expanded = [{{Key, Seq, DocId}, Val} || Val <- Vals],
+    Expanded = [{{Seq, Key, DocId}, Val} || Val <- Vals],
     changes_expand_dups(Rest, Expanded ++ Acc);
-changes_expand_dups([{{Key, Seq}, {DocId, {dups, Vals}}} | Rest], Acc) ->
-    Expanded = [{{Key, Seq, DocId}, Val} || Val <- Vals],
+changes_expand_dups([{{Seq, Key}, {DocId, {dups, Vals}}} | Rest], Acc) ->
+    Expanded = [{{Seq, Key, DocId}, Val} || Val <- Vals],
     changes_expand_dups(Rest, Expanded ++ Acc);
 changes_expand_dups([{{[Key, Seq], DocId}, Val} | Rest], Acc) ->
-    changes_expand_dups(Rest, [{{Key, Seq, DocId}, Val} | Acc]);
-changes_expand_dups([{{Key, Seq}, {DocId, Val}} | Rest], Acc) ->
-    changes_expand_dups(Rest, [{{Key, Seq, DocId}, Val} | Acc]).
+    changes_expand_dups(Rest, [{{Seq, Key, DocId}, Val} | Acc]);
+changes_expand_dups([{{Seq, Key}, {DocId, Val}} | Rest], Acc) ->
+    changes_expand_dups(Rest, [{{Seq, Key, DocId}, Val} | Acc]).
 
 maybe_load_doc(_Db, _DI, #mrargs{include_docs=false}) ->
     [];

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/3b6903e4/test/08-changes_since.t
----------------------------------------------------------------------
diff --git a/test/08-changes_since.t b/test/08-changes_since.t
new file mode 100644
index 0000000..3127cff
--- /dev/null
+++ b/test/08-changes_since.t
@@ -0,0 +1,123 @@
+#!/usr/bin/env escript
+%% -*- erlang -*-
+%%! -pa ./deps/*/ebin -pa ./apps/*/ebin -pa ./test/etap
+
+% Licensed under the Apache License, Version 2.0 (the "License"); you may not
+% use this file except in compliance with the License. You may obtain a copy of
+% the License at
+%
+%   http://www.apache.org/licenses/LICENSE-2.0
+%
+% Unless required by applicable law or agreed to in writing, software
+% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+% License for the specific language governing permissions and limitations under
+% the License.
+
+main(_) ->
+    etap:plan(10),
+    case (catch test()) of
+        ok ->
+            etap:end_tests();
+        Other ->
+            etap:diag(io_lib:format("Test died abnormally: ~p", [Other])),
+            etap:bail(Other)
+    end,
+    timer:sleep(300),
+    ok.
+
+test() ->
+    test_util:start_couch(),
+
+    {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, changes),
+
+    test_basic(Db),
+    test_range(Db),
+    test_basic_since(Db),
+    test_range_since(Db),
+    test_basic_count(Db),
+    test_range_count(Db),
+    test_basic_count_since(Db),
+    test_range_count_since(Db),
+    test_compact(Db),
+    test_util:stop_couch(),
+    ok.
+
+
+test_basic(Db) ->
+    Result = run_query(Db, 0, []),
+    Expect = {ok, [
+                {{2, 1, <<"1">>}, 1},
+                {{3, 10, <<"10">>}, 10},
+                {{4, 2, <<"2">>}, 2},
+                {{5, 3, <<"3">>}, 3},
+                {{6, 4, <<"4">>}, 4},
+                {{7, 5, <<"5">>}, 5},
+                {{8, 6, <<"6">>}, 6},
+                {{9, 7, <<"7">>}, 7},
+                {{10, 8, <<"8">>}, 8},
+                {{11, 9, <<"9">>}, 9}
+    ]},
+    etap:is(Result, Expect, "Simple view query worked.").
+
+
+test_range(Db) ->
+    Result = run_query(Db, 0, [{start_key, 3}, {end_key, 5}]),
+    Expect = {ok, [
+                {{5, 3, <<"3">>}, 3},
+                {{6, 4, <<"4">>}, 4},
+                {{7, 5, <<"5">>}, 5}
+    ]},
+    etap:is(Result, Expect, "Query with range works.").
+
+test_basic_since(Db) ->
+    Result = run_query(Db, 5, []),
+    Expect = {ok, [
+                {{6, 4, <<"4">>}, 4},
+                {{7, 5, <<"5">>}, 5},
+                {{8, 6, <<"6">>}, 6},
+                {{9, 7, <<"7">>}, 7},
+                {{10, 8, <<"8">>}, 8},
+                {{11, 9, <<"9">>}, 9}
+    ]},
+    etap:is(Result, Expect, "Simple view query since 5 worked.").
+
+test_range_since(Db) ->
+    Result = run_query(Db, 5, [{start_key, 3}, {end_key, 5}]),
+    Expect = {ok, [
+                {{6, 4, <<"4">>}, 4},
+                {{7, 5, <<"5">>}, 5}
+    ]},
+    etap:is(Result, Expect, "Query with range since 5 works.").
+
+test_basic_count(Db) ->
+    Result = run_count_query(Db, 0, []),
+    etap:is(Result, 10, "Simple view count worked.").
+
+test_range_count(Db) ->
+    Result = run_count_query(Db, 0, [{start_key, 3}, {end_key, 5}]),
+    etap:is(Result, 3, "Count with range works.").
+
+test_basic_count_since(Db) ->
+    Result = run_count_query(Db, 5, []),
+    etap:is(Result, 6, "Simple view count since 5 worked.").
+
+test_range_count_since(Db) ->
+    Result = run_count_query(Db, 5, [{start_key, 3}, {end_key, 5}]),
+    etap:is(Result, 2, "Count with range since 5 works.").
+
+test_compact(Db) ->
+    Result = couch_mrview:compact(Db, <<"_design/bar">>),
+    etap:is(Result, ok, "compact view is OK"),
+    Count = run_count_query(Db, 0, []),
+    etap:is(Count, 10, "compact view worked.").
+
+run_query(Db, Since, Opts) ->
+    Fun = fun(KV, Acc) -> {ok, [KV | Acc]} end,
+    {ok, R} = couch_mrview:view_changes_since(Db, <<"_design/bar">>, <<"baz">>,
+                                              Since, Fun, Opts, []),
+    {ok, lists:reverse(R)}.
+
+run_count_query(Db, Since, Opts) ->
+    couch_mrview:count_view_changes_since(Db, <<"_design/bar">>, <<"baz">>,
+                                          Since, Opts).


[22/25] couch-mrview commit: updated refs/heads/1994-merge-rcouch to 7775266

Posted by da...@apache.org.
couch_index: add background indexing facility

This change add the possibility to trigger a view indexation in
background. The indexation can only work in background if at least one
process acquired it using the `couch_index_server:acquire_index/3`
function. If all the process that acquired it are down or released it
using `couch_index_server:release_indexer/3` then the background task is
stopped.

By default the background indexation will happen every 1s or when 200
docs has been saved in the database. These parameters can be changed
using the options `threshold` and `refresh_interval` in the couch_index
section.

To use it with couch_mrview a new option {refresh, true} has been added
to couch_mrview_changes:handle_changes Also the query parameter
refresh=true is passsed in t the HTTP changes API.


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

Branch: refs/heads/1994-merge-rcouch
Commit: 76a7d60f769ad38a70317e01620bcc7a5a9ffb21
Parents: 53b8373
Author: benoitc <be...@apache.org>
Authored: Sat Feb 8 19:55:40 2014 +0100
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Wed Feb 12 17:27:40 2014 -0600

----------------------------------------------------------------------
 src/couch_mrview_changes.erl | 56 ++++++++++++++++++++++++++++-----------
 test/10-index-changes.t      | 17 +++++++++++-
 2 files changed, 56 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/76a7d60f/src/couch_mrview_changes.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_changes.erl b/src/couch_mrview_changes.erl
index a0e5281..c31624e 100644
--- a/src/couch_mrview_changes.erl
+++ b/src/couch_mrview_changes.erl
@@ -28,14 +28,16 @@
               heartbeat,
               timeout_acc=0,
               notifier,
-              stream}).
+              stream,
+              refresh}).
 
 -type changes_stream() :: true | false | once.
 -type changes_options() :: [{stream, changes_stream()} |
                             {since, integer()} |
                             {view_options, list()} |
                             {timeout, integer()} |
-                            {heartbeat, true | integer()}].
+                            {heartbeat, true | integer()} |
+                            {refresh, true | false}].
 
 -export_type([changes_stream/0]).
 -export_type([changes_options/0]).
@@ -47,6 +49,7 @@ handle_changes(DbName, DDocId, View, Fun, Acc, Options) ->
     Since = proplists:get_value(since, Options, 0),
     Stream = proplists:get_value(stream, Options, false),
     ViewOptions = proplists:get_value(view_options, Options, []),
+    Refresh = proplists:get_value(refresh, Options, false),
 
     State0 = #vst{dbname=DbName,
                   ddoc=DDocId,
@@ -56,20 +59,25 @@ handle_changes(DbName, DDocId, View, Fun, Acc, Options) ->
                   callback=Fun,
                   acc=Acc},
 
-    case view_changes_since(State0) of
-        {ok, #vst{since=LastSeq, acc=Acc2}=State} ->
-            case Stream of
-                true ->
-                    start_loop(State#vst{stream=true}, Options);
-                once when LastSeq =:= Since ->
-                    start_loop(State#vst{stream=once}, Options);
-                _ ->
-                    Fun(stop, {LastSeq, Acc2})
-            end;
-        {stop, #vst{since=LastSeq, acc=Acc2}} ->
-            Fun(stop, {LastSeq, Acc2});
-        Error ->
-            Error
+    maybe_acquire_indexer(Refresh, DbName, DDocId),
+    try
+        case view_changes_since(State0) of
+            {ok, #vst{since=LastSeq, acc=Acc2}=State} ->
+                case Stream of
+                    true ->
+                        start_loop(State#vst{stream=true}, Options);
+                    once when LastSeq =:= Since ->
+                        start_loop(State#vst{stream=once}, Options);
+                    _ ->
+                        Fun(stop, {LastSeq, Acc2})
+                end;
+            {stop, #vst{since=LastSeq, acc=Acc2}} ->
+                Fun(stop, {LastSeq, Acc2});
+            Error ->
+                Error
+        end
+    after
+        maybe_release_indexer(Refresh, DbName, DDocId)
     end.
 
 start_loop(#vst{dbname=DbName, ddoc=DDocId}=State, Options) ->
@@ -169,3 +177,19 @@ index_update_notifier(DbName, DDocId) ->
                     ok
             end),
     NotifierPid.
+
+%% acquire the background indexing task so it can eventually be started
+%% if the process close the background task will be automatically
+%% released.
+maybe_acquire_indexer(false, _, _) ->
+    ok;
+maybe_acquire_indexer(true, DbName, DDocId) ->
+    couch_index_server:acquire_indexer(couch_mrview_index, DbName,
+                                       DDocId).
+
+%% release the background indexing task so it can eventually be stopped
+maybe_release_indexer(false, _, _) ->
+    ok;
+maybe_release_indexer(true, DbName, DDocId) ->
+    couch_index_server:release_indexer(couch_mrview_index, DbName,
+                                       DDocId).

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/76a7d60f/test/10-index-changes.t
----------------------------------------------------------------------
diff --git a/test/10-index-changes.t b/test/10-index-changes.t
index 627376f..f53e9ed 100644
--- a/test/10-index-changes.t
+++ b/test/10-index-changes.t
@@ -15,7 +15,7 @@
 % the License.
 
 main(_) ->
-    etap:plan(6),
+    etap:plan(8),
     case (catch test()) of
         ok ->
             etap:end_tests();
@@ -35,6 +35,7 @@ test() ->
     test_stream_once_timeout(Db),
     test_stream_once_heartbeat(Db),
     test_stream(Db),
+    test_indexer(Db),
     test_util:stop_couch(),
     ok.
 
@@ -173,6 +174,20 @@ test_stream(Db) ->
     end.
 
 
+test_indexer(Db) ->
+    Result = run_query(Db, [{since, 14}]),
+    Expect = {ok, 15, [{{15,14,<<"14">>},14}]},
+    etap:is(Result, Expect, "refresh index by hand OK."),
+
+    {ok, Db1} = save_doc(Db, 15),
+    timer:sleep(1000),
+    Result1 = run_query(Db, [{since, 14}]),
+    Expect1 = {ok, 16, [{{15,14,<<"14">>},14},
+                       {{16,15,<<"15">>},15}]},
+    etap:is(Result1, Expect1, "changes indexed in background OK."),
+    ok.
+
+
 save_doc(Db, Id) ->
     Doc = couch_mrview_test_util:doc(Id),
     {ok, _Rev} = couch_db:update_doc(Db, Doc, []),


[21/25] couch-mrview commit: updated refs/heads/1994-merge-rcouch to 7775266

Posted by da...@apache.org.
couch_mrview: add API to retrieve view info.

Add couch_mrview:get_view_info/3 to retrieve the internal informations
of a view like the last update seq in this view or the number of rows.


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

Branch: refs/heads/1994-merge-rcouch
Commit: 916e1b3c902c52f2a98c20a0bc1800d76f11e91a
Parents: 96aa28d
Author: benoitc <be...@apache.org>
Authored: Sat Feb 8 22:49:42 2014 +0100
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Wed Feb 12 17:27:40 2014 -0600

----------------------------------------------------------------------
 src/couch_mrview.erl | 25 +++++++++++++++++++++++++
 test/04-index-info.t | 10 +++++++++-
 2 files changed, 34 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/916e1b3c/src/couch_mrview.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview.erl b/src/couch_mrview.erl
index 26538a2..e5b0d99 100644
--- a/src/couch_mrview.erl
+++ b/src/couch_mrview.erl
@@ -17,6 +17,7 @@
 -export([view_changes_since/6, view_changes_since/7]).
 -export([count_view_changes_since/4, count_view_changes_since/5]).
 -export([get_info/2]).
+-export([get_view_info/3]).
 -export([refresh/2]).
 -export([compact/2, compact/3, cancel_compaction/2]).
 -export([cleanup/1]).
@@ -147,6 +148,30 @@ get_info(Db, DDoc) ->
     couch_index:get_info(Pid).
 
 
+%% get informations on a view
+get_view_info(Db, DDoc, VName) ->
+    {ok, {_, View}, _, _Args} = couch_mrview_util:get_view(Db, DDoc, VName,
+                                                          #mrargs{}),
+
+    %% get the total number of rows
+    {ok, TotalRows} =  couch_mrview_util:get_row_count(View),
+
+    %% get the total number of sequence logged in this view
+    SeqBtree = View#mrview.seq_btree,
+    {ok, TotalSeqs} = case SeqBtree of
+        nil -> {ok, 0};
+        _ ->
+            {ok, {Count, _Reds}} = couch_btree:full_reduce(SeqBtree),
+            {ok, Count}
+    end,
+
+    {ok, [{update_seq, View#mrview.update_seq},
+          {purge_seq, View#mrview.purge_seq},
+          {total_rows, TotalRows},
+          {total_seqs, TotalSeqs}]}.
+
+
+
 %% @doc refresh a view index
 refresh(#db{name=DbName}, DDoc) ->
     refresh(DbName, DDoc);

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/916e1b3c/test/04-index-info.t
----------------------------------------------------------------------
diff --git a/test/04-index-info.t b/test/04-index-info.t
index 34fb192..e95db1c 100644
--- a/test/04-index-info.t
+++ b/test/04-index-info.t
@@ -15,7 +15,7 @@
 % the License.
 
 main(_) ->
-    etap:plan(9),
+    etap:plan(12),
     case (catch test()) of
         ok ->
             etap:end_tests();
@@ -46,6 +46,14 @@ test() ->
     etap:is(getval(compact_running, Info), false, "No compaction running."),
     etap:is(getval(waiting_clients, Info), 0, "No waiting clients."),
 
+
+    {ok, ViewInfo} = couch_mrview:get_view_info(Db, <<"_design/bar">>,
+                                           <<"baz">>),
+    etap:is(getval(update_seq, ViewInfo), 11, "View Update seq is ok."),
+    etap:is(getval(purge_seq, ViewInfo), 0, "View Update seq is ok."),
+    etap:is(getval(total_rows, ViewInfo), 10, "View total rows is ok."),
+
+
     test_util:stop_couch(),
     ok.
 


[18/25] couch-mrview commit: updated refs/heads/1994-merge-rcouch to 7775266

Posted by da...@apache.org.
add supports of view changes in the _changes API

Now when the option `seq_indexed=true` is set in the design doc, the
view filter in _changes will use it to retrieve the results. Compared to
the current way, using a view index will be faster to retrieve changes.
It also gives the possibility to filter changes by key or get changes in
a key range. All the view options can be used.

Note 1: if someone is trying to filter a changes with view options when
the views are not indexed by sequence, a 400 error will be returned.
Note 2: The changes will only be returned when the view is updated if
seq_indexed=true


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

Branch: refs/heads/1994-merge-rcouch
Commit: 53b837326f4abf84a74e2905fd1aa9da9cccbc50
Parents: 01355fd
Author: benoitc <bc...@gmail.com>
Authored: Fri Feb 7 15:38:34 2014 +0100
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Wed Feb 12 17:27:40 2014 -0600

----------------------------------------------------------------------
 src/couch_mrview_changes.erl |  6 ++----
 src/couch_mrview_http.erl    | 12 ++++++++++--
 src/couch_mrview_index.erl   | 21 ++++++++++++++++++---
 test/09-index-events.t       | 21 +++++++++++++++++----
 4 files changed, 47 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/53b83732/src/couch_mrview_changes.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_changes.erl b/src/couch_mrview_changes.erl
index 2b8f910..a0e5281 100644
--- a/src/couch_mrview_changes.erl
+++ b/src/couch_mrview_changes.erl
@@ -141,10 +141,8 @@ view_changes_since(#vst{dbname=DbName, ddoc=DDocId, view=View,
                 true -> OldSeq
             end,
 
-            case Callback(KV, Acc2) of
-                {ok, Acc3} -> {ok, {Go, Acc3, LastSeq}};
-                {stop, Acc3} -> {stop, {stop, Acc3, LastSeq}}
-            end
+            {Go, Acc3} = Callback(KV, Acc2),
+            {Go, {Go, Acc3, LastSeq}}
     end,
 
     Acc0 = {ok, UserAcc, Since},

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/53b83732/src/couch_mrview_http.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_http.erl b/src/couch_mrview_http.erl
index 22e0dc3..4801e27 100644
--- a/src/couch_mrview_http.erl
+++ b/src/couch_mrview_http.erl
@@ -22,6 +22,10 @@
     parse_qs/2
 ]).
 
+-export([parse_boolean/1,
+         parse_int/1,
+         parse_pos_int/1]).
+
 -include_lib("couch/include/couch_db.hrl").
 -include_lib("couch_mrview/include/couch_mrview.hrl").
 
@@ -378,6 +382,10 @@ parse_qs(Key, Val, Args) ->
     end.
 
 
+parse_boolean(true) ->
+    true;
+parse_boolean(false) ->
+    false;
 parse_boolean(Val) ->
     case string:to_lower(Val) of
     "true" -> true;
@@ -387,7 +395,8 @@ parse_boolean(Val) ->
         throw({query_parse_error, ?l2b(Msg)})
     end.
 
-
+parse_int(Val) when is_integer(Val) ->
+    Val;
 parse_int(Val) ->
     case (catch list_to_integer(Val)) of
     IntVal when is_integer(IntVal) ->
@@ -397,7 +406,6 @@ parse_int(Val) ->
         throw({query_parse_error, ?l2b(Msg)})
     end.
 
-
 parse_pos_int(Val) ->
     case parse_int(Val) of
     IntVal when IntVal >= 0 ->

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/53b83732/src/couch_mrview_index.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_index.erl b/src/couch_mrview_index.erl
index 0835f44..5f5ae88 100644
--- a/src/couch_mrview_index.erl
+++ b/src/couch_mrview_index.erl
@@ -38,8 +38,10 @@ get(Property, State) ->
             Opts = State#mrst.design_opts,
             IncDesign = couch_util:get_value(<<"include_design">>, Opts, false),
             LocalSeq = couch_util:get_value(<<"local_seq">>, Opts, false),
+            SeqIndexed = couch_util:get_value(<<"seq_indexed">>, Opts, false),
             if IncDesign -> [include_design]; true -> [] end
-                ++ if LocalSeq -> [local_seq]; true -> [] end;
+                ++ if LocalSeq -> [local_seq]; true -> [] end
+                ++ if SeqIndexed -> [seq_indexed]; true -> [] end;
         info ->
             #mrst{
                 fd = Fd,
@@ -49,19 +51,32 @@ get(Property, State) ->
                 language = Lang,
                 update_seq = UpdateSeq,
                 purge_seq = PurgeSeq,
-                views = Views
+                views = Views,
+                design_opts = Opts
             } = State,
             {ok, Size} = couch_file:bytes(Fd),
             {ok, DataSize} = couch_mrview_util:calculate_data_size(IdBtree,
                                                                    LogBtree,
                                                                    Views),
+
+
+            IncDesign = couch_util:get_value(<<"include_design">>, Opts, false),
+            LocalSeq = couch_util:get_value(<<"local_seq">>, Opts, false),
+            SeqIndexed = couch_util:get_value(<<"seq_indexed">>, Opts, false),
+            UpdateOptions =
+                if IncDesign -> [<<"include_design">>]; true -> [] end
+                ++ if LocalSeq -> [<<"local_seq">>]; true -> [] end
+                ++ if SeqIndexed -> [<<"seq_indexed">>]; true -> [] end,
+
+
             {ok, [
                 {signature, list_to_binary(couch_index_util:hexsig(Sig))},
                 {language, Lang},
                 {disk_size, Size},
                 {data_size, DataSize},
                 {update_seq, UpdateSeq},
-                {purge_seq, PurgeSeq}
+                {purge_seq, PurgeSeq},
+                {update_options, UpdateOptions}
             ]};
         Other ->
             throw({unknown_index_property, Other})

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/53b83732/test/09-index-events.t
----------------------------------------------------------------------
diff --git a/test/09-index-events.t b/test/09-index-events.t
index 1489e4e..6cc1e9c 100644
--- a/test/09-index-events.t
+++ b/test/09-index-events.t
@@ -15,7 +15,7 @@
 % the License.
 
 main(_) ->
-    etap:plan(4),
+    etap:plan(5),
     case (catch test()) of
         ok ->
             etap:end_tests();
@@ -29,11 +29,18 @@ main(_) ->
 test() ->
     test_util:start_couch(),
     {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, changes),
+    test_info(Db),
     test_update_event(Db),
     test_delete_event(Db),
     test_util:stop_couch(),
     ok.
 
+test_info(Db) ->
+    {ok, Info} = couch_mrview:get_info(Db, <<"_design/bar">>),
+    etap:is(getval(update_options, Info), [<<"seq_indexed">>],
+            "update options OK"),
+    ok.
+
 test_update_event(Db) ->
     {ok, Pid} = couch_index_event:start_link(self()),
     etap:ok(is_pid(Pid), "event handler added"),
@@ -47,11 +54,13 @@ test_update_event(Db) ->
     couch_index_event:stop(Pid).
 
 test_delete_event(Db) ->
-     ok = couch_mrview:refresh(Db, <<"_design/bar">>),
+    ok = couch_mrview:refresh(Db, <<"_design/bar">>),
+    timer:sleep(300),
     {ok, Pid} = couch_index_event:start_link(self()),
+    etap:ok(is_pid(Pid), "delete event handler added"),
 
-    etap:ok(is_pid(Pid), "event handler added"),
-    couch_mrview_test_util:delete_db(<<"foo">>),
+
+    catch couch_mrview_test_util:delete_db(<<"foo">>),
     Expect = {index_delete, {<<"foo">>, <<"_design/bar">>,
                              couch_mrview_index}},
     receive
@@ -59,3 +68,7 @@ test_delete_event(Db) ->
             etap:is(Event, Expect, "index delete events OK")
     end,
     couch_index_event:stop(Pid).
+
+getval(Key, PL) ->
+    {value, {Key, Val}} = lists:keysearch(Key, 1, PL),
+    Val.


[14/25] couch-mrview commit: updated refs/heads/1994-merge-rcouch to 7775266

Posted by da...@apache.org.
make couch_httpd a full couch application

With this change, the HTTP API is now handled by its own erlang
application and supervision. It also improved the way you can reload the
configuration and the modules. Now upgrading a listener or its
configuration is first removing it from the supervsion then start the
new process with the new configuration. This behaviour is similar to the
one you have in nginx.


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

Branch: refs/heads/1994-merge-rcouch
Commit: f53c063d2e1cdc6082059d7a0e3dd34c3373b5c0
Parents: 7d5f765
Author: benoitc <be...@apache.org>
Authored: Sat Jan 11 11:20:27 2014 +0100
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Wed Feb 12 17:27:39 2014 -0600

----------------------------------------------------------------------
 test/02-map-views.t    | 1 +
 test/03-red-views.t    | 2 +-
 test/04-index-info.t   | 1 +
 test/05-collation.t    | 1 +
 test/06-all-docs.t     | 1 +
 test/07-compact-swap.t | 1 +
 6 files changed, 6 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/f53c063d/test/02-map-views.t
----------------------------------------------------------------------
diff --git a/test/02-map-views.t b/test/02-map-views.t
index 567042d..98d6a8f 100644
--- a/test/02-map-views.t
+++ b/test/02-map-views.t
@@ -30,6 +30,7 @@ main(_) ->
 
 test() ->
     couch_server_sup:start_link(test_util:config_files()),
+    couch_httpd_sup:start_link(),
     {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, map),
 
     test_basic(Db),

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/f53c063d/test/03-red-views.t
----------------------------------------------------------------------
diff --git a/test/03-red-views.t b/test/03-red-views.t
index 7f52f75..e478521 100644
--- a/test/03-red-views.t
+++ b/test/03-red-views.t
@@ -20,7 +20,7 @@ main(_) ->
 
 test() ->
     couch_server_sup:start_link(test_util:config_files()),
-
+    couch_httpd_sup:start_link(),
     {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, red),
 
     test_basic(Db),

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/f53c063d/test/04-index-info.t
----------------------------------------------------------------------
diff --git a/test/04-index-info.t b/test/04-index-info.t
index 834b7d2..3f47436 100644
--- a/test/04-index-info.t
+++ b/test/04-index-info.t
@@ -32,6 +32,7 @@ sig() -> <<"276df562b152b3c4e5d34024f62672ed">>.
 
 test() ->
     couch_server_sup:start_link(test_util:config_files()),
+    couch_httpd_sup:start_link(),
 
     {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, map),
     couch_mrview:query_view(Db, <<"_design/bar">>, <<"baz">>),

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/f53c063d/test/05-collation.t
----------------------------------------------------------------------
diff --git a/test/05-collation.t b/test/05-collation.t
index f98e88d..f0c4f0d 100644
--- a/test/05-collation.t
+++ b/test/05-collation.t
@@ -20,6 +20,7 @@ main(_) ->
 
 test() ->
     couch_server_sup:start_link(test_util:config_files()),
+    couch_httpd_sup:start_link(),
 
     {ok, Db0} = couch_mrview_test_util:new_db(<<"foo">>, map),
     {ok, Db1} = couch_mrview_test_util:save_docs(Db0, docs()),

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/f53c063d/test/06-all-docs.t
----------------------------------------------------------------------
diff --git a/test/06-all-docs.t b/test/06-all-docs.t
index 370825e..3a08b59 100644
--- a/test/06-all-docs.t
+++ b/test/06-all-docs.t
@@ -20,6 +20,7 @@ main(_) ->
 
 test() ->
     couch_server_sup:start_link(test_util:config_files()),
+    couch_httpd_sup:start_link(),
 
     {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, map),
 

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/f53c063d/test/07-compact-swap.t
----------------------------------------------------------------------
diff --git a/test/07-compact-swap.t b/test/07-compact-swap.t
index f7ebca2..9185a19 100644
--- a/test/07-compact-swap.t
+++ b/test/07-compact-swap.t
@@ -21,6 +21,7 @@ main(_) ->
 
 test() ->
     couch_server_sup:start_link(test_util:config_files()),
+    couch_httpd_sup:start_link(),
 
     {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, map, 1000),
     couch_mrview:query_view(Db, <<"_design/bar">>, <<"baz">>),


[06/25] couch-mrview commit: updated refs/heads/1994-merge-rcouch to 7775266

Posted by da...@apache.org.
add `make test` target . all erlang test pass

note: from time to time there is a timing issue on 200- test that need
to be fixed. It is most probably due to the way the indexer is
supervised.


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

Branch: refs/heads/1994-merge-rcouch
Commit: 145ef45d2227df8affd94110929a1c15cafb245b
Parents: 866ed59
Author: benoitc <be...@apache.org>
Authored: Thu Jan 9 16:24:32 2014 +0100
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Wed Feb 12 17:27:39 2014 -0600

----------------------------------------------------------------------
 test/01-load.t         | 1 +
 test/02-map-views.t    | 2 ++
 test/03-red-views.t    | 3 +++
 test/04-index-info.t   | 2 ++
 test/05-collation.t    | 3 +++
 test/06-all-docs.t     | 2 ++
 test/07-compact-swap.t | 8 ++++++--
 7 files changed, 19 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/145ef45d/test/01-load.t
----------------------------------------------------------------------
diff --git a/test/01-load.t b/test/01-load.t
index a57c1a7..ae66525 100644
--- a/test/01-load.t
+++ b/test/01-load.t
@@ -1,5 +1,6 @@
 #!/usr/bin/env escript
 %% -*- erlang -*-
+%%! -pa ./src/deps/*/ebin -pa ./src/apps/*/ebin -pa ./src/test/etap
 
 % Licensed under the Apache License, Version 2.0 (the "License"); you may not
 % use this file except in compliance with the License. You may obtain a copy of

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/145ef45d/test/02-map-views.t
----------------------------------------------------------------------
diff --git a/test/02-map-views.t b/test/02-map-views.t
index 7e1ca0c..ed1b1cc 100644
--- a/test/02-map-views.t
+++ b/test/02-map-views.t
@@ -1,5 +1,6 @@
 #!/usr/bin/env escript
 %% -*- erlang -*-
+%%! -pa ./src/deps/*/ebin -pa ./src/apps/*/ebin -pa ./src/test/etap
 
 % Licensed under the Apache License, Version 2.0 (the "License"); you may not
 % use this file except in compliance with the License. You may obtain a copy of
@@ -29,6 +30,7 @@ main(_) ->
 
 test() ->
     couch_server_sup:start_link(test_util:config_files()),
+    couch_index_sup:start_link(),
 
     {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, map),
 

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/145ef45d/test/03-red-views.t
----------------------------------------------------------------------
diff --git a/test/03-red-views.t b/test/03-red-views.t
index 6ad341b..17b9148 100644
--- a/test/03-red-views.t
+++ b/test/03-red-views.t
@@ -1,5 +1,7 @@
 #!/usr/bin/env escript
 %% -*- erlang -*-
+%%! -pa ./src/deps/*/ebin -pa ./src/apps/*/ebin -pa ./src/test/etap
+
 
 % Licensed under the Apache License, Version 2.0 (the "License"); you may not
 % use this file except in compliance with the License. You may obtain a copy of
@@ -18,6 +20,7 @@ main(_) ->
 
 test() ->
     couch_server_sup:start_link(test_util:config_files()),
+    couch_index_sup:start_link(),
 
     {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, red),
 

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/145ef45d/test/04-index-info.t
----------------------------------------------------------------------
diff --git a/test/04-index-info.t b/test/04-index-info.t
index 6b67b56..73c4dcc 100644
--- a/test/04-index-info.t
+++ b/test/04-index-info.t
@@ -1,5 +1,6 @@
 #!/usr/bin/env escript
 %% -*- erlang -*-
+%%! -pa ./src/deps/*/ebin -pa ./src/apps/*/ebin -pa ./src/test/etap
 
 % Licensed under the Apache License, Version 2.0 (the "License"); you may not
 % use this file except in compliance with the License. You may obtain a copy of
@@ -31,6 +32,7 @@ sig() -> <<"276df562b152b3c4e5d34024f62672ed">>.
 
 test() ->
     couch_server_sup:start_link(test_util:config_files()),
+    couch_index_sup:start_link(),
 
     {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, map),
     couch_mrview:query_view(Db, <<"_design/bar">>, <<"baz">>),

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/145ef45d/test/05-collation.t
----------------------------------------------------------------------
diff --git a/test/05-collation.t b/test/05-collation.t
index ac8f8bc..d476601 100644
--- a/test/05-collation.t
+++ b/test/05-collation.t
@@ -1,5 +1,6 @@
 #!/usr/bin/env escript
 %% -*- erlang -*-
+%%! -pa ./src/deps/*/ebin -pa ./src/apps/*/ebin -pa ./src/test/etap
 
 % Licensed under the Apache License, Version 2.0 (the "License"); you may not
 % use this file except in compliance with the License. You may obtain a copy of
@@ -19,6 +20,8 @@ main(_) ->
 
 test() ->
     couch_server_sup:start_link(test_util:config_files()),
+    couch_index_sup:start_link(),
+
     {ok, Db0} = couch_mrview_test_util:new_db(<<"foo">>, map),
     {ok, Db1} = couch_mrview_test_util:save_docs(Db0, docs()),
 

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/145ef45d/test/06-all-docs.t
----------------------------------------------------------------------
diff --git a/test/06-all-docs.t b/test/06-all-docs.t
index 4501aa5..a19cd7e 100644
--- a/test/06-all-docs.t
+++ b/test/06-all-docs.t
@@ -1,5 +1,6 @@
 #!/usr/bin/env escript
 %% -*- erlang -*-
+%%! -pa ./src/deps/*/ebin -pa ./src/apps/*/ebin -pa ./src/test/etap
 
 % Licensed under the Apache License, Version 2.0 (the "License"); you may not
 % use this file except in compliance with the License. You may obtain a copy of
@@ -19,6 +20,7 @@ main(_) ->
 
 test() ->
     couch_server_sup:start_link(test_util:config_files()),
+    couch_index_sup:start_link(),
 
     {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, map),
 

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/145ef45d/test/07-compact-swap.t
----------------------------------------------------------------------
diff --git a/test/07-compact-swap.t b/test/07-compact-swap.t
index 4bfe124..a74d273 100644
--- a/test/07-compact-swap.t
+++ b/test/07-compact-swap.t
@@ -1,5 +1,7 @@
 #!/usr/bin/env escript
 %% -*- erlang -*-
+%%! -pa ./src/deps/*/ebin -pa ./src/apps/*/ebin -pa ./src/test/etap
+
 
 % Licensed under the Apache License, Version 2.0 (the "License"); you may not
 % use this file except in compliance with the License. You may obtain a copy of
@@ -19,6 +21,8 @@ main(_) ->
 
 test() ->
     couch_server_sup:start_link(test_util:config_files()),
+    couch_index_sup:start_link(),
+
     {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, map, 1000),
     couch_mrview:query_view(Db, <<"_design/bar">>, <<"baz">>),
     test_swap(Db),
@@ -26,7 +30,7 @@ test() ->
 
 
 test_swap(Db) ->
-    {ok, QPid} = start_query(Db),    
+    {ok, QPid} = start_query(Db),
     {ok, MonRef} = couch_mrview:compact(Db, <<"_design/bar">>, [monitor]),
     receive
         {'DOWN', MonRef, process, _, _} -> ok
@@ -50,7 +54,7 @@ start_query(Db) ->
             ({row, _}, Count) -> {ok, Count+1};
             (_, Count) -> {ok, Count}
         end,
-        {ok, Result} = 
+        {ok, Result} =
         couch_mrview:query_view(Db, <<"_design/bar">>, <<"baz">>, [], CB, wait),
         Self ! {self(), Result}
     end),


[16/25] couch-mrview commit: updated refs/heads/1994-merge-rcouch to 7775266

Posted by da...@apache.org.
start and stop the application correctly


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

Branch: refs/heads/1994-merge-rcouch
Commit: 5c5c5cf2336061c97f1646a3cf4cb798ae178fe3
Parents: 0ce0e96
Author: benoitc <be...@apache.org>
Authored: Mon Jan 13 22:30:39 2014 +0100
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Wed Feb 12 17:27:39 2014 -0600

----------------------------------------------------------------------
 test/02-map-views.t    | 7 +++----
 test/03-red-views.t    | 5 +++--
 test/04-index-info.t   | 6 ++----
 test/05-collation.t    | 4 ++--
 test/06-all-docs.t     | 4 ++--
 test/07-compact-swap.t | 5 +++--
 6 files changed, 15 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/5c5c5cf2/test/02-map-views.t
----------------------------------------------------------------------
diff --git a/test/02-map-views.t b/test/02-map-views.t
index 3b55462..4f87193 100644
--- a/test/02-map-views.t
+++ b/test/02-map-views.t
@@ -15,8 +15,6 @@
 % the License.
 
 main(_) ->
-    test_util:init_code_path(),
-
     etap:plan(6),
     case (catch test()) of
         ok ->
@@ -29,8 +27,8 @@ main(_) ->
     ok.
 
 test() ->
-    couch_server_sup:start_link(test_util:config_files()),
-    couch_httpd_sup:start_link(),
+    test_util:start_couch(),
+
     {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, map),
 
     test_basic(Db),
@@ -40,6 +38,7 @@ test() ->
     test_include_docs(Db),
     test_empty_view(Db),
 
+    test_util:stop_couch(),
     ok.
 
 

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/5c5c5cf2/test/03-red-views.t
----------------------------------------------------------------------
diff --git a/test/03-red-views.t b/test/03-red-views.t
index 9491882..594fdfd 100644
--- a/test/03-red-views.t
+++ b/test/03-red-views.t
@@ -19,8 +19,8 @@ main(_) ->
     test_util:run(4, fun() -> test() end).
 
 test() ->
-    couch_server_sup:start_link(test_util:config_files()),
-    couch_httpd_sup:start_link(),
+    test_util:start_couch(),
+
     {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, red),
 
     test_basic(Db),
@@ -28,6 +28,7 @@ test() ->
     test_group_level(Db),
     test_group_exact(Db),
 
+    test_util:stop_couch(),
     ok.
 
 

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/5c5c5cf2/test/04-index-info.t
----------------------------------------------------------------------
diff --git a/test/04-index-info.t b/test/04-index-info.t
index 8ed6170..d7e1de1 100644
--- a/test/04-index-info.t
+++ b/test/04-index-info.t
@@ -15,8 +15,6 @@
 % the License.
 
 main(_) ->
-    test_util:init_code_path(),
-
     etap:plan(9),
     case (catch test()) of
         ok ->
@@ -31,8 +29,7 @@ main(_) ->
 sig() -> <<"276df562b152b3c4e5d34024f62672ed">>.
 
 test() ->
-    couch_server_sup:start_link(test_util:config_files()),
-    couch_httpd_sup:start_link(),
+    test_util:start_couch(),
 
     {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, map),
     couch_mrview:query_view(Db, <<"_design/bar">>, <<"baz">>),
@@ -49,6 +46,7 @@ test() ->
     etap:is(getval(compact_running, Info), false, "No compaction running."),
     etap:is(getval(waiting_clients, Info), 0, "No waiting clients."),
 
+    test_util:stop_couch(),
     ok.
 
 getval(Key, PL) ->

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/5c5c5cf2/test/05-collation.t
----------------------------------------------------------------------
diff --git a/test/05-collation.t b/test/05-collation.t
index 4c13bb7..1ebbe9c 100644
--- a/test/05-collation.t
+++ b/test/05-collation.t
@@ -19,8 +19,7 @@ main(_) ->
 
 
 test() ->
-    couch_server_sup:start_link(test_util:config_files()),
-    couch_httpd_sup:start_link(),
+    test_util:start_couch(),
 
     {ok, Db0} = couch_mrview_test_util:new_db(<<"foo">>, map),
     {ok, Db1} = couch_mrview_test_util:save_docs(Db0, docs()),
@@ -32,6 +31,7 @@ test() ->
     test_uninclusive_end(Db1),
     test_with_endkey_docid(Db1),
 
+    test_util:stop_couch(),
     ok.
 
 test_collated_fwd(Db) ->

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/5c5c5cf2/test/06-all-docs.t
----------------------------------------------------------------------
diff --git a/test/06-all-docs.t b/test/06-all-docs.t
index a031f58..0916568 100644
--- a/test/06-all-docs.t
+++ b/test/06-all-docs.t
@@ -19,8 +19,7 @@ main(_) ->
 
 
 test() ->
-    couch_server_sup:start_link(test_util:config_files()),
-    couch_httpd_sup:start_link(),
+    test_util:start_couch(),
 
     {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, map),
 
@@ -31,6 +30,7 @@ test() ->
     test_include_docs(Db),
     test_empty_view(Db),
 
+    test_util:stop_couch(),
     ok.
 
 

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/5c5c5cf2/test/07-compact-swap.t
----------------------------------------------------------------------
diff --git a/test/07-compact-swap.t b/test/07-compact-swap.t
index 34a5fb7..ba8e438 100644
--- a/test/07-compact-swap.t
+++ b/test/07-compact-swap.t
@@ -20,12 +20,13 @@ main(_) ->
 
 
 test() ->
-    couch_server_sup:start_link(test_util:config_files()),
-    couch_httpd_sup:start_link(),
+    test_util:start_couch(),
 
     {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, map, 1000),
     couch_mrview:query_view(Db, <<"_design/bar">>, <<"baz">>),
     test_swap(Db),
+
+    test_util:stop_couch(),
     ok.
 
 


[25/25] couch-mrview commit: updated refs/heads/1994-merge-rcouch to 7775266

Posted by da...@apache.org.
couch_mrview: fix 10-index-changes.t

proper test to check the indexer.


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

Branch: refs/heads/1994-merge-rcouch
Commit: 96aa28d58928e6303561ac45edf833a80a3c00d9
Parents: 76a7d60
Author: benoitc <be...@apache.org>
Authored: Sat Feb 8 20:20:47 2014 +0100
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Wed Feb 12 17:27:40 2014 -0600

----------------------------------------------------------------------
 test/10-index-changes.t | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/96aa28d5/test/10-index-changes.t
----------------------------------------------------------------------
diff --git a/test/10-index-changes.t b/test/10-index-changes.t
index f53e9ed..ce79eac 100644
--- a/test/10-index-changes.t
+++ b/test/10-index-changes.t
@@ -175,13 +175,13 @@ test_stream(Db) ->
 
 
 test_indexer(Db) ->
-    Result = run_query(Db, [{since, 14}]),
+    Result = run_query(Db, [{since, 14}, refresh]),
     Expect = {ok, 15, [{{15,14,<<"14">>},14}]},
     etap:is(Result, Expect, "refresh index by hand OK."),
 
     {ok, Db1} = save_doc(Db, 15),
-    timer:sleep(1000),
-    Result1 = run_query(Db, [{since, 14}]),
+    timer:sleep(1500),
+    Result1 = run_query(Db1, [{since, 14}], false),
     Expect1 = {ok, 16, [{{15,14,<<"14">>},14},
                        {{16,15,<<"15">>},15}]},
     etap:is(Result1, Expect1, "changes indexed in background OK."),
@@ -195,6 +195,9 @@ save_doc(Db, Id) ->
     couch_db:reopen(Db).
 
 run_query(Db, Opts) ->
+    run_query(Db, Opts, true).
+
+run_query(Db, Opts, Refresh) ->
     Fun = fun
         (stop, {LastSeq, Acc}) ->
             {ok, LastSeq, Acc};
@@ -203,7 +206,12 @@ run_query(Db, Opts) ->
         (Event, Acc) ->
             {ok, [Event | Acc]}
     end,
-    couch_mrview:refresh(Db, <<"_design/bar">>),
+    case Refresh of
+        true ->
+            couch_mrview:refresh(Db, <<"_design/bar">>);
+        false ->
+            ok
+    end,
     {ok, LastSeq, R} = couch_mrview_changes:handle_changes(Db, <<"_design/bar">>,
                                                   <<"baz">>, Fun, [], Opts),
     {ok, LastSeq, lists:reverse(R)}.


[20/25] couch-mrview commit: updated refs/heads/1994-merge-rcouch to 7775266

Posted by da...@apache.org.
extract couch_httpd changes API in its own module


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

Branch: refs/heads/1994-merge-rcouch
Commit: 01355fd931c5b800cf3827cba820d79c1611f951
Parents: dcaadec
Author: benoitc <bc...@gmail.com>
Authored: Sun Feb 2 19:54:01 2014 +0100
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Wed Feb 12 17:27:40 2014 -0600

----------------------------------------------------------------------
 src/couch_mrview_updater.erl | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/01355fd9/src/couch_mrview_updater.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_updater.erl b/src/couch_mrview_updater.erl
index a23def6..be1055c 100644
--- a/src/couch_mrview_updater.erl
+++ b/src/couch_mrview_updater.erl
@@ -182,7 +182,7 @@ map_docs(Parent, State0) ->
     end.
 
 
-write_results(Parent, #mrst{db_name=DbName, idx_name=IdxName}=State) ->
+write_results(Parent, State) ->
     case couch_work_queue:dequeue(State#mrst.write_queue) of
         closed ->
             Parent ! {new_state, State};
@@ -192,11 +192,6 @@ write_results(Parent, #mrst{db_name=DbName, idx_name=IdxName}=State) ->
                                                            [], dict:new()),
             NewState = write_kvs(State, Seq, ViewKVs, DocIdKeys, Log),
             send_partial(NewState#mrst.partial_resp_pid, NewState),
-
-            % notifify the view update
-            couch_index_event:notify({index_update, {DbName, IdxName,
-                                                     couch_mrview_index}}),
-
             write_results(Parent, NewState)
     end.
 


[23/25] couch-mrview commit: updated refs/heads/1994-merge-rcouch to 7775266

Posted by da...@apache.org.
couch_mrview: add HTTP handler to retrieve the infos on a view.


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

Branch: refs/heads/1994-merge-rcouch
Commit: a18c0418b17c7c39276c5b15985e5ec72a0cbc1a
Parents: 916e1b3
Author: benoitc <be...@apache.org>
Authored: Sat Feb 8 23:15:28 2014 +0100
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Wed Feb 12 17:27:40 2014 -0600

----------------------------------------------------------------------
 src/couch_mrview.erl      |  6 +++---
 src/couch_mrview_http.erl | 12 ++++++++++++
 2 files changed, 15 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/a18c0418/src/couch_mrview.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview.erl b/src/couch_mrview.erl
index e5b0d99..a578b85 100644
--- a/src/couch_mrview.erl
+++ b/src/couch_mrview.erl
@@ -161,11 +161,11 @@ get_view_info(Db, DDoc, VName) ->
     {ok, TotalSeqs} = case SeqBtree of
         nil -> {ok, 0};
         _ ->
-            {ok, {Count, _Reds}} = couch_btree:full_reduce(SeqBtree),
-            {ok, Count}
+            couch_btree:full_reduce(SeqBtree)
     end,
 
-    {ok, [{update_seq, View#mrview.update_seq},
+    {ok, [{seq_indexed, View#mrview.seq_indexed},
+          {update_seq, View#mrview.update_seq},
           {purge_seq, View#mrview.purge_seq},
           {total_rows, TotalRows},
           {total_seqs, TotalSeqs}]}.

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/a18c0418/src/couch_mrview_http.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_http.erl b/src/couch_mrview_http.erl
index 4801e27..c5ba622 100644
--- a/src/couch_mrview_http.erl
+++ b/src/couch_mrview_http.erl
@@ -48,6 +48,18 @@ handle_all_docs_req(Req, _Db) ->
     couch_httpd:send_method_not_allowed(Req, "GET,POST,HEAD").
 
 
+handle_view_req(#httpd{method='GET',
+                      path_parts=[_, _, DDocName, _, VName, <<"_info">>]}=Req,
+                Db, DDoc) ->
+
+    DDocId = <<"_design/", DDocName/binary >>,
+    {ok, Info} = couch_mrview:get_view_info(Db#db.name, DDocId, VName),
+
+    FinalInfo = [{db_name, Db#db.name},
+                 {ddoc, DDocId},
+                 {view, VName}] ++ Info,
+    couch_httpd:send_json(Req, 200, {FinalInfo});
+
 handle_view_req(#httpd{method='GET'}=Req, Db, DDoc) ->
     [_, _, _, _, ViewName] = Req#httpd.path_parts,
     couch_stats_collector:increment({httpd, view_reads}),


[13/25] couch-mrview commit: updated refs/heads/1994-merge-rcouch to 7775266

Posted by da...@apache.org.
couch_mrview: check removed keys from the index.


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

Branch: refs/heads/1994-merge-rcouch
Commit: 8ca63957d0884537a0fc3a3365f8f299a6748bcf
Parents: 3b6903e
Author: benoitc <be...@apache.org>
Authored: Mon Jan 27 21:03:28 2014 +0100
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Wed Feb 12 17:27:39 2014 -0600

----------------------------------------------------------------------
 test/08-changes_since.t | 42 ++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 40 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/8ca63957/test/08-changes_since.t
----------------------------------------------------------------------
diff --git a/test/08-changes_since.t b/test/08-changes_since.t
index 3127cff..5a10f4c 100644
--- a/test/08-changes_since.t
+++ b/test/08-changes_since.t
@@ -15,7 +15,7 @@
 % the License.
 
 main(_) ->
-    etap:plan(10),
+    etap:plan(14),
     case (catch test()) of
         ok ->
             etap:end_tests();
@@ -40,7 +40,8 @@ test() ->
     test_basic_count_since(Db),
     test_range_count_since(Db),
     test_compact(Db),
-    test_util:stop_couch(),
+    test_remove_key(Db),
+    catch test_util:stop_couch(),
     ok.
 
 
@@ -112,6 +113,43 @@ test_compact(Db) ->
     Count = run_count_query(Db, 0, []),
     etap:is(Count, 10, "compact view worked.").
 
+test_remove_key(Db) ->
+    %% add new doc
+    Doc = couch_mrview_test_util:doc(11),
+    {ok, Rev} = couch_db:update_doc(Db, Doc, []),
+    RevStr = couch_doc:rev_to_str(Rev),
+    {ok, _} =  couch_db:ensure_full_commit(Db),
+    {ok, Db1} = couch_db:reopen(Db),
+    Result = run_count_query(Db1, 0, []),
+    etap:is(Result, 11, "Add new doc worked."),
+    %% check new view key
+    Result1 = run_query(Db1, 0, [{start_key, 11}, {end_key, 11}]),
+    Expect = {ok, [
+                {{12, 11, <<"11">>}, 11}
+    ]},
+    etap:is(Result1, Expect, "added key OK."),
+
+    %% delete doc
+    Doc2 = couch_doc:from_json_obj({[
+                {<<"_id">>, <<"11">>},
+                {<<"_rev">>, RevStr},
+                {<<"_deleted">>, true}
+    ]}),
+    {ok, _} = couch_db:update_doc(Db1, Doc2, []),
+    {ok, Db2} = couch_db:reopen(Db1),
+    Result2 = run_count_query(Db2, 0, []),
+    etap:is(Result2, 11, "removed key saved."),
+    %% check new view key
+    Result3 = run_query(Db2, 0, [{start_key, 11}, {end_key, 11}]),
+    Expect2 = {ok, [
+                {{13, 11, <<"11">>}, {[{<<"_removed">>, true}]}}
+    ]},
+    etap:is(Result3, Expect2, "removed key OK.").
+
+
+
+
+
 run_query(Db, Since, Opts) ->
     Fun = fun(KV, Acc) -> {ok, [KV | Acc]} end,
     {ok, R} = couch_mrview:view_changes_since(Db, <<"_design/bar">>, <<"baz">>,


[12/25] couch-mrview commit: updated refs/heads/1994-merge-rcouch to 7775266

Posted by da...@apache.org.
couch_mrview: add couch_mrview:refresh/2 function

function to refresh a view index.


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

Branch: refs/heads/1994-merge-rcouch
Commit: fcfc8d29f18c60732d5798b836b01f38d299164f
Parents: 8ca6395
Author: benoitc <be...@apache.org>
Authored: Tue Jan 28 23:23:37 2014 +0100
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Wed Feb 12 17:27:39 2014 -0600

----------------------------------------------------------------------
 src/couch_mrview.erl    | 20 ++++++++++++++++++++
 test/08-changes_since.t |  4 ----
 2 files changed, 20 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/fcfc8d29/src/couch_mrview.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview.erl b/src/couch_mrview.erl
index d8f092c..26538a2 100644
--- a/src/couch_mrview.erl
+++ b/src/couch_mrview.erl
@@ -17,6 +17,7 @@
 -export([view_changes_since/6, view_changes_since/7]).
 -export([count_view_changes_since/4, count_view_changes_since/5]).
 -export([get_info/2]).
+-export([refresh/2]).
 -export([compact/2, compact/3, cancel_compaction/2]).
 -export([cleanup/1]).
 
@@ -146,6 +147,25 @@ get_info(Db, DDoc) ->
     couch_index:get_info(Pid).
 
 
+%% @doc refresh a view index
+refresh(#db{name=DbName}, DDoc) ->
+    refresh(DbName, DDoc);
+
+refresh(Db, DDoc) ->
+    UpdateSeq = couch_util:with_db(Db, fun(WDb) ->
+                    couch_db:get_update_seq(WDb)
+            end),
+
+    case couch_index_server:get_index(couch_mrview_index, Db, DDoc) of
+        {ok, Pid} ->
+            case catch couch_index:get_state(Pid, UpdateSeq) of
+                {ok, _} -> ok;
+                Error -> {error, Error}
+            end;
+        Error ->
+            {error, Error}
+    end.
+
 compact(Db, DDoc) ->
     compact(Db, DDoc, []).
 

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/fcfc8d29/test/08-changes_since.t
----------------------------------------------------------------------
diff --git a/test/08-changes_since.t b/test/08-changes_since.t
index 5a10f4c..58c92e9 100644
--- a/test/08-changes_since.t
+++ b/test/08-changes_since.t
@@ -146,10 +146,6 @@ test_remove_key(Db) ->
     ]},
     etap:is(Result3, Expect2, "removed key OK.").
 
-
-
-
-
 run_query(Db, Since, Opts) ->
     Fun = fun(KV, Acc) -> {ok, [KV | Acc]} end,
     {ok, R} = couch_mrview:view_changes_since(Db, <<"_design/bar">>, <<"baz">>,