3333 call_stat /1 , call_stat /2 ]).
3434
3535% % API - utilities
36- -export ([contains_data /2 ,
36+ -export ([match_data / 2 , contains_data / 2 , contains_val / 2 , match_val /2 ,
3737 do /1 ,
3838 lookup /1 ,
3939 next /1 , seq_next /1 , next /2 , prev /1 , seq_prev /1 , prev /2 ,
@@ -504,10 +504,36 @@ call_stat(KeyF, Tab) ->
504504% % @doc Looks for `DataVal' in `#tr.data'.
505505% %
506506% % `DataVal' can occur in (possibly nested) tuples, maps or lists.
507+ -spec match_data (fun ((term ()) -> boolean ()), tr ()) -> boolean ().
508+ match_data (Pred , # tr {data = Data }) when is_function (Pred , 1 ) ->
509+ match_val (Pred , Data ).
510+
507511-spec contains_data (term (), tr ()) -> boolean ().
508512contains_data (DataVal , # tr {data = Data }) ->
509513 contains_val (DataVal , Data ).
510514
515+ -spec match_val (fun ((term ()) -> boolean ()), term ()) -> boolean ().
516+ match_val (Pred , Val ) ->
517+ case catch Pred (Val ) of
518+ true ->
519+ true ;
520+ _ ->
521+ case Val of
522+ [_ |_ ] ->
523+ lists :any (fun (El ) -> match_val (Pred , El ) end , Val );
524+ _ when is_tuple (Val ) ->
525+ match_val (Pred , tuple_to_list (Val ));
526+ #{} when map_size (Val ) > 0 ->
527+ match_val (Pred , maps :to_list (Val ));
528+ _ ->
529+ false
530+ end
531+ end .
532+
533+ -spec contains_val (term (), term ()) -> boolean ().
534+ contains_val (DataVal , Data ) ->
535+ match_val (fun (Val ) -> Val =:= DataVal end , Data ).
536+
511537% % @doc Executes the function call for the provided `t:tr()' record or index.
512538-spec do (tr ()) -> term ().
513539do (Index ) when is_integer (Index ) ->
@@ -701,9 +727,7 @@ create_tab(Tab) ->
701727select (_MS , _DataVal , DataAcc , '$end_of_table' ) ->
702728 lists :append (lists :reverse (DataAcc ));
703729select (MS , DataVal , DataAcc , {Matched , Cont }) ->
704- Filtered = lists :filter (fun (# tr {data = Data }) -> contains_val (DataVal , Data );
705- (T ) -> contains_val (DataVal , T )
706- end , Matched ),
730+ Filtered = lists :filter (fun (T ) -> contains_data (DataVal , T ) end , Matched ),
707731 SelectRes = ets :select (Cont ),
708732 select (MS , DataVal , [Filtered | DataAcc ], SelectRes ).
709733
@@ -713,12 +737,6 @@ filter_trace(F, T, State) ->
713737 _ -> State
714738 end .
715739
716- contains_val (DataVal , DataVal ) -> true ;
717- contains_val (DataVal , L ) when is_list (L ) -> lists :any (fun (El ) -> contains_val (DataVal , El ) end , L );
718- contains_val (DataVal , T ) when is_tuple (T ) -> contains_val (DataVal , tuple_to_list (T ));
719- contains_val (DataVal , M ) when is_map (M ) -> contains_val (DataVal , maps :to_list (M ));
720- contains_val (_ , _ ) -> false .
721-
722740index (Tab ) ->
723741 case ets :last (Tab ) of
724742 I when is_integer (I ) -> I + 1 ;
0 commit comments