/src/dreyfus/src/dreyfus_bookmark.erl
https://github.com/apache/couchdb · Erlang · 90 lines · 63 code · 15 blank · 12 comment · 1 complexity · 2999f2c1c6085cc949576ecb67267638 MD5 · raw file
- % 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(dreyfus_bookmark).
- -include("dreyfus.hrl").
- -include_lib("mem3/include/mem3.hrl").
- -export([
- update/3,
- unpack/2,
- pack/1,
- add_missing_shards/2
- ]).
- update(_Sort, Bookmark, []) ->
- Bookmark;
- update(relevance, Bookmark, [#sortable{} = Sortable | Rest]) ->
- #sortable{
- order = [Score, Doc],
- shard = Shard
- } = Sortable,
- B1 = fabric_dict:store(Shard, {Score, Doc}, Bookmark),
- B2 = fabric_view:remove_overlapping_shards(Shard, B1),
- update(relevance, B2, Rest);
- update(Sort, Bookmark, [#sortable{} = Sortable | Rest]) ->
- #sortable{
- order = Order,
- shard = Shard
- } = Sortable,
- B1 = fabric_dict:store(Shard, Order, Bookmark),
- B2 = fabric_view:remove_overlapping_shards(Shard, B1),
- update(Sort, B2, Rest).
- unpack(DbName, #index_query_args{bookmark=nil} = Args) ->
- fabric_dict:init(dreyfus_util:get_shards(DbName, Args), nil);
- unpack(DbName, #index_query_args{} = Args) ->
- unpack(DbName, Args#index_query_args.bookmark);
- unpack(DbName, Packed) when is_binary(Packed) ->
- lists:map(fun({Node, Range, After}) ->
- case mem3:get_shard(DbName, Node, Range) of
- {ok, Shard} ->
- {Shard, After};
- {error, not_found} ->
- PlaceHolder = #shard{
- node = Node,
- range = Range,
- dbname = DbName,
- _='_'
- },
- {PlaceHolder, After}
- end
- end, binary_to_term(couch_util:decodeBase64Url(Packed))).
- pack(nil) ->
- null;
- pack(Workers) ->
- Workers1 = [{N,R,A} || {#shard{node=N, range=R}, A} <- Workers, A =/= nil],
- Bin = term_to_binary(Workers1, [compressed, {minor_version,1}]),
- couch_util:encodeBase64Url(Bin).
- add_missing_shards(Bookmark, LiveShards) ->
- {BookmarkShards, _} = lists:unzip(Bookmark),
- add_missing_shards(Bookmark, BookmarkShards, LiveShards).
- add_missing_shards(Bookmark, _, []) ->
- Bookmark;
- add_missing_shards(Bookmark, BMShards, [H | T]) ->
- Bookmark1 = case lists:keymember(H#shard.range, #shard.range, BMShards) of
- true -> Bookmark;
- false -> fabric_dict:store(H, nil, Bookmark)
- end,
- add_missing_shards(Bookmark1, BMShards, T).