Capturing finalized objects

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Capturing finalized objects

Sebastián Sastre
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


Reply | Threaded
Open this post in threaded view
|

Re: Capturing finalized objects

Chris Uppal-3
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


Reply | Threaded
Open this post in threaded view
|

Re: Capturing finalized objects

Blair McGlashan
"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


Reply | Threaded
Open this post in threaded view
|

Re: Capturing finalized objects

Sebastián Sastre
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