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

Erik Reitsma (RY/ETM)-2
It works very nicely, thanks! I was not aware that mnesia:dirty_prev/2 would work like this.

> 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".

Yes, you understood me correctly. :)

> > 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.

I will be accessing the table from one process anyway, so there should not be a problem.

*Erik.