Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Erlang: optimize complex qlc

Tags:

I have qlc

RefsBlocked = qlc:e(qlc:q([
    Ref1 ||
    {{Ref1, {pattern, {_Status1, _Pattern1, Limit1}}}, Count} <- dict:to_list(
        qlc:fold(
            fun({Key, _Ref2}, Acc) ->
                dict:update_counter(Key, 1, Acc)
            end,
            dict:new(),
            qlc:q([
                {{Ref1, {pattern, {Status1, Pattern1, Limit1}}}, Ref2} ||
                {Ref2, {status, Status2}} <- ets:table(Tmp),
                {Ref3, {tag, Tag3}} <- ets:table(Tmp),
                Ref2 =:= Ref3,
                {Ref1, {pattern, {Status1, Pattern1, Limit1}}} <- ets:table(Tmp),
                Ref =:= Ref1,
                Status1 =:= Status2,
                Pattern1 =:= Tag3
            ])
        )
    ),
    Count >= Limit1
], unique))

where Tmp is an ets of type bag and Ref is a particular identifier I need to test.

Ets contains from hundreds to thousands of entries like

{Ref1, {definition, {Tuple1}}}
{Ref1, {status, scheduled}}
{Ref1, {status, blocked}}
{Ref1, {pattern, {scheduled, Pattern11, Limit11}}}
{Ref1, {pattern, {dispatched, Pattern12, Limit12}}}
{Ref1, {tag, Tag11}}
{Ref2, {definition, {Tuple2}}}
{Ref2, {status, scheduled}}
{Ref2, {status, dispatched}}
{Ref2, {pattern, {scheduled, Pattern21, Limit21}}}
{Ref2, {pattern, {dispatched, Pattern22, Limit22}}}
{Ref2, {tag, Tag21}}
{Ref3, {definition, Tuple3}}
{Ref3, {status, error}}

i. e. for each Ref there is one definition, one or two (of four) statuses, zero or more (in most cases no more than 3) patterns and zero or more (in most cases no more than 3) tags.

I need to test whether one particular identifier is blocked by others. It is blocked when the number of identifiers matching any of its patterns on their Tag = its Pattern and their Status = its pattern Status is more or equal to its pattern Limit.

Is there a way to optimize qlc?

like image 918
trytrytry Avatar asked Apr 12 '11 11:04

trytrytry


1 Answers

Unless you have a different, more efficient equality relation to use, the code you have there is as good as it gets. I imagine you've profiled this code and found it too slow? In what way?

like image 145
troutwine Avatar answered Oct 04 '22 16:10

troutwine