Current section

Files

Jump to
edb_core src edb_server_sets.erl
Raw

src/edb_server_sets.erl

%% Copyright (c) Meta Platforms, Inc. and affiliates.
%%
%% 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.
%% % @format
-module(edb_server_sets).
-compile(warn_missing_spec_all).
%% erlfmt:ignore
% @fb-only
%% Public API
-export([
is_element/2,
take_element/2,
union/2, union/1,
intersection/2,
subtract/2,
to_map/2,
map_subtract_keys/2,
is_empty/1
]).
-export_type([set/1]).
%% -------------------------------------------------------------------
%% Map-based sets
%% -------------------------------------------------------------------
-type set(A) :: #{A => term()}.
-spec is_empty(set(_)) -> boolean().
is_empty(Set) ->
maps:size(Set) =:= 0.
-spec take_element(A, #{A => []}) -> {found, #{A => []}} | not_found.
take_element(X, Set) ->
case maps:take(X, Set) of
{_, Set1} -> {found, Set1};
error -> not_found
end.
-spec is_element(X :: A, Set :: set(A)) -> boolean().
is_element(X, Set) ->
maps:is_key(X, Set).
-spec union(L :: set(A), R :: set(A)) -> set(A).
union(L, R) ->
maps:merge(L, R).
-spec union([set(A)]) -> set(A).
union(Sets) ->
lists:foldl(fun union/2, #{}, Sets).
-spec intersection(L :: set(A), R :: set(A)) -> set(A).
intersection(L, R) ->
#{X => [] || X := _ <- L, maps:is_key(X, R)}.
-spec subtract(L :: set(A), R :: set(A)) -> set(A).
subtract(L, R) ->
map_subtract_keys(L, R).
-spec to_map(set(K), V) -> #{K => V}.
to_map(S, V) ->
#{K => V || K := _ <- S}.
-spec map_subtract_keys(Map :: #{K => V}, KeysToRemove :: set(K)) -> #{K => V}.
map_subtract_keys(Map, KeysToRemove) ->
#{A => B || A := B <- Map, not is_element(A, KeysToRemove)}.