summaryrefslogtreecommitdiff
path: root/src/nouveau/src/nouveau_bookmark.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/nouveau/src/nouveau_bookmark.erl')
-rw-r--r--src/nouveau/src/nouveau_bookmark.erl68
1 files changed, 68 insertions, 0 deletions
diff --git a/src/nouveau/src/nouveau_bookmark.erl b/src/nouveau/src/nouveau_bookmark.erl
new file mode 100644
index 000000000..b919534ea
--- /dev/null
+++ b/src/nouveau/src/nouveau_bookmark.erl
@@ -0,0 +1,68 @@
+%%
+%% 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.
+
+%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
+
+-module(nouveau_bookmark).
+
+-include_lib("mem3/include/mem3.hrl").
+
+-export([new/0, update/3, unpack/2, pack/1, to_ejson/1]).
+
+new() ->
+ #{}.
+
+%% Form a bookmark from the last contribution from each shard range
+update(DbName, PreviousBookmark, SearchResults) when is_binary(PreviousBookmark) ->
+ update(DbName, unpack(DbName, PreviousBookmark), SearchResults);
+update(DbName, {EJson}, SearchResults) when is_list(EJson) ->
+ update(DbName, from_ejson({EJson}), SearchResults);
+update(DbName, PreviousBookmark, SearchResults) when is_map(PreviousBookmark) ->
+ #{<<"hits">> := Hits} = SearchResults,
+ NewBookmark0 = lists:foldl(
+ fun(#{<<"id">> := Id, <<"order">> := Order}, Acc) ->
+ Acc#{range_of(DbName, Id) => Order}
+ end,
+ new(),
+ Hits
+ ),
+ maps:merge(PreviousBookmark, NewBookmark0).
+
+range_of(DbName, DocId) when is_binary(DbName), is_binary(DocId) ->
+ [#shard{range = Range} | _] = mem3_shards:for_docid(DbName, DocId),
+ Range;
+range_of(DbName, Order) when is_binary(DbName), is_list(Order) ->
+ #{<<"@type">> := <<"string">>, <<"value">> := DocId} = lists:last(Order),
+ range_of(DbName, DocId).
+
+unpack(_DbName, Empty) when Empty == undefined; Empty == nil; Empty == null ->
+ new();
+unpack(DbName, PackedBookmark) when is_list(PackedBookmark) ->
+ unpack(DbName, list_to_binary(PackedBookmark));
+unpack(DbName, PackedBookmark) when is_binary(PackedBookmark) ->
+ Bookmark = jiffy:decode(base64:decode(PackedBookmark), [return_maps]),
+ maps:from_list([{range_of(DbName, V), V} || V <- Bookmark]).
+
+pack(nil) ->
+ null;
+pack({EJson}) when is_list(EJson) ->
+ pack(from_ejson(EJson));
+pack(UnpackedBookmark) when is_map(UnpackedBookmark) ->
+ base64:encode(jiffy:encode(maps:values(UnpackedBookmark))).
+
+%% legacy use of ejson within mango
+from_ejson({Props}) ->
+ maps:from_list(Props).
+
+to_ejson(Bookmark) when is_map(Bookmark) ->
+ {maps:to_list(Bookmark)}.