Well, you are saying that if you are using references
to fact objects in combination with constraints comparing such a
reference to some other object any (overridden) hashCode method must
not refer to mutable fields of that object.
hashCode method must not refer to mutable fields of
that object.
That's not a good idea really. Hashcode's should refer to fields
that you constrain on, as a general good rule. and those fields are
normally mutable.
I don't really know what more to say than...
Nested accessors are "black box" if you modify a nested accessor you
must notify the root object(s) that are inserted into the engine.
If you want to write up some paragraphs talking people through how
hashcode's and hashmap's work. Specifiically if you change the
hashcode of an object that is in map you won't be able to find it in
the map any more - which is what is happening to you. Notification
effectively takes the root object out and put's it back in again, so
it lives in the correct index.
This is why other engines don't support Objects as fields, you can
only use values - strings, numbers etc. For them it's worse though,
they have to use techniques like shadow facts otherwise they get
memory corruption - but shadow facts only work on direct values, and
cannot shadow objects and nested fields. If you tried to do this
stuff in other engines they would just get corrupted. It's only
because we do a tree-graph based rete network for assymetrical
retract that we can allow you to do this without corruption, but you
must still notify the engine.
Mark
Certainly: this restriction should not hurt - I'm inclined to
regard mutable hashCode methods as "suspicious" anyway.
But, nevertheless, it deserves a short paragraph in the "Expert"
manual, don't you think so?
If I have
class Type {
int field;
setField( int f ){ field = f; }
}
and do
modify( $type ){ setField( 42 ) }
where is there a "nested accessor"?
$one: One()
$two: Two( $x: one == $one )
If you change a field on object "one". that field is a
nested accessor to Two.
one.field1 = "x"
is the same as doing
two.one.field1 = "x"
so to "two" changing the field of 1 is a nested accessor.
Think about how indexing works.
left == right
when two objects are == each other indexing creates a bucket
for the left and a bucket for the right. If you change the
hashcode of the one on the right, how will it find the
bucket on the left?
Assume this: A is a field of B is a field of
C is a field of D is a...
Object references remain the same, in all
objects; I simply modify A, and
"when you change [A] you are also changing
[B], so I must notify the
engine for [B]" but that's a field of C...
D... E... and so on, until
'I' for infinity?!
It's just a change in some fact
object's hashCode that causes this
problem.
If you don't want any indexing in your rule
engine. If you want indexing, you have to notify
the engine. Changes to nested accessors have
always been invisible to the engine. If a nested
access changes, you must notify the engine of
the root fact.
Mark
-W
On 22 June 2011 22:37, Mark Proctor <mproctor@codehaus.org>
wrote:
> As One is a field of Two. When you
change One you are also changing Two, so
> you most notify the engine for Two
too.
>
> MArk
> On 22/06/2011 14:37, Wolfgang Laun
wrote:
>
> To avoid misunderstandings: yes,
equals() is written according to hashCode,
> i.e., according to the usual Java
conventions.
>
> If
>
> - an object of class Two contains
a member of class One, and
> - one object Two and one object
One are facts, and
> - a rule modifies One, changing
its hashCode
>
> then
>
> another rule containing the
patterns
> $one: One()
> $two: Two( $x: one == $one )
>
> does NOT fire (any more).
>
> If you use the constraint
> one == $one || != $one
> the rule will fire, and you can
observe that hashCode results for $one and
> $x are the same and that $one.equals(
$x ) returns true.
>
> Reproduced using 5.1.1 and 5.2.x
>
> -W
>
>
>
>
>
_______________________________________________
> rules-dev mailing list
> rules-dev@lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-dev
>
>
>
_______________________________________________
> rules-dev mailing list
> rules-dev@lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-dev
>
>