(Something strange is indeed going on which does result in differences
between accumulate functions with and without reverse. But I see now
that this is not what worries you. Sorry - but read on.)
This particular condition:
when
$event: TestEvent( $key:key)
$total : Number( ) from accumulate( event : TestEvent( key ==
$key ) , test( 1 ) )
then
results in a first evaluation for the first TestEvent(), creating one
activation, binding $event to this TestEvent(). When the second
TestEent() is inserted, another activation is added, this time with
$event bound to the second TestEvent(), and another accumulate is
required. The first accumulate is extended to include the second
TestEvent; the second accumulate computes, from scratch, for both. The
same thing happens with the third TestEvent so that you now have three
separate accumulates.
If you want to compute once and only once for each value of
TestEvent.key, you'll have to avoid the spurious activations for
successive TestEvents with the same key, e.g.,
when
$event: TestEvent( $key:key )
not TestEvent( key == $key, this after $event )
$total : Number( ) from accumulate( event : TestEvent( key ==
$key ) , test( 1 ) )
then
-W
On 22/06/2012, ekzl(a)yahoo.com <ekzl(a)yahoo.com> wrote:
Hi Wolfgang,
I couldn't agree more with your analysis unfortunately it seems that or i
have something wrong with my rule or there is something wrong with the
implementation?
First off all the reserve was set to false this would mean that once the
rule is finished the context shouldn't be available any more and therefore
not updated when the rule is executed again (as recalculation would
require
all the facts to be processed again anyway). Now if my understanding is
correct then this is not how drools behaves, you can see evidence of this
in
the trace of the first post.
I tried returning true for the reverse but the behaviour is exactly the
same. Each new fact creates a new context then for all matching facts the
accuulate is called on that context. The accumulate method is called on all
existing contexts for the new fact.
Here is the rule (test just makes a sum of the values)
import eu.mc2bis.drools.TestEvent;
declare TestEvent
@role(event)
@timestamp( eventDate )
end
rule "test accumulator"
salience 100 // Make sure this rule is always executed by giving it a
very
high salience
no-loop true
when
$event: TestEvent( $key:key)
$total : Number( ) from accumulate( event : TestEvent( key == $key ) ,
test( 1 ) )
then
System.out.println("-- Rule output Total for key:" + $key + "
total:" +
$total);
end
here is the output with reverse:false
Main:inserting event with key:0
-> Accumulator: Context created:553
-> Accumulator: Init called for context:553
-> Accumulator: getResults() called for context:553
-> Accumulator: accumulate called for context:553 key:553 value:1
-> Accumulator: getResults() called for context:553
Main:fireAllRules start
-- Rule output Total for key:0 total:1
Main:fireAllRules finished
Main:inserting event with key:0
-> Accumulator: Context created:454
-> Accumulator: Init called for context:454
-> Accumulator: accumulate called for context:454 key:454 value:1
-> Accumulator: getResults() called for context:454
-> Accumulator: accumulate called for context:553 key:553 value:1
-> Accumulator: accumulate called for context:454 key:454 value:1
-> Accumulator: getResults() called for context:454
-> Accumulator: getResults() called for context:553
Main:fireAllRules start
-- Rule output Total for key:0 total:2
-- Rule output Total for key:0 total:2
Main:fireAllRules finished
Main:inserting event with key:0
-> Accumulator: Context created:695
-> Accumulator: Init called for context:695
-> Accumulator: accumulate called for context:695 key:695 value:1
-> Accumulator: accumulate called for context:695 key:695 value:1
-> Accumulator: getResults() called for context:695
-> Accumulator: accumulate called for context:553 key:553 value:1
-> Accumulator: accumulate called for context:454 key:454 value:1
-> Accumulator: accumulate called for context:695 key:695 value:1
-> Accumulator: getResults() called for context:695
-> Accumulator: getResults() called for context:454
-> Accumulator: getResults() called for context:553
Main:fireAllRules start
-- Rule output Total for key:0 total:3
-- Rule output Total for key:0 total:3
-- Rule output Total for key:0 total:3
Main:fireAllRules finished
Time (ms) required to update: 100k profiles = 30
Ended
I would have expected:
Main:inserting event with key:0
-> Accumulator: Context created:553
-> Accumulator: Init called for context:553
-> Accumulator: getResults() called for context:553
-> Accumulator: accumulate called for context:553 key:553 value:1
-> Accumulator: getResults() called for context:553
Main:fireAllRules start
-- Rule output Total for key:0 total:1
Main:fireAllRules finished
Main:inserting event with key:0
-> Accumulator: Context created:454
-> Accumulator: Init called for context:454
-> Accumulator: accumulate called for context:454 key:454 value:1
-> Accumulator: getResults() called for context:454
-> Accumulator: accumulate called for context:454 key:454 value:1
-> Accumulator: getResults() called for context:454
Main:fireAllRules start
-- Rule output Total for key:0 total:2
Main:fireAllRules finished
Main:inserting event with key:0
-> Accumulator: Context created:695
-> Accumulator: Init called for context:695
-> Accumulator: accumulate called for context:695 key:695 value:1
-> Accumulator: accumulate called for context:695 key:695 value:1
-> Accumulator: getResults() called for context:695
-> Accumulator: accumulate called for context:695 key:695 value:1
-> Accumulator: getResults() called for context:695
Main:fireAllRules start
-- Rule output Total for key:0 total:3
Main:fireAllRules finished
Time (ms) required to update: 100k profiles = 30
Ended
Here is the output with reverse:true
Main:inserting event with key:0
-> Accumulator: Context created:943
-> Accumulator: Init called for context:943
-> Accumulator: getResults() called for context:943
-> Accumulator: accumulate called for context:943 key:943 value:1
-> Accumulator: getResults() called for context:943
Main:fireAllRules start
-- Rule output Total for key:0 total:1
Main:fireAllRules finished
Main:inserting event with key:0
-> Accumulator: Context created:677
-> Accumulator: Init called for context:677
-> Accumulator: accumulate called for context:677 key:677 value:1
-> Accumulator: getResults() called for context:677
-> Accumulator: accumulate called for context:943 key:943 value:1
-> Accumulator: accumulate called for context:677 key:677 value:1
-> Accumulator: getResults() called for context:677
-> Accumulator: getResults() called for context:943
Main:fireAllRules start
-- Rule output Total for key:0 total:2
-- Rule output Total for key:0 total:2
Main:fireAllRules finished
Main:inserting event with key:0
-> Accumulator: Context created:968
-> Accumulator: Init called for context:968
-> Accumulator: accumulate called for context:968 key:968 value:1
-> Accumulator: accumulate called for context:968 key:968 value:1
-> Accumulator: getResults() called for context:968
-> Accumulator: accumulate called for context:943 key:943 value:1
-> Accumulator: accumulate called for context:677 key:677 value:1
-> Accumulator: accumulate called for context:968 key:968 value:1
-> Accumulator: getResults() called for context:968
-> Accumulator: getResults() called for context:677
-> Accumulator: getResults() called for context:943
Main:fireAllRules start
-- Rule output Total for key:0 total:3
-- Rule output Total for key:0 total:3
-- Rule output Total for key:0 total:3
Main:fireAllRules finished
Time (ms) required to update: 100k profiles = 32
Ended
I would have expected:
Main:inserting event with key:0
-> Accumulator: Context created:943
-> Accumulator: Init called for context:943
-> Accumulator: getResults() called for context:943
-> Accumulator: accumulate called for context:943 key:943 value:1
-> Accumulator: getResults() called for context:943
Main:fireAllRules start
-- Rule output Total for key:0 total:1
Main:fireAllRules finished
Main:inserting event with key:0
-> Accumulator: Init called for context:943
-> Accumulator: accumulate called for context:943 key:943 value:1
-> Accumulator: getResults() called for context:943
Main:fireAllRules start
-- Rule output Total for key:0 total:2
Main:fireAllRules finished
Main:inserting event with key:0
-> Accumulator: Init called for context:943
-> Accumulator: accumulate called for context:943 key:943 value:1
-> Accumulator: getResults() called for context:943
Main:fireAllRules start
-- Rule output Total for key:0 total:3
Main:fireAllRules finished
Time (ms) required to update: 100k profiles = 32
Ended
Thank you for being so patient with me I'm sure I must be doing something
wrong?
Can you point me out to some documentation or sequence diagram how this is
designed (if possible) or perhaps i just need to read the code ;-)
Best Regards,
e
--
View this message in context:
http://drools.46999.n3.nabble.com/Accumulator-being-executed-depending-on...
Sent from the Drools: User forum mailing list archive at
Nabble.com.
_______________________________________________
rules-users mailing list
rules-users(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users