Robert Klemme
10/26/2004 5:56:00 PM
"Markus" <markus@reality.com> schrieb im Newsbeitrag
news:1098808602.21256.755.camel@lapdog.reality.com...
> On Tue, 2004-10-26 at 08:54, Robert Klemme wrote:
>> "Markus" <markus@reality.com> schrieb im Newsbeitrag
>> news:1098804673.21256.734.camel@lapdog.reality.com...
>> > On Tue, 2004-10-26 at 02:14, Erwan Loisant wrote:
>> > > What could be a better design? I there a way to design my C library
>> > > better so I can tell Ruby's garbage collector about references
>> > > without
>> > > introducing a Ruby dependency in my library's source code ?
>> >
>> > One idea might be to give ruby "handles" of some sort that were
>> > only usable/meaningful via calls to your library. As far as ruby's GC
>> > was concerned, they would just be integers. You would then be able to
>> > manage your storage as you saw fit, and ruby would be able to do
>> > likewise.
>>
>> IMHO this is probably the most reasonable approach. Additionally Erwan
>> should then have some mechanism of verifying the handle stored in a
>> wrapper object to be able to detect the situation that you have a wrapper
>> whose corresponding C model instance is gone. Unfortunately you would
>> have to check the validity in every method that needs the C model
>> instance
>> or even in *every* method. Alternatively you need some kind of observer
>> mechanism so your Ruby model instances get to know that their C model
>> counterparts are gone. But even then you still some other object might
>> reference the Ruby model instance...
>>
>> Another issue is aliasing: depending on the application it might be
>> crucial that you have at most one Ruby model instance per C model
>> instance, i.e., you want the same representant on the higher level. This
>> is typically the case when you store additional state in the wrapper
>> instance. You can handle this with some sort of mapping - but you'll
>> have
>> to be careful with respect to GC in order to not fix wrapper instances in
>> mem: You might need a Hash where values are WeakReferences to the
>> wrapping
>> instances.
>>
>> This is all not very nice and personally I haven't found a clean, nice
>> and
>> efficient solution to this issue...
>
> If he wants to be truly independent of ruby (so that his library
> can be used elsewhere) I would suggest the following:
>
> * Assign each C object a handle (int) on creation.
> * Store the handle in the object
> * Maintain an index mapping handle --> C object
> * Only talk to outsiders in terms of handles
> * When an outsider tries to talk to you about a C object, first
> check that the handle is valid (via the index)
>
>
> There are several operations that would need to be implemented in
> the library:
>
> * Assigning a handle
> * Adding a handle=>object to the index
> * Looking up an object given a handle
> * Cleaning up the index when an object is deleted
> * Detecting if an object is valid
>
> All of them admit to rather simple, time & space efficient
> solutions, provided you know what sort of load (lots of lookups, few
> creations, or visa versa, etc.) to expect. For example, if deletions
> were going to be rare or done all at the end, the index could be a
> hierarchical array and:
>
> * Assigning a handle-- this_handle = (next_handle++)
> * Adding a handle=>object to the index --
> index[this_handle] = this_object
> * Looking up an object given a handle -- index[handle]
> * Cleaning up the index when an object is deleted --
> index[this_handle] = NULL
> * Detecting if an object is valid -- index[handle]
>
>
> If there was going to be more turnover, you could use a hash for
> the index, or store an additional id with the object (and in the index)
> to detect recycled handles. In effect, the handle becomes a
> (slot,version) pair. The later may be a tad faster but a hash is less
> ad hoc and might be easier to maintain.
Completely ACK! Still, these solutions do not get rid of the problem of
orphaned handles, which renders them somehow ugly. But the ugliness is in
the problem, not in the solution. *sigh*
Kind regards
robert