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