Why is MagmaSession>>#noteOldKeysFor: necessary?

Chris Muller asqueaker at gmail.com
Tue Jan 5 04:21:56 UTC 2010


> On: http://wiki.squeak.org/squeak/5605 you mention that option 3) autocommit
> is completely transparent. I disagree, since the signalNoteOldKeys message
> on a session is absolutely necessary to make it work correctly. I can
> understand your reasoning about the performance hit if you have to check
> everything.

Yeah, I agree with you.  I've removed that sentence.

> I will try out option 2) because the other I suggested is just too complex.
> I still have my doubts about the transparency of this option. Out of
> experience I know that most code is modified after being written. What the
> developer now has to remember is that if an index is added to some magma
> collection is to add the signalNoteOldKeys: in the mutator of it.

For clarification, signalNoteOldKeys: need only be called when instVar
an object will cause one of its indexed attributes to change.  Nothing
needs to be done when "an index is added to some magma collection."

Using the Smalltalk browser to browse "definitions" of a particular
instVar, all changes to an indexed attribute is presented.  Usually,
attributes of an object are modified in just one or two places (like
#initialize and a setter).  So this is the only place you would need
to put it, and only for indexed attributes.

Incidentally, there is a parallel "lack-of-transparency" in standard
Smalltalk and even, if I am not mistaken, Java.  If you were to use a
standard Dictionary / HashTable to look up objects, when something
causes an objects #hash / hashCode() to change, the Dictionary must be
rehashed; I actually cannot remember if this is true in Java but it is
with Smalltalk.

> Thats
> error prone. That is the reason I tried to do that completely automatically.
> You set up it correct one time and move on, just don't have to think about
> it again.

It is an unfortunate piercing of the transparency.  For me its impact
has been very limited and isolated; but then, I mostly only use
MagmaCollections for keyword searching my domain models.  I put a
#signalNoteOldKeysFor: in my #description: setter and, done.

> The index I'm trying to create makes this more error prone: I have a root
> object which is in a MagmaCollection. It has a keywords index. The keywords
> are made up of a list which contains multiple fields of the root object but
> also of a list of fields of the sub objects of this root. Using this, I can
> implement a kind of google search box in which you can find keywords
> dispersed over my entire domain and let Magma retrieve the correct aggegrate
> root, and I would not have to integrate any kind of full text search
> technology to do this. The reason I wanted it to be transparent is that if I
> for instance add a new field on this keywords list, I now have to remember
> the signalNoteKeys on this setter, (which is error prone ...).

Ah, thank you for the explanation.  May I offer a couple of suggestions?

Option 1)  Can the "sub-objects" know their parent / "root" object?
If so, instead of indexing your root object by it's keywords and all
of its sub-objects key-words, just make the root object respond with
its *own* keywords.  Make each sub-object respond with its *own*
keywords too.  Add the sub-objects to the MagmaCollection as well as
the root object.  When a Reader of objects is found, display them all
of them (a heterogeneous list) or, if the sub-objects are not wanted,
traverse up their parents to the "roots" and put them into a Set (to
avoid presenting duplicates to the user).  This way, you only need
#signalNoteOldKeysFor: in just the keywords setter of each type of
object that can be searched.

Option 2)  Throw the MagmaCollection, indexes, and all the calls to
#signalNoteOldKeys: out the window.  Implement #maContextKeywordsDo:
on all domain objects you want to have keyword search capability
(otherwise, the printString of the object will act as its keywords!).
As in Option 1, each domain object only values the passed in Block
with its *own* keywords.

You can then send, #maNewSearchContext to any object in order to
search its "sub-objects".  This search object runs in the background,
provides progress indication, provides results as they are found (so
research can begin concurrently), and even orders the results
according to how well they matched (e.g., whole match first, then
front match, finally substring match).  The results, themselves, are a
searchable context.  Multiple contexts can even be grouped into
"CompositeContexts" so that one keyword can search a number of
sources.

To learn more about this, start at the class MaAbstractContext, its
class comment.  This framework is pretty easy to use and it works.

Option 3)  Implement your own visitor to do a search similar to (2).

> You say that it is slow. Did Magma once provide this auto notify keys
> functionality? I think I could maybe live with the bit slower performance

It won't hurt anything to send #noteOldKeysFor: even if the key, in
fact, did not change.  I know there are places to hook to send
#noteOldKeysFor: to every object so that Magma will appear to
automatically detect it..  But please evaluate other options first, as
I would like to wrap up this e-mail for now..   :)

Man, I sure wish more folks had your good patience!  Someone else
recently said Magma is "dog-slow".  It may be, but I like dogs.  :)
Hopefully Cog will help someday!

Cheers,
  Chris


More information about the Magma mailing list