Set and #oneWayBecome:

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

Set and #oneWayBecome:

Dmitry Zamotkin-5
Hello all,

Is there a good way to autoupdate hash of object in Set after performing
#become: method?

o1 := Object new.
o2 := Object new.
s := Set new.
s add: o1.
o1 oneWayBecome: o2.
s add: o1.
s size "2"

oc := s asOrderedCollection.
oc first == oc second "true"

s rehash
s size "1"

--
Dmitry Zamotkin


Reply | Threaded
Open this post in threaded view
|

Re: Set and #oneWayBecome:

Chris Uppal-3
Dmitry Zamotkin wrote:

> Is there a good way to autoupdate hash of object in Set after performing
> #become: method?

I can't think of anything better than:

    o1 := Object new.
    o2 := Object new.
    sets := o1 allReferences select: [:each | each isKindOf: Set].
    o1 oneWayBecome: o2.
    sets do: [:each | each rehash].

but it's kinda dodgy.  What about other objects that use the #hash, but aren't
Sets ?  Also, do you have to consider other Processes that might refer to the
the object ?  It'd be awkward if the object were changed after another Process
had computed its #hash, but before using the hash value (e.g. was half-way
through inserting the object into a Set).

I'd be interested to know what kind of situation means that you have to use one
of the #become* methods on an object that may have arbitrary references to it.
Maybe there's a way you can ensure that the two objects have the same #hash.

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: Set and #oneWayBecome:

Dmitry Zamotkin-5
Hello Chris,

> I'd be interested to know what kind of situation means that you have to
use one
> of the #become* methods on an object that may have arbitrary references to
it.

I've a OR-mapper with a LookupTable, uids are keys and persistent objects
are values. During data reading object with existing uid replaces "old"
object with same uid. And Set is part of caching mechanism for a quick
searching, elements are persistent.

> Maybe there's a way you can ensure that the two objects have the same
#hash.

Thanks, I suppose it's a solution.

--
Dmitry Zamotkin


Reply | Threaded
Open this post in threaded view
|

Re: Set and #oneWayBecome:

Chris Uppal-3
Dmitry,

> I've a OR-mapper with a LookupTable, uids are keys and persistent objects
> are values. During data reading object with existing uid replaces "old"
> object with same uid. And Set is part of caching mechanism for a quick
> searching, elements are persistent.
>
> > Maybe there's a way you can ensure that the two objects have the same
> > #hash.
>
> Thanks, I suppose it's a solution.

I'd be tempted to make the uid (or something derived from it) be the objects'
default #hash, that way most Sets would be unaffected as you updated your
objects.

There'd still be a problem with objects that override #hash/#equals to provide
their own idea of equality based on their state, but maybe that's not something
you have to worry about in general[*].  You can use a PluggableSet which forces
the use of the uid-based hash for your cache, so that would be unaffected by
any objects that do override equals/hash.

([*]  Any application that stores long-lived objects with state-based equality
in a Set must have some way of dealing with changes to their state.  So they
will /have/ to arrange to be told when that state is changed by your OR
layer -- it's not something that you can be expected to automate, I think.)

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: Set and #oneWayBecome:

Blair McGlashan
In reply to this post by Dmitry Zamotkin-5
"Dmitry Zamotkin" <[hidden email]> wrote in message
news:c9f5d1$1t3t$[hidden email]...
> Hello Chris,
>
> > I'd be interested to know what kind of situation means that you have to
> use one
> > of the #become* methods on an object that may have arbitrary references
to
> it.
>
> I've a OR-mapper with a LookupTable, uids are keys and persistent objects
> are values. During data reading object with existing uid replaces "old"
> object with same uid. And Set is part of caching mechanism for a quick
> searching, elements are persistent.

I think you should reconsider the use of #oneWayBecome: for this purpose
anyway. It doesn't preserve object identity (hence the problem with hashed
collections that you have encountered), and it is also a slow operation that
requires a complete memory scan. Its actual speed will depend on the speed
of your machine and the number of objects in your image, but it is going to
be tens of milliseconds per operation. Although it is fast enough when used
a few times, once you start to load a few thousand objects it is probably
going to be too slow. #become:, on the other hand, is virtually
instantaneous (at least 100,000 times faster) and also preserves object
identity. However, as Chris points out, you may still encounter issues with
hashed collections that are based on a hash of the value of the object (as
opposed to its identity hash).

Regards

Blair