

package gov.va.med.cds.util;


import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import gov.va.med.cds.junit.runners.SuiteAwareRunner;
import gov.va.med.cds.junit.runners.Suite;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.Collection;
import java.util.Map;


@RunWith( SuiteAwareRunner.class )
public class LRUCacheTest
{
    public static final int LRU_CACHE_SIZE = 4;


    @Test
    @Suite( groups = { "checkintest" } )
    public void testConcurrentLRUCache( )
    {
        ConcurrentLRUCache<String, String> cache = new ConcurrentLRUCache<String, String>( LRU_CACHE_SIZE );
        cache.put( "1", "One" ); // 1
        cache.put( "2", "Two" ); // 2 1
        cache.put( "3", "Three" ); // 3 2 1
        cache.put( "4", "Four" ); // 4 3 2 1
        cache.put( "5", "Five" ); // 5 4 3 2

        assertEquals( LRU_CACHE_SIZE, cache.getCacheSize() );
        assertEquals( "Should only have " + LRU_CACHE_SIZE + "entries in cache", cache.usedEntries(), LRU_CACHE_SIZE );

        Collection<Map.Entry<String, String>> allElements = cache.getAll();
        assertEquals( LRU_CACHE_SIZE, allElements.size() );

        cache.get( "3" ); // 3 5 4 2
        cache.get( "4" ); // 4 3 5 2
        cache.put( "6", "Six" ); // 6 4 3 5
        cache.put( "5", "New Five" );

        assertTrue( cache.containsKey( "5" ) );
        assertEquals( cache.get( "5" ), "New Five" ); // 5 6 4 3
        assertTrue( cache.containsKey( "6" ) );
        assertTrue( cache.containsKey( "4" ) );
        assertTrue( cache.containsKey( "3" ) );

        assertFalse( cache.containsKey( "2" ) );
        assertFalse( cache.containsKey( "1" ) );

        cache.clear();
        Assert.assertNull( cache.get( "5" ) );
    }


    @Test
    @Suite( groups = "checkintest" )
    public void testLRUHashMap( )
    {
        LRUHashMap<String, String> map = new LRUHashMap<String, String>( LRU_CACHE_SIZE );
        map.put( "1", "One" ); // 1
        map.put( "2", "Two" ); // 2 1
        map.put( "3", "Three" ); // 3 2 1
        map.put( "4", "Four" ); // 4 3 2 1
        map.put( "5", "Five" ); // 5 4 3 2

        assertEquals( LRU_CACHE_SIZE, map.getMapThreshold() );

        map.get( "3" ); // 3 5 4 2
        map.get( "4" ); // 4 3 5 2
        
        map.reSize( 2 );
        assertEquals( 2, map.getMapThreshold() );
    }

}
