From e3fc1173b0b05a4d81d070206a3f2e7ac66b0e36 Mon Sep 17 00:00:00 2001 From: Patrik Nyblom Date: Thu, 12 Aug 2010 17:36:35 +0200 Subject: Add testcase for ets:select_reverse/1/2/3 --- lib/stdlib/test/ets_SUITE.erl | 69 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl index 5d7e558601..6a123da792 100644 --- a/lib/stdlib/test/ets_SUITE.erl +++ b/lib/stdlib/test/ets_SUITE.erl @@ -94,6 +94,8 @@ do_heavy_concurrent/1 ]). +-export([t_select_reverse/1]). + -include("test_server.hrl"). init_per_testcase(Case, Config) -> @@ -128,7 +130,7 @@ all(suite) -> match_heavy, fold, member, t_delete_object, t_init_table, t_whitebox, t_delete_all_objects, t_insert_list, t_test_ms, - t_select_delete, t_ets_dets, memory, + t_select_delete, t_ets_dets, memory, t_select_reverse, t_bucket_disappears, select_fail,t_insert_new, t_repair_continuation, otp_5340, otp_6338, otp_6842_select_1000, otp_7665, otp_8732, @@ -788,6 +790,67 @@ t_test_ms(Config) when is_list(Config) -> ?line true = (if is_list(String) -> true; true -> false end), ?line verify_etsmem(EtsMem). +t_select_reverse(doc) -> + ["Test the select reverse BIF's"]; +t_select_reverse(suite) -> + []; +t_select_reverse(Config) when is_list(Config) -> + ?line Table = ets:new(xxx, [ordered_set]), + ?line filltabint(Table,1000), + ?line A = lists:reverse(ets:select(Table,[{{'$1', '_'}, + [{'>', + {'rem', + '$1', 5}, + 2}], + ['$_']}])), + ?line A = ets:select_reverse(Table,[{{'$1', '_'}, + [{'>', + {'rem', + '$1', 5}, + 2}], + ['$_']}]), + ?line A = reverse_chunked(Table,[{{'$1', '_'}, + [{'>', + {'rem', + '$1', 5}, + 2}], + ['$_']}],3), + % A set/bag/duplicate_bag should get the same result regardless + % of select or select_reverse + ?line Table2 = ets:new(xxx, [set]), + ?line filltabint(Table2,1000), + ?line Table3 = ets:new(xxx, [bag]), + ?line filltabint(Table3,1000), + ?line Table4 = ets:new(xxx, [duplicate_bag]), + ?line filltabint(Table4,1000), + ?line lists:map(fun(Tab) -> + B = ets:select(Tab,[{{'$1', '_'}, + [{'>', + {'rem', + '$1', 5}, + 2}], + ['$_']}]), + B = ets:select_reverse(Tab,[{{'$1', '_'}, + [{'>', + {'rem', + '$1', 5}, + 2}], + ['$_']}]) + end,[Table2, Table3, Table4]), + ok. + + + +reverse_chunked(T,MS,N) -> + do_reverse_chunked(ets:select_reverse(T,MS,N),[]). + +do_reverse_chunked('$end_of_table',Acc) -> + lists:reverse(Acc); +do_reverse_chunked({L,C},Acc) -> + NewAcc = lists:reverse(L)++Acc, + do_reverse_chunked(ets:select_reverse(C), NewAcc). + + t_select_delete(doc) -> ["Test the ets:select_delete/2 and ets:select_count/2 BIF's"]; t_select_delete(suite) -> @@ -3942,7 +4005,7 @@ do_lookup_element(Tab, N, M) -> end. -heavy_concurrent(Config) -> +heavy_concurrent(_Config) -> repeat_for_opts(do_heavy_concurrent). do_heavy_concurrent(Opts) -> @@ -3961,7 +4024,7 @@ do_heavy_concurrent(Opts) -> ?line lists:foreach(fun (P) -> M = erlang:monitor(process, P), receive - {'DOWN', Mon, process, P, _} -> + {'DOWN', M, process, P, _} -> ok end end, -- cgit v1.2.3 From 44cbc2691654adb20516490e079602843ab4c371 Mon Sep 17 00:00:00 2001 From: Patrik Nyblom Date: Fri, 13 Aug 2010 11:30:42 +0200 Subject: Add documentation for ets:select_reverse/1/2/3 --- lib/stdlib/doc/src/ets.xml | 107 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 93 insertions(+), 14 deletions(-) (limited to 'lib') diff --git a/lib/stdlib/doc/src/ets.xml b/lib/stdlib/doc/src/ets.xml index 5df60a92e5..dd4a289c61 100644 --- a/lib/stdlib/doc/src/ets.xml +++ b/lib/stdlib/doc/src/ets.xml @@ -1384,6 +1384,28 @@ is_integer(X), is_integer(Y), X + Y < 4711]]> objects in the table.

+ + select_count(Tab, MatchSpec) -> NumMatched + Match the objects in an ETS table against a match_spec and returns the number of objects for which the match_spec returned 'true' + + Tab = tid() | atom() + Object = tuple() + MatchSpec = match_spec() + NumMatched = integer() + + +

Matches the objects in the table Tab using a + match_spec. If the + match_spec returns true for an object, that object + considered a match and is counted. For any other result from + the match_spec the object is not considered a match and is + therefore not counted.

+

The function could be described as a match_delete/2 + that does not actually delete any elements, but only counts + them.

+

The function returns the number of objects matched.

+
+
select_delete(Tab, MatchSpec) -> NumDeleted Match the objects in an ETS table against a match_spec and deletes objects where the match_spec returns 'true' @@ -1411,25 +1433,82 @@ is_integer(X), is_integer(Y), X + Y < 4711]]> - select_count(Tab, MatchSpec) -> NumMatched - Match the objects in an ETS table against a match_spec and returns the number of objects for which the match_spec returned 'true' + select_reverse(Tab, MatchSpec) -> [Match] + Match the objects in an ETS table against a match_spec. Tab = tid() | atom() - Object = tuple() + Match = term() MatchSpec = match_spec() - NumMatched = integer() -

Matches the objects in the table Tab using a - match_spec. If the - match_spec returns true for an object, that object - considered a match and is counted. For any other result from - the match_spec the object is not considered a match and is - therefore not counted.

-

The function could be described as a match_delete/2 - that does not actually delete any elements, but only counts - them.

-

The function returns the number of objects matched.

+ +

Works like select/2, but returns the list in reverse + order for the ordered_set table type. For all other table + types, the return value is identical to that of select/2.

+ +
+
+ + select_reverse(Tab, MatchSpec, Limit) -> {[Match],Continuation} | '$end_of_table' + Match the objects in an ETS table against a match_spec and returns part of the answers. + + Tab = tid() | atom() + Match = term() + MatchSpec = match_spec() + Continuation = term() + + + +

Works like select/3, but for the ordered_set + table type, traversing is done starting at the last object in + Erlang term order and moves towards the first. For all other + table types, the return value is identical to that of + select/3.

+ +

Note that this is not equivalent to + reversing the result list of a select/3 call, as the result list + is not only reversed, but also contains the last Limit + matching objects in the table, not the first.

+ +
+
+ + select_reverse(Continuation) -> {[Match],Continuation} | '$end_of_table' + Continue matching objects in an ETS table. + + Match = term() + Continuation = term() + + + +

Continues a match started with + ets:select_reverse/3. If the table is an + ordered_set, the traversal of the table will continue + towards objects with keys earlier in the Erlang term order. The + returned list will also contain objects with keys in reverse + order.

+ +

For all other table types, the behaviour is exatly that of select/1.

+

Example:

+ +1> T = ets:new(x,[ordered_set]). +2> [ ets:insert(T,{N}) || N <- lists:seq(1,10) ]. +... +3> {R0,C0} = ets:select_reverse(T,[{'_',[],['$_']}],4). +... +4> R0. +[{10},{9},{8},{7}] +5> {R1,C1} = ets:select_reverse(C0). +... +6> R1. +[{6},{5},{4},{3}] +7> {R2,C2} = ets:select_reverse(C1). +... +8> R2. +[{2},{1}] +9> '$end_of_table' = ets:select_reverse(C2). +... +
-- cgit v1.2.3