jiweigang1 / google-collections

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

MapMaker expiration does not reset on duplicate put() #286

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
When an Object is put into the Map, removal is scheduled via a Timer.  If 
the value is updated the expiration does not reset, the initial Timer is 
still running and will remove the Object.

The initial Timer should be cancelled on put and a new one created.

Original issue reported on code.google.com by morgan...@gmail.com on 30 Oct 2009 at 8:59

GoogleCodeExporter commented 9 years ago
I meant the initial TimerTask should be cancelled / removed

Original comment by morgan...@gmail.com on 30 Oct 2009 at 9:28

GoogleCodeExporter commented 9 years ago
I assume that you are reporting this bug based on reading the code instead of 
from actually observing incorrect 
behavior? As it is, MapMaker only expires if the value is still the same 
object, so what you describe would only 
happen on a redundant put. Is that what you're concerned about?

Original comment by yrfselrahc@gmail.com on 31 Oct 2009 at 12:53

GoogleCodeExporter commented 9 years ago
I think you are assuming I'm using soft keys, I'm use the default, strong keys.

Here is a test.  Since a put is happening after 1 second, I'd expect the value 
not 
to expire, but it does.

    public void testTimeoutWhenKeyIsUpdated() throws Exception {
        Map<Integer, Integer> map = new MapMaker()
                .expiration(1500, TimeUnit.MILLISECONDS)
                .makeComputingMap(
                        new Function<Integer, Integer>() {
                            public Integer apply(Integer integer) {
                                System.out.println("executing function");
                                return new Integer(integer);
                            }
                        });

        System.out.println("request 1");
        map.get(new Integer(1));
        Thread.sleep(1000);
        System.out.println("request 2");
        map.get(new Integer(1));
        map.put(new Integer(1), new Integer(1));
        Thread.sleep(1000);
        System.out.println("request 3");
        map.get(new Integer(1));
    }

Original comment by morgan...@gmail.com on 3 Nov 2009 at 12:43

GoogleCodeExporter commented 9 years ago
Right. So you are doing a put that maps to an object that is equal to the old. 
That is the one known case where 
this happens. If you changed your put to map 1 to 2, then it would not expire.

I agree that this is not perfect, I just want to qualify the bounds of this 
issue.

Original comment by yrfselrahc@gmail.com on 3 Nov 2009 at 3:31

GoogleCodeExporter commented 9 years ago
OK the timer resets if !newValue.equals(oldValue).  Here is a new test:

    public void testTimeoutWhenKeyIsUpdated() throws Exception {
        Map<Integer, Long> map = new MapMaker()
                .expiration(1500, TimeUnit.MILLISECONDS)
                .makeComputingMap(
                        new Function<Integer, Long>() {
                            public Long apply(Integer integer) {
                                System.out.println("executing function");
                                return new Long(System.currentTimeMillis());
                            }
                        });

        System.out.println("request 1");
        map.get(new Integer(1));
        Thread.sleep(1000);
        System.out.println("request 2");
        map.get(new Integer(1));
        map.put(new Integer(1), new Long(2));
        Thread.sleep(1000);
        System.out.println("request 3");
        map.get(new Integer(1));
    }

Original comment by morgan...@gmail.com on 3 Nov 2009 at 5:44

GoogleCodeExporter commented 9 years ago
What's the use case for this?  Why perform this redundant put() in the first 
place, 
when you can just let it expire and let it get calculated again when it's 
needed?

Original comment by kevin...@gmail.com on 5 Nov 2009 at 1:06

GoogleCodeExporter commented 9 years ago
closed at least until such time as need is made clear.

Original comment by kevin...@gmail.com on 6 Nov 2009 at 10:02