mneisa, mnemosyne questions...

Hakan Mattsson hakan@REDACTED
Tue Aug 22 10:56:43 CEST 2000

On Fri, 18 Aug 2000, Mike Tilstra wrote:

> Two questions here, hopefuly someone can answer these.
> First: Using mnemosyne to get a subset of a table, (with the cursor calls).
> Is there any way to get the N smallest that are greater than X?  I have a
> section where I need to grab the next 64 items in sequenced order that
> have the use field set to false. (I want the next 64 in order that are
> true.)  (did that make anysense?)  I managed to get something working the
> way I want using match_object and a loop, but I was hoping that I could use
> a query for it.

It is a little bit unfortunate that Mnemosyne has such a nice syntax,
since it often leads to an overuse of Mnemosyne. The Mnemosyne
application is purely implemented on top of Mnesia, using the same API
as ordinary Mnesia applications.

A simple Mnemosyne query requesting only a few solutions boils down to a
mnesia:match_object/3. Implying that all solutions first are copied to
the process heap by ets/dets, then all but the few solutions you asked
for are dropped. For more complex queries, the solutions are copied
a few times more as the solutions are sent as messages between internal
Mnemosyne processes and stored in a intermediate ets table.

The greater then X comparison in your query implies that your query
will be classified as a complex query.

Nowdays ets has a extended match capability that allows "pico
queries", enabling a wider range of comparison operators, than simple
equality as in match_object.  By using these pico queries more of the
query evaluation can be made much more efficient by pushing it down
into the ets-BIFs. But so far the corresponding functionality lacks
both in dets and Mnesia.

If you have extreamly high performance requirements and is hosting the
table in a local ram_copies table, you have the option of using the
new efficient matching capabilities directly in ets rather than
waiting for the new functionality to be offered via dets' API,
Mnesia's API and eventually by Mnemosyne.

But if you have moderate performance requirements I would recommend you
to use mnesia:match_object/3.

> Second: sometimes, I need to grab any entry in the table that has the use
> field set to false.  Is there a fast way to do this?  I've tried a couple
> of things, and they are all pretty slow.  (slower than looping over the
> *entire* table of 10000 elements)  (so the fastest method I've found so
> far, is to loop over the elements, until I find one that is set to false.
> This is icky.)

Try one of these methods to find all elements with the 'use' attribute
set to 'false':

    -record(rec, {key, use, foo, bar, etc}).
    safe_q(Tab) ->
       Wild = mnesia:table_info(Tab, wild_pattern),
       mnesia:match_object(Tab, Wild#rec{use = false}, read).
    dirty_q(Tab) ->
       Wild = mnesia:table_info(Tab, wild_pattern),
       mnesia:dirty_match_object(Tab, Wild#rec{use = false}).

For the time being you have to post process the solutions by sorting
them and perform the greater then comparison in order to make your
query complete.


Håkan Mattsson
Computer Science Laboratory

More information about the erlang-questions mailing list