public boolean put(Key key, Value value) {
        // retain value so that it's not released before we put it in the cache and calculate the weight
        value.retain();
        try {
            if (!value.matchesKey(key)) {
                throw new IllegalArgumentException("Value '" + value + "' does not match key '" + key + "'");
            }
            long entrySize = weighter.getSize(value);
            EntryWrapper<Key, Value> newWrapper = EntryWrapper.create(key, value, entrySize);
            if (entries.putIfAbsent(key, newWrapper) == null) {
                this.size.addAndGet(entrySize);
                return true;
            } else {
                // recycle the new wrapper as it was not used
                newWrapper.recycle();
                return false;
            }
        } finally {
            value.release();
        }
    }
@Test
    public void testPutSameObj() {
        RangeCache<Integer, RefString> cache = new RangeCache<>(value -> value.s.length(), x -> 0);
        RefString s0 = new RefString("zero", 0);
        assertEquals(s0.refCnt(), 1);
        assertTrue(cache.put(0, s0));
        assertFalse(cache.put(0, s0));
    }