mapmaker: hash method odds with weak and soft strength

9 views
Skip to first unread message

Mario Ivankovits

unread,
Oct 3, 2009, 10:18:20 AM10/3/09
to Google Collections Library - users list
Hi!

Today I tried to use google collections MapMaker to create a map as
replacement for Javas WeakHashMap.

Using new MapMaker().weakKeys().makeMap() I thought I am done.

But a Map created that way will not be able to find the entry again if
the key overrides .hashCode() and .equals() simply due to the fact the
the Strength enum in MapMaker for WEAK and SOFT strengths will use
object identity to match the keys.

Is there any reason for this?

The problem is, that I have the key somewhere stored as strong
reference so that the entry will not be gc'ed, but I also have the key
serialized over the network where it come back as a different
instance, but with the some content so that .hashCode() and .equals()
will make up to the same key - but the lookup into the map fails.

I'd suggest to change that to the same handling of hashCode() and
equals() as STRONG do, or at least to open up the api to have our own
Strength implementations. Or you could provide a WEAK_EQ and SOFT_EQ?


Thanks!

Ciao,
Mario

Kevin Bourrillion

unread,
Oct 3, 2009, 11:59:44 AM10/3/09
to Mario Ivankovits, Google Collections Library - users list
On Sat, Oct 3, 2009 at 7:18 AM, Mario Ivankovits <mario.iv...@gmail.com> wrote:

I have the key somewhere stored as strong
reference so that the entry will not be gc'ed,

Then why use .weakKeys() for the map at all?


--
Kevin Bourrillion @ Google
internal:  http://go/javalibraries
external: guava-libraries.googlecode.com

Mario Ivankovits

unread,
Oct 3, 2009, 12:17:06 PM10/3/09
to Google Collections Library - users list
> > reference so that the entry will not be gc'ed,
>
> Then why use .weakKeys() for the map at all?

To have the value gc'ed when I remove my strong reference. Just for
what this map has been built for.

The point is, at the moment you can not access the value using a key
which implements .equals() and .hashCode(). This is a problem at least
if you have to deal with serialization/deserialization.
It is clear, that the value might have been gc'ed as the map does not
know anything about my serialized key, but this is an expected
behaviour.

Ciao,
Mario

Kevin Bourrillion

unread,
Oct 3, 2009, 12:47:33 PM10/3/09
to Mario Ivankovits, Google Collections Library - users list
Mario,

Please read

http://code.google.com/p/google-collections/issues/detail?id=250

do you have anything to add?

Mario Ivankovits

unread,
Oct 4, 2009, 2:28:25 AM10/4/09
to Google Collections Library - users list
Hmm .... for me it was always clear that the entry is reclaimed once
the INSTANCE of the key-object I used is gc'ed, but I can use any
instance of a key to get the entry as long as it follows the contract
of HashMap, those are correctly implemented hashCode() and equals()
methods.

My actual use case is, that I have a client/server system here where
the server provides services which the client can access using
"handles", those handles are stored in a WeakHashMap on the server
(and somewhere else on the server). Once the key is removed from the
"somewhere else" place, the entry in the WeakHashMap is allowed to be
reclaimed.
For the time it stays in the WeakHashMap, the client is able to access
this service using the handle it retrieved from the server. Due to the
fact that it is serialized through the wire, it is not possible to use
the same instance to access the map.
It might happen that the client tries to access the service but the
handle has been reclaimed already, but this is by design.

Anyway, I understand your technical concerns as outlined in the issue
and that you don't want to have your API to behave "not clean".
The thing I'd like to ask, is, to make the Strength enum an abstract
class instead of a private enum and make the setXXXXStrength methods
public. That way we can provide our own Strength implementations. If
then the WEAK, SOFT, STRONG implementations are also public we can
inherit from e.g. WEAK and having the behaviour we would like to have
is just a two liner then.

Beside anything else, it would be nice to have this customizable at
all. :-)

This can be implemented without breaking backward compatibility of the
api.
If wanted, I can provide a patch.
Reply all
Reply to author
Forward
0 new messages