4
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
4
%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
6
6
%% The contents of this file are subject to the Erlang Public License,
7
7
%% Version 1.1, (the "License"); you may not use this file except in
8
8
%% compliance with the License. You should have received a copy of the
9
9
%% Erlang Public License along with this software. If not, it can be
10
10
%% retrieved online at http://www.erlang.org/.
12
12
%% Software distributed under the License is distributed on an "AS IS"
13
13
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14
14
%% the License for the specific language governing rights and limitations
15
15
%% under the License.
43
43
-export([i/0, i/1, i/2, i/3]).
45
%%------------------------------------------------------------------------------
45
-export_type([tab/0, tid/0]).
47
%%-----------------------------------------------------------------------------
47
49
-type tab() :: atom() | tid().
51
%% a similar definition is also in erl_types
52
-opaque tid() :: integer().
49
54
-type ext_info() :: 'md5sum' | 'object_count'.
50
55
-type protection() :: 'private' | 'protected' | 'public'.
51
56
-type type() :: 'bag' | 'duplicate_bag' | 'ordered_set' | 'set'.
63
68
-type match_pattern() :: atom() | tuple().
64
69
-type match_specs() :: [{match_pattern(), [_], [_]}].
66
%%------------------------------------------------------------------------------
71
%%-----------------------------------------------------------------------------
68
73
%% The following functions used to be found in this module, but
69
74
%% are now BIFs (i.e. implemented in C).
230
235
erlang:error(Unexpected,[EtsTable,DetsTable])
233
-spec to_dets(tab(), dets:tab_name()) -> tab().
238
-spec to_dets(tab(), dets:tab_name()) -> dets:tab_name().
235
240
to_dets(EtsTable, DetsTable) ->
236
241
case (catch dets:from_ets(DetsTable, EtsTable)) of
508
513
file2tab(File, Opts) ->
510
{ok,Verify} = parse_f2t_opts(Opts,false),
515
{ok,Verify,TabArg} = parse_f2t_opts(Opts,false,[]),
511
516
Name = make_ref(),
512
517
{ok, Major, Minor, FtOptions, MD5State, FullHeader, DLContext} =
513
518
case disk_log:open([{name, Name},
624
629
{ok,{FinalMD5State,FinalCount,['$end_of_table',LastInfo],_}} ->
625
ECount = case lists:keysearch(count,1,LastInfo) of
630
ECount = case lists:keyfind(count,1,LastInfo) of
631
EMD5 = case lists:keysearch(md5,1,LastInfo) of
636
EMD5 = case lists:keyfind(md5,1,LastInfo) of
674
parse_f2t_opts([],Verify) ->
676
parse_f2t_opts([{verify, true}|T],_OV) ->
677
parse_f2t_opts(T,true);
678
parse_f2t_opts([{verify,false}|T],OV) ->
679
parse_f2t_opts(T,OV);
680
parse_f2t_opts([Unexpected|_],_) ->
679
parse_f2t_opts([],Verify,Tab) ->
681
parse_f2t_opts([{verify, true}|T],_OV,Tab) ->
682
parse_f2t_opts(T,true,Tab);
683
parse_f2t_opts([{verify,false}|T],OV,Tab) ->
684
parse_f2t_opts(T,OV,Tab);
685
parse_f2t_opts([{table,Tab}|T],OV,[]) ->
686
parse_f2t_opts(T,OV,Tab);
687
parse_f2t_opts([Unexpected|_],_,_) ->
681
688
throw({unknown_option,Unexpected});
682
parse_f2t_opts(Malformed,_) ->
689
parse_f2t_opts(Malformed,_,_) ->
683
690
throw({malformed_option,Malformed}).
685
692
count_mandatory([]) ->
745
Major = case lists:keysearch(major,1,L) of
746
{value,{major,Maj}} ->
752
Major = case lists:keyfind(major,1,L) of
751
Minor = case lists:keysearch(minor,1,L) of
752
{value,{minor,Min}} ->
758
Minor = case lists:keyfind(minor,1,L) of
758
case lists:keysearch(extended_info,1,L) of
759
{value,{extended_info,I}}
765
case lists:keyfind(extended_info,1,L) of
766
{extended_info,I} when is_list(I) ->
788
794
get_header_data(Name, false) ->
789
case wrap_chunk(Name,start,1,false) of
795
case wrap_chunk(Name, start, 1, false) of
790
796
{C,[Tup]} when is_tuple(Tup) ->
791
797
L = tuple_to_list(Tup),
792
798
case verify_header_mandatory(L) of
796
Major = case lists:keysearch(major_version,1,L) of
797
{value,{major_version,Maj}} ->
802
Major = case lists:keyfind(major_version, 1, L) of
803
{major_version, Maj} ->
802
Minor = case lists:keysearch(minor_version,1,L) of
803
{value,{minor_version,Min}} ->
808
Minor = case lists:keyfind(minor_version, 1, L) of
809
{minor_version, Min} ->
809
case lists:keysearch(extended_info,1,L) of
810
{value,{extended_info,I}}
815
case lists:keyfind(extended_info, 1, L) of
816
{extended_info, I} when is_list(I) ->
828
md5_and_convert([],MD5State,Count) ->
833
md5_and_convert([], MD5State, Count) ->
829
834
{[],MD5State,Count,[]};
830
md5_and_convert([H|T],MD5State,Count) when is_binary(H) ->
835
md5_and_convert([H|T], MD5State, Count) when is_binary(H) ->
831
836
case (catch binary_to_term(H)) of
833
838
md5_and_convert(T,MD5State,Count);
834
['$end_of_table',Dat] ->
835
{[],MD5State,Count,['$end_of_table',Dat]};
839
['$end_of_table',_Dat] = L ->
840
{[],MD5State,Count,L};
837
X = erlang:md5_update(MD5State,H),
838
{Rest,NewMD5,NewCount,NewLast} = md5_and_convert(T,X,Count+1),
842
X = erlang:md5_update(MD5State, H),
843
{Rest,NewMD5,NewCount,NewLast} = md5_and_convert(T, X, Count+1),
839
844
{[Term | Rest],NewMD5,NewCount,NewLast}
841
scan_for_endinfo([],Count) ->
847
scan_for_endinfo([], Count) ->
843
scan_for_endinfo([['$end_of_table',Dat]],Count) ->
849
scan_for_endinfo([['$end_of_table',Dat]], Count) ->
844
850
{['$end_of_table',Dat],Count,[]};
845
scan_for_endinfo([Term|T],Count) ->
846
{NewLast,NCount,Rest} = scan_for_endinfo(T,Count+1),
851
scan_for_endinfo([Term|T], Count) ->
852
{NewLast,NCount,Rest} = scan_for_endinfo(T, Count+1),
847
853
{NewLast,NCount,[Term | Rest]}.
849
855
load_table(ReadFun, State, Tab) ->
855
ets:insert(Tab,List),
856
load_table(ReadFun,NewState,Tab)
861
ets:insert(Tab, List),
862
load_table(ReadFun, NewState, Tab)
860
{value, {name, Name}} = lists:keysearch(name, 1, I),
861
{value, {type, Type}} = lists:keysearch(type, 1, I),
862
{value, {protection, P}} = lists:keysearch(protection, 1, I),
863
{value, {named_table, Val}} = lists:keysearch(named_table, 1, I),
864
{value, {keypos, Kp}} = lists:keysearch(keypos, 1, I),
865
{value, {size, Sz}} = lists:keysearch(size, 1, I),
867
Tab = ets:new(Name, [Type, P, {keypos, Kp} | named_table(Val)]),
871
throw(cannot_create_table)
865
create_tab(I, TabArg) ->
866
{name, Name} = lists:keyfind(name, 1, I),
867
{type, Type} = lists:keyfind(type, 1, I),
868
{protection, P} = lists:keyfind(protection, 1, I),
869
{named_table, Val} = lists:keyfind(named_table, 1, I),
870
{keypos, _Kp} = Keypos = lists:keyfind(keypos, 1, I),
871
{size, Sz} = lists:keyfind(size, 1, I),
872
Comp = case lists:keyfind(compressed, 1, I) of
873
{compressed, true} -> [compressed];
874
{compressed, false} -> [];
880
Tab = ets:new(Name, [Type, P, Keypos] ++ named_table(Val) ++ Comp),
883
throw(cannot_create_table)
874
889
named_table(true) -> [named_table];
905
920
{value, Val} = lists:keysearch(named_table, 1, FullHeader),
906
921
{value, Kp} = lists:keysearch(keypos, 1, FullHeader),
907
922
{value, Sz} = lists:keysearch(size, 1, FullHeader),
908
Ei = case lists:keysearch(extended_info, 1, FullHeader) of
910
_ -> {extended_info, []}
923
Ei = case lists:keyfind(extended_info, 1, FullHeader) of
924
false -> {extended_info, []};
912
927
{ok, [N,Type,P,Val,Kp,Sz,Ei,{version,{Major,Minor}}]}
1021
1036
options([Option], Keys, []).
1023
1038
options(Options, [Key | Keys], L) when is_list(Options) ->
1024
V = case lists:keysearch(Key, 1, Options) of
1025
{value, {n_objects, default}} ->
1039
V = case lists:keyfind(Key, 1, Options) of
1040
{n_objects, default} ->
1026
1041
{ok, default_option(Key)};
1027
{value, {n_objects, NObjs}} when is_integer(NObjs),
1042
{n_objects, NObjs} when is_integer(NObjs), NObjs >= 1 ->
1030
{value, {traverse, select}} ->
1044
{traverse, select} ->
1032
{value, {traverse, {select, MS}}} ->
1034
{value, {traverse, first_next}} ->
1046
{traverse, {select, _MS} = Select} ->
1048
{traverse, first_next} ->
1035
1049
{ok, first_next};
1036
{value, {traverse, last_prev}} ->
1050
{traverse, last_prev} ->
1037
1051
{ok, last_prev};
1038
{value, {Key, _}} ->
1041
1055
Default = default_option(Key),