Drools: Firing a rule if a set of events has n distinct values for a property -
suppose have event
type has 3 properties: constraint
, common
, , distinct
. goal write rule in drools fires when subset of event
s exists meets following criteria:
event
s happened in last t seconds; andevent
s have known valueconstraint
property; and- share unknown value
common
property; and - there @ least n different values
distinct
property
if rule fires, need set of participating events further processing.
how advise approach problem?
note 1: question similar link, , steve's answer there seems promising incomplete.
note 2: performance of essence. have developed rules task, reduce performance of whole rule-base dramatically, , unacceptable.
edit 1: current (poorly performing) solution looks this:
rule "" when $event : event(constraint == constant_value) $events : arraylist() collect( event(constraint == constant_value, common == $event.common) on window:time( t )) $distinctvals : set( size >= n ) accumulate(event($d : distinct) $events, collectset($d)) // process $events end
drools isn't meant used computations require repeated evaluations of potentially big set of facts. in such situation you'll have offload details java code.
class collector { string constraint; string common; list<event> events = ...; // or queue map<string,list<event>> dist2events = ...; int diversity; public void addevent( event e ){ // 1. remove event sets x events older t // 2. remove members of x dist2events, // delete map elements value list empty events.add( e ); list<event> ofdistinct = dist2events.get( e.getdistinct() ); if( ofdistinct == null ){ ofdistinct = new arraylist<event>(); dist2events.put( ofdistinct ); } ofdistinct.add( e ); diversity = dist2events.keyset().size(); } } rule createcollector when event( $constraint: constraint, $common: common ) not collector( constraint == constraint, common == $common ) insert( new collector( $constraint, $common ) ); end rule addevent when $event: event( $constraint: constraint, $common: common ) $collector: collector( constraint == constraint, common == $common, events not contains $event ) modify( $collector ){ addevent( $event ) } end rule morethan when collector( $constraint: constraint, $common: common, $events: events, diversity >= n ) // maybe when n-1 n? ... process $events end
you'll have decide whether want rule fire when threshold n exceeded or whenever set changes while diversity >= n.
you might want add rule remove empty collectors.
Comments
Post a Comment