Mnesia query: less or equal than given key

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Mnesia query: less or equal than given key

Ulf Wiger (AL/EAB)

Erik Reitsma wrote:
>
> Using mnesia, is there an efficient way to find the smallest
> entry in a table with a key equal to or less than a given key?

It appears as if you intended to write "the _largest_ entry
with a key equal to or less than a given key".


> So suppose that I have keys 10, 23, 33, 34, 56, 100 and I
> look for 26, I want to get 23 back. If I look for 23, I should get 23.

Here's a first suggestion:

(ord)3> mnesia:create_table(test,[{type, ordered_set}]).
{atomic,ok}
(ord)4> [mnesia:dirty_write({test,N,a}) ||?N <- [10,23,33,34,56,100]].
[ok,ok,ok,ok,ok,ok]
(ord)5> F = fun(N) ->
          mnesia:transaction(
             fun() ->
               case mnesia:read({test,N}) of
                  [] ->
                     case mnesia:dirty_prev(test,N) of
                        '$end_of_table' -> [];
                        Prev -> mnesia:read({test,Prev})
                     end; [Obj] -> Obj
               end
              end)
          end.
#Fun<erl_eval.6.10732646>
(ord)6> F(26).                                                         {atomic,[{test,23,a}]}                                                          (ord)7> F(23).                                                         {atomic,{test,23,a}}                                                            (ord)8>                                            

It's not 100% safe, since dirty_prev bypasses the
transaction store, while the second read() doesn't.


/Uffe