2013-08-30 06:52:20 -05:00
|
|
|
%%% vi:ts=4 sw=4 et
|
2011-10-14 12:29:28 -05:00
|
|
|
%%%-------------------------------------------------------------------
|
|
|
|
%%% @author Eric Merritt <ericbmerritt@gmail.com>
|
|
|
|
%%% @copyright 2011 Erlware, LLC.
|
|
|
|
%%% @doc
|
|
|
|
%%% This provides an implementation of the type ec_dictionary using
|
|
|
|
%%% gb_trees as a backin
|
2012-09-03 11:33:00 -05:00
|
|
|
%%% see ec_dictionary
|
|
|
|
%%% see gb_trees
|
2011-10-14 12:29:28 -05:00
|
|
|
%%% @end
|
|
|
|
%%%-------------------------------------------------------------------
|
|
|
|
-module(ec_gb_trees).
|
|
|
|
|
|
|
|
-behaviour(ec_dictionary).
|
|
|
|
|
|
|
|
%% API
|
|
|
|
-export([new/0,
|
2012-09-03 11:33:00 -05:00
|
|
|
has_key/2,
|
|
|
|
get/2,
|
|
|
|
get/3,
|
|
|
|
add/3,
|
|
|
|
remove/2,
|
|
|
|
has_value/2,
|
|
|
|
size/1,
|
|
|
|
to_list/1,
|
|
|
|
from_list/1,
|
|
|
|
keys/1]).
|
2011-10-14 12:29:28 -05:00
|
|
|
|
|
|
|
%%%===================================================================
|
|
|
|
%%% API
|
|
|
|
%%%===================================================================
|
|
|
|
|
|
|
|
%% @doc create a new dictionary object from the specified module. The
|
|
|
|
%% module should implement the dictionary behaviour. In the clause
|
|
|
|
%% where an existing object is passed in new empty dictionary of the
|
|
|
|
%% same implementation is created and returned.
|
|
|
|
%%
|
|
|
|
%% @param ModuleName|Object The module name or existing dictionary object.
|
2014-10-01 12:31:47 -07:00
|
|
|
-spec new() -> gb_trees:tree(_K, _V).
|
2011-10-14 12:29:28 -05:00
|
|
|
new() ->
|
|
|
|
gb_trees:empty().
|
|
|
|
|
|
|
|
%% @doc check to see if the dictionary provided has the specified key.
|
|
|
|
%%
|
|
|
|
%% @param Object The dictory object to check
|
|
|
|
%% @param Key The key to check the dictionary for
|
2014-10-01 12:31:47 -07:00
|
|
|
-spec has_key(ec_dictionary:key(K), Object::gb_trees:tree(K, _V)) -> boolean().
|
2011-10-14 12:29:28 -05:00
|
|
|
has_key(Key, Data) ->
|
|
|
|
case gb_trees:lookup(Key, Data) of
|
2012-09-03 11:33:00 -05:00
|
|
|
{value, _Val} ->
|
|
|
|
true;
|
|
|
|
none ->
|
|
|
|
false
|
2011-10-14 12:29:28 -05:00
|
|
|
end.
|
|
|
|
|
|
|
|
%% @doc given a key return that key from the dictionary. If the key is
|
|
|
|
%% not found throw a 'not_found' exception.
|
|
|
|
%%
|
|
|
|
%% @param Object The dictionary object to return the value from
|
|
|
|
%% @param Key The key requested
|
2012-09-03 11:33:00 -05:00
|
|
|
%% when the key does not exist @throws not_found
|
2014-10-01 12:31:47 -07:00
|
|
|
-spec get(ec_dictionary:key(K), Object::gb_trees:tree(K, V)) ->
|
2011-10-14 12:29:28 -05:00
|
|
|
ec_dictionary:value(V).
|
|
|
|
get(Key, Data) ->
|
|
|
|
case gb_trees:lookup(Key, Data) of
|
2012-09-03 11:33:00 -05:00
|
|
|
{value, Value} ->
|
|
|
|
Value;
|
|
|
|
none ->
|
|
|
|
throw(not_found)
|
2011-10-14 12:29:28 -05:00
|
|
|
end.
|
|
|
|
|
|
|
|
-spec get(ec_dictionary:key(K),
|
2012-09-03 11:33:00 -05:00
|
|
|
ec_dictionary:value(V),
|
2014-10-01 12:31:47 -07:00
|
|
|
Object::gb_trees:tree(K, V)) ->
|
2011-10-14 12:29:28 -05:00
|
|
|
ec_dictionary:value(V).
|
|
|
|
get(Key, Default, Data) ->
|
|
|
|
case gb_trees:lookup(Key, Data) of
|
2012-09-03 11:33:00 -05:00
|
|
|
{value, Value} ->
|
|
|
|
Value;
|
|
|
|
none ->
|
|
|
|
Default
|
2011-10-14 12:29:28 -05:00
|
|
|
end.
|
|
|
|
|
|
|
|
%% @doc add a new value to the existing dictionary. Return a new
|
|
|
|
%% dictionary containing the value.
|
|
|
|
%%
|
|
|
|
%% @param Object the dictionary object to add too
|
|
|
|
%% @param Key the key to add
|
|
|
|
%% @param Value the value to add
|
|
|
|
-spec add(ec_dictionary:key(K), ec_dictionary:value(V),
|
2014-10-01 12:31:47 -07:00
|
|
|
Object::gb_trees:tree(K, V)) ->
|
|
|
|
gb_trees:tree(K, V).
|
2011-10-14 12:29:28 -05:00
|
|
|
add(Key, Value, Data) ->
|
|
|
|
gb_trees:enter(Key, Value, Data).
|
|
|
|
|
|
|
|
%% @doc Remove a value from the dictionary returning a new dictionary
|
|
|
|
%% with the value removed.
|
|
|
|
%%
|
|
|
|
%% @param Object the dictionary object to remove the value from
|
|
|
|
%% @param Key the key of the key/value pair to remove
|
2014-10-01 12:31:47 -07:00
|
|
|
-spec remove(ec_dictionary:key(K), Object::gb_trees:tree(K, V)) ->
|
|
|
|
gb_trees:tree(K, V).
|
2011-10-14 12:29:28 -05:00
|
|
|
remove(Key, Data) ->
|
|
|
|
gb_trees:delete_any(Key, Data).
|
|
|
|
|
|
|
|
%% @doc Check to see if the value exists in the dictionary
|
|
|
|
%%
|
|
|
|
%% @param Object the dictionary object to check
|
|
|
|
%% @param Value The value to check if exists
|
2014-10-01 12:31:47 -07:00
|
|
|
-spec has_value(ec_dictionary:value(V), Object::gb_trees:tree(_K, V)) -> boolean().
|
2011-10-14 12:29:28 -05:00
|
|
|
has_value(Value, Data) ->
|
|
|
|
lists:member(Value, gb_trees:values(Data)).
|
|
|
|
|
|
|
|
%% @doc return the current number of key value pairs in the dictionary
|
|
|
|
%%
|
|
|
|
%% @param Object the object return the size for.
|
2014-10-01 12:31:47 -07:00
|
|
|
-spec size(Object::gb_trees:tree(_K, _V)) -> non_neg_integer().
|
2011-10-14 12:29:28 -05:00
|
|
|
size(Data) ->
|
|
|
|
gb_trees:size(Data).
|
|
|
|
|
2014-10-01 12:31:47 -07:00
|
|
|
-spec to_list(gb_trees:tree(K, V)) -> [{ec_dictionary:key(K),
|
|
|
|
ec_dictionary:value(V)}].
|
2011-10-14 12:29:28 -05:00
|
|
|
to_list(Data) ->
|
|
|
|
gb_trees:to_list(Data).
|
|
|
|
|
|
|
|
-spec from_list([{ec_dictionary:key(K), ec_dictionary:value(V)}]) ->
|
2014-10-01 12:31:47 -07:00
|
|
|
gb_trees:tree(K, V).
|
2011-10-14 12:29:28 -05:00
|
|
|
from_list(List) when is_list(List) ->
|
|
|
|
lists:foldl(fun({Key, Value}, Dict) ->
|
2012-09-03 11:33:00 -05:00
|
|
|
gb_trees:enter(Key, Value, Dict)
|
|
|
|
end,
|
|
|
|
gb_trees:empty(),
|
|
|
|
List).
|
2011-10-14 12:29:28 -05:00
|
|
|
|
2014-10-01 12:31:47 -07:00
|
|
|
-spec keys(gb_trees:tree(K,_V)) -> [ec_dictionary:key(K)].
|
2011-10-14 12:29:28 -05:00
|
|
|
keys(Data) ->
|
|
|
|
gb_trees:keys(Data).
|