Retrieving zero answers using mnemosyne

Hakan Mattsson hakan@REDACTED
Tue Dec 21 19:32:38 CET 1999


On Tue, 21 Dec 1999, Sean Hinde wrote:

Sean> I am writing an application which will retrieve zero or one answers from a
Sean> mnemosyne query but have hit a problem.
Sean> 
Sean> mnemosyne:next_answers/3 appears to be the only way to get a single answer
Sean> from a match type query but if there are no matches it hangs. The obvious
Sean> thing to do is set Nmin to 0 but this is not allowed.
Sean> 
Sean> Has anyone come across this problem before or have any suggestions of how to
Sean> retrieve a single match out of potentially more then one result?

Which version of Mnemosyne do you use?
In earlier versions Mnemosyne had the problem of not returning any
answers even if there was matching records. I think hovewer that
this issue has been fixed.

I don't really know why Mnemosyne hangs in your query, but I suspect
that it is the mnesia:write/1 call inside the query that is the problem.
In fact, a query is not allowed to have any side effects at all.

Picking just one answer looks rather nice in the Mnemosyne API, but in
fact all answers are fetched and allocated on the heap, possibly sent
as messages between a couple of processes and eventually one answer is
returned to you. A plain:

    assign(User) ->
        Wild = mnesia:table_info(ip_pool, wild_pattern),
        case mnesia:match_object(Wild#ip_pool{user = []}) of
            [] ->
                mnesia:abort(no_spare_ip_addresses);
            [IP | _] ->
                mnesia:write(#ip_pool{ip = IP,
                                      user = User,
                                      timestamp = now()}),
                IP
	end.
   
    mnesia:transaction(fun assign/1, [User]).

is a more efficient way to just pick one answer and then possibly
update the matching record. (And it does not hang.)

/Håkan

Sean> 
Sean> Thanks,
Sean> 
Sean> Sean
Sean> 
Sean> %% Example of what I am trying to achieve..
Sean> assign(User) ->
Sean>     Handle = 
Sean> 	query
Sean> 	    [ I.ip || I <- table(ip_pool),
Sean> 		      I.user == [] ]
Sean> 	end,
Sean>     F = fun() ->
Sean> 		Cursor = mnemosyne:cursor(Handle),
Sean> 		case mnemosyne:next_answers(Cursor,1,1) of
Sean> 		    [] ->
Sean> 			mnesia:abort(no_spare_ip_addresses);
Sean> 		    [IP] ->
Sean> 			mnesia:write(#ip_pool{ip = IP,
Sean> 					      user = User,
Sean> 					      timestamp = now()}),
Sean> 			mnemosyne:delete_cursor(Cursor),
Sean> 			IP
Sean> 		end
Sean> 	end,
Sean>     mnesia:transaction(F).
Sean> 




More information about the erlang-questions mailing list