All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.javakaffee.web.msm.ReadOnlyRequestsCache Maven / Gradle / Ivy

There is a newer version: 2.3.2
Show newest version
/*
 * Copyright 2011 Martin Grotzke
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package de.javakaffee.web.msm;

import java.util.Comparator;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;

/**
 * Stores readonly requests and a blacklist (requests that modified the session).
 *
 * @author Martin Grotzke
 */
public class ReadOnlyRequestsCache {

    private static final Comparator ATOMLONG_COMP = new Comparator() {

        @Override
        public int compare( final AtomicLong o1, final AtomicLong o2 ) {
            final long val1 = o1.longValue();
            final long val2 = o2.longValue();
            return val1 < val2 ? -1 : ( val1 == val2 ? 0 : 1);
        }

    };

    private final Log _log = LogFactory.getLog( getClass() );

    private final LRUCache _readOnlyRequests;
    private final LRUCache _blacklist;

    public ReadOnlyRequestsCache() {
        final long sixHours = TimeUnit.HOURS.toMillis( 6 );
        _readOnlyRequests = new LRUCache( 1000, sixHours );
        _blacklist = new LRUCache( 50000, sixHours );
    }

    /**
     * Registers the given requestURI as a readonly request, as long as it has not been tracked
     * before as a modifying request (via {@link #modifyingRequest(String)}).
     * 

* There's a limit on the number and the time readonly requests are beeing stored (simply a LRU cache), * so that the most frequently accessed readonly requests are stored. *

* @param requestId the request uri to track. * @return true if the requestURI was stored as readonly, false if it was on the blacklist. * @see #modifyingRequest(String) */ public boolean readOnlyRequest( final String requestId ) { if ( !_blacklist.containsKey( requestId ) ) { if ( _log.isDebugEnabled() ) { _log.debug( "Registering readonly request: " + requestId ); } incrementOrPut( _readOnlyRequests, requestId ); return true; } return false; } /** * Registers the given requestURI as a modifying request, which can be seen as a blacklist for * readonly requests. There's a limit on number and time for modifying requests beeing stored. * @param requestId the request uri to track. */ public void modifyingRequest( final String requestId ) { if ( _log.isDebugEnabled() ) { _log.debug( "Registering modifying request: " + requestId ); } incrementOrPut( _blacklist, requestId ); _readOnlyRequests.remove( requestId ); } /** * Determines, if the given requestURI is a readOnly request and not blacklisted as a modifying request. * @param requestId the request uri to check * @return true if the given request uri can be regarded as read only. */ public boolean isReadOnlyRequest( final String requestId ) { if ( _log.isDebugEnabled() ) { _log.debug( "Asked for readonly request: " + requestId + " ("+ _readOnlyRequests.containsKey( requestId ) +")" ); } // TODO: add some threshold return _readOnlyRequests.containsKey( requestId ); } /** * The readonly requests, ordered by last accessed time, from least-recently accessed to most-recently. * @return a list of readonly requests. */ public List getReadOnlyRequests() { return _readOnlyRequests.getKeys(); } /** * The readonly requests, ordered by the frequency they got registered, from least-frequently to most-frequently. * @return a list of readonly requests. */ public List getReadOnlyRequestsByFrequency() { return _readOnlyRequests.getKeysSortedByValue( ATOMLONG_COMP ); } private void incrementOrPut( final LRUCache cache, final String requestURI ) { final AtomicLong count = cache.get( requestURI ); if ( count != null ) { count.incrementAndGet(); } else { cache.put( requestURI, new AtomicLong( 1 ) ); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy