Hi all,
as I've said before, I'm porting the Avi Bryant's GOODS (objects database engine) client. Right now we have a version that could be useful to make some tests. It is not in production yet because is too young ;) (pre-alpha?) It's available in: http://gatekeeper.dynalias.org:8888/GoodsST/4 At some point the client must to say to the server what objects aren't referenced anymore. In squeak this code: wkd := WeakIdentityKeyDictionary new. wkd at: OrderedCollection new put:123. dict := Dictionary new. wkd at: dict put:457. wkd at: TreeSet new put:879. cache := Dictionary new. Smalltalk garbageCollect. finalized := OrderedCollection new. wkd keysAndValuesDo: [:object :key | object ifNil: [finalized add: key] ifNotNil: [cache at: key put: object]]. ...gives the following results (copy pasted): finalized 'an OrderedCollection(123 879)' cache 'a Dictionary(457->a Dictionary() )' I'm triyng to replicate the same behavior in dolphin with: wkd := WeakIdentityDictionary newWithWeakKeys. wkd at: OrderedCollection new put:123. dict := Dictionary new. wkd at: dict put:345. wkd at: TreeSet new put:657. cache := Dictionary new. MemoryManager current collectGarbage. finalized := OrderedCollection new. wkd keysAndValuesDo: [:object :key | object ifNil: [finalized add: key] ifNotNil: [:o| cache at: key put: o]]. ...but I'm having this unsuccesful results: cache a Dictionary(345 -> a Dictionary()) finalized an OrderedCollection() I doesn't see any obvious way to capture the finalized objects of that dictionary after a garbage collection. Any body could help this soul? thank you in advance, -- Sebastián Sastre [hidden email] www.seaswork.com.ar |
Sebastián Sastre wrote:
> I doesn't see any obvious way to capture the finalized objects of that > dictionary after a garbage collection. Two ways. One, which is probably not relevant in your case, is to ensure that all GOODS objects are represented in Dolphin space by "special" objects that know that they stand for something in the GOODS system, and which have a dedicated #finalize method that does its own cleanup. In some ways that's cleanest, but is only applicable if you are willing to restrict the classes of objects that can stand for GOODS data, which I doubt in this case. Otherwise, I think you'll either have to roll your own solution, or base one on MourningWeakArray. I have never tried this myself, so be warned... The basic idea is that you keep a map from objects to the "handles" for those objects in the GOODS server (presumably some kind of integer). When the Dolphin system "kills" a reference in a weak object it sets the corresponding slot in that object to DeadObject current *and* then sends #elementsExpired: to the weak object. This only happens, as I understand it, if the *class* of the weak object has been marked as a "mourner" by sending it #makeMourner sometime (in the class #initialize for instance). You can take a look at the implementations of WeakSet and MourningWeakArray to see examples of this. MourningWeakArray is (again, as I understand it) intended to pre-package this functionality. It has a #pathologist which is an external object to which it will send #elementsExpired:of: when some of its slots have been "killed". Incidentally, #pathologist[:] are private methods, but I presume that's a mistake since the class is pointless without them; perhaps there was supposed to be a class-side instance creation methods #withPathologist:, or something, that never materialised. So you can keep your references to GOODS objects in a MourningWeakArray, and keep GOODS handles in a corresponding normal Array, and make yourself be the #pathologist (love this morbid nomenclature). When you are sent #elementsExpired:of: you scan the MourningWeakArray and find the slots that have been killed (see #corpsesDo:), you then tell the GOODS server to release the handles at the corresponding indices in the Array of handles. All this needs Mutex protection, I think[*]. The implementation of WeakLookupTable provides an example of this, since it keeps its "values" in a MourningWeakArray. [*] Although EventMessageSequence uses a MourningWeakArray with no mutex protection -- I haven't worked out how it gets away with it. -- chris |
"Chris Uppal" <[hidden email]> wrote in message
news:[hidden email]... > ... > [*] Although EventMessageSequence uses a MourningWeakArray with no mutex > protection -- I haven't worked out how it gets away with it. > It carefully checks that the entries are still valid before firing them as well as repairing losses in its #elementsExpired:of:, relying on certain known characteristics of the implementation. I wouldn't recommend this as a general technique though. (Excellent summary, BTW). Regards Blair |
In reply to this post by Chris Uppal-3
In some ways that's
> cleanest, but is only applicable if you are willing to restrict the classes of > objects that can stand for GOODS data, which I doubt in this case. You're right, that it's not applicable to this case. > Otherwise, I think you'll either have to roll your own solution, or base one on > MourningWeakArray. I've managed to implement a WeakIdentityKeyDictionary on dolphin (that is based on a MourningWeakArray and WeakValueAssociation). When this dictionary executes #elementsExpired:, I've made it to trigger a collection with the values of the expired keys (mourn by default). In this way the KKKeyCache can hook that event and tell to the engine to forget the derreferenced ones. I'm testing it, I think it could work. thanks for that clue ! regards, -- Sebastián Sastre [hidden email] www.seaswork.com.ar |
Free forum by Nabble | Edit this page |