public V put()

in commons-jcs3-core/src/main/java/org/apache/commons/jcs3/utils/struct/AbstractLRUMap.java [283:354]


    public V put(final K key, final V value)
    {
        putCnt++;

        LRUElementDescriptor<K, V> old = null;
        final LRUElementDescriptor<K, V> me = new LRUElementDescriptor<>(key, value);

        lock.lock();
        try
        {
            list.addFirst( me );
            old = map.put(key, me);

            // If the node was the same as an existing node, remove it.
            if ( old != null && key.equals(old.getKey()))
            {
                list.remove( old );
            }
        }
        finally
        {
            lock.unlock();
        }

        // If the element limit is reached, we need to spool
        if (shouldRemove())
        {
            log.debug( "In memory limit reached, removing least recently used." );

            // The spool will put them in a disk event queue, so there is no
            // need to pre-queue the queuing. This would be a bit wasteful
            // and wouldn't save much time in this synchronous call.
            while (shouldRemove())
            {
                lock.lock();
                try
                {
                    final LRUElementDescriptor<K, V> last = list.getLast();
                    if (last == null) {
                        verifyCache();
                        throw new Error("update: last is null!");
                    }
                    processRemovedLRU(last.getKey(), last.getPayload());
                    if (map.remove(last.getKey()) == null)
                    {
                        log.warn("update: remove failed for key: {0}",
                                last::getKey);
                        verifyCache();
                    }
                    list.removeLast();
                }
                finally
                {
                    lock.unlock();
                }
            }

            log.debug( "update: After spool map size: {0}", map::size);
            if ( map.size() != list.size() )
            {
                log.error("update: After spool, size mismatch: map.size() = {0}, "
                        + "linked list size = {1}",
                        map::size, list::size);
            }
        }

        if ( old != null )
        {
            return old.getPayload();
        }
        return null;
    }