cogitate / guava-libraries

Automatically exported from code.google.com/p/guava-libraries
Apache License 2.0
0 stars 0 forks source link

MapMaker add ability allow key matching using equals rather than identity. #337

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
I would like to use MapMaker to hold a cache of objects, but lookups fail
because my keys are equal but the same. Id imagine with maps with String
keys are constnatly being rebuilt and equal but not the same and this
feature would be useful.

MapMaker{
   keyEquality();  // overrides default "identity equality".
}

Original issue reported on code.google.com by miroslav...@gmail.com on 5 Mar 2010 at 11:33

GoogleCodeExporter commented 8 years ago
We might be providing this in the future.  But note that this is a feature that 
way, 
way more users *think* they need than actually need it.

Here was the previous WontFix bug:
http://code.google.com/p/google-collections/issues/detail?id=250

Original comment by kevinb@google.com on 9 Apr 2010 at 7:23

GoogleCodeExporter commented 8 years ago
250 has many good points, the most important being that 
using a always strong ref (like the ones returned by 
long.valueof()) are a poor choice when using a map based on 
non strong keys, because the Long will never go weak etc. 
Interned strings as keys are also bogus for the same reason 
of course.

However mapmaker as it is with equality means it's not really 
a cache because one can't rebuild a key. One must already 
have the key and one wishes to hold onto some extra 
association but it's ok if it disappears. Others without the key 
can never gain from the benefit because they can never find 
the value as they don't have the key. With this in mind 
mapmaker becomes another weakhashmap albeit with a 
more wide range of reference type semantics.

Original comment by miroslav...@gmail.com on 9 Apr 2010 at 11:13

GoogleCodeExporter commented 8 years ago
I think I have another reason why it might be a good idea : Hash Consing of 
tree whose children are sets.
For HashConsing, you don't care if something will be deleted if it is not in 
memory anymore (as long as the value is in 
memory, it has a pointer to the key).
So the key can be soft/weak.

If you use ==, you have to HashCons the set of children too, which can be 
annoying (especially if you use sets from 
another source). Using equal would do what it needs to do.

HashConsing is not only a performance improvment for memory but a key element 
in some algorithms on tree.

Original comment by nicolas....@gmail.com on 18 May 2010 at 8:33

GoogleCodeExporter commented 8 years ago
I have another use case for allows keys to match on == instead of equals().  We 
have a node tree unserialized a Protocol Buffers coming over a socket and I 
need to associate some additional information on each node.

I could use a WeakHashMap or MapMaker.weakKeys() for this, but I'm building the 
node tree and associated map in a single thread and both will have their strong 
references removed at the same time when they go out of scope.  So I'm paying 
the cost for a WeakReference, reference queue, etc when I just need == instead 
of equals().

Original comment by blair-ol...@orcaware.com on 17 Nov 2010 at 5:15

GoogleCodeExporter commented 8 years ago

Original comment by fry@google.com on 26 Jan 2011 at 7:47

GoogleCodeExporter commented 8 years ago

Original comment by kevinb@google.com on 13 Jul 2011 at 6:18

GoogleCodeExporter commented 8 years ago
Charles found that our code to permit custom equivalence was widely misused, 
and weak keys seemed to be an acceptable solution for all our users.  He'd be 
interested in any performance numbers to the contrary.

Original comment by cpov...@google.com on 13 Jul 2011 at 8:37

GoogleCodeExporter commented 8 years ago
@Charles your comment seems completely at odds with how regular Maps like 
HashMap which of course use the equals() from added keys. I am confused how or 
why performance is mentioned. Can you please elaborate why this request is a 
bad. If its good enough for HashMap it should be good for MapMaker which aims 
to be a better HashMap.

Original comment by miroslav...@gmail.com on 13 Jul 2011 at 10:09

GoogleCodeExporter commented 8 years ago
The relevant comparison is WeakHashMap, which also uses == for equality 
comparison. MapMaker does the same with weak keys. Also note that some of the 
use cases on this thread should consider using EquivalenceWrapper.

Original comment by fry@google.com on 14 Jul 2011 at 7:00

GoogleCodeExporter commented 8 years ago
@Charles
Some of the comments by others could make use of EquivalenceWrapper that my 
original request has not been addressed. 

We both know that MapMaker with weak/soft keys is a better WeakHashMap. After 
all thatyou have not actually stated hot solve the functionality being 
mentioned by my original post. Could you plz elaborate either way. Im confused 
as the original post seems to have been ignored/not addressed.

Original comment by miroslav...@gmail.com on 15 Jul 2011 at 1:05

GoogleCodeExporter commented 8 years ago
To be clear, we aren't claiming to have solved your problem. We are claiming 
that after looking at dozens of internal attempts to use the functionality you 
are asking for, we couldn't find a single one that was using it right, and 
wouldn't be better off doing something else. We can't rule out the possibility 
that an occasional valid use will arise; we just haven't seen one yet.

I'd be interested in better understanding your specific use case, just to 
inform our future thought, though we have enough experience on this one to 
maintain the current status quo.

Original comment by fry@google.com on 15 Jul 2011 at 6:59

GoogleCodeExporter commented 8 years ago
Thanx Fry,

I was partially confused because your comments seemed to be more directed at
other comments. Thanks for the meaningful writeup.

*Definitions*
MapMaker with soft/weak keys is basically as stated before a WeakHashMap. As
per my original post i am using the MapMaker map as a cache, primarily
because i want stuff (key=values) to disappear automatically when memory is
needed. Hopefully that is not a overly simple explaination of a cache, but
it will do for the remainder of my reply. WHereever i mention cache i mean a
MapMaker map.

*Example*
Imagine a service that holds hits (an Integer) for a page (cache key= page
path without query parameters). Lets pretend we hold this data in a cache,
if a particular page is absent we grab it from some datastore which is of
course slow so we want to cache. Lets say we wish to hold these in a
MapMaker Map or cache. The first user will of course load the data from some
counting done on the datastore. We place the page and count=1 into the
cache. Now the next request for the very same page comes along. We can get
the path from the request but because its a "different" String and identity
is different we cannot use it as a key to the cache.

*Recreating keys*
Hopefully the examples highlights that its often possible to recreate the
key, and this makes support for equality in map maker extremely useful.

   - A key could be a Long id. If the id is larger than the cache size used
   by Long.valueOf() then it will be a different object.

*WeakHashMap observation...*
Personally i find that the association or mapping that WeakHashMap employs
seems to be best suited for a single user environment, where objects belong
to the scope of that user. Other users may be able to create equal objects
but they can never forge the "same" object reference. A cache seems to me to
work best when its used by lots of people, being filled with useful stuff.
Different people put different values under different keys using a naming
system etc. If others cant create a key that works in the cache then the
utlity seems to be lost or at the very least much less useful. Maybe just
maybe that cache is not really multi user but has limited scope utility.

Original comment by miroslav...@gmail.com on 15 Jul 2011 at 8:07

GoogleCodeExporter commented 8 years ago
In all cases I've seen, including my understanding of what you describe, 
soft/weak references are a better fit for values than keys.

The question isn't whether it is possible to recreate a key, but why it would 
make sense to remove a mapping in the cache just because one of the instances 
of a key was garbage collected. Removing the mapping because the cached value 
was collected, on the other hand, makes perfect sense.

Original comment by fry@google.com on 18 Jul 2011 at 10:30

GoogleCodeExporter commented 8 years ago
Issue 1571 has been merged into this issue.

Original comment by cpov...@google.com on 6 Nov 2013 at 4:07

GoogleCodeExporter commented 8 years ago
Issue 1571 has been merged into this issue.

Original comment by cpov...@google.com on 6 Nov 2013 at 4:13

GoogleCodeExporter commented 8 years ago
This issue has been migrated to GitHub.

It can be found at https://github.com/google/guava/issues/<id>

Original comment by cgdecker@google.com on 1 Nov 2014 at 4:15

GoogleCodeExporter commented 8 years ago

Original comment by cgdecker@google.com on 3 Nov 2014 at 9:10