/*
 * Copyright (C) The Apache Software Foundation. All rights reserved.
 *
 * This software is published under the terms of the Apache Software License
 * version 1.1, a copy of which has been included  with this distribution in
 * the LICENSE.txt file.
 */
package org.apache.avalon.excalibur.cache;

import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Vector;
import java.util.Set;

/**
 * @author <a href="mailto:lawrence_mccay-iii@hp.com">Larry McCay</a>
 */
public class SpacesCacheStore extends AbstractCacheStore
{
   private HashMap m_newCache = null;
   private HashMap m_oldCache = null;
   private int m_capacity = 10;

   public SpacesCacheStore( final int capacity )
   {
       if ( capacity < 1 ) throw new IllegalArgumentException( "Specified capacity must be at least 1" );

       m_capacity = capacity;
       m_newCache = new HashMap( m_capacity );
       m_oldCache = new HashMap( m_capacity );
   }

   public Object put( final Object resourceName, final Object resource )
   {
      Object previous = null;
      get( resourceName );
      previous = m_newCache.put(resourceName, resource);
      if( size() > m_capacity ) // cache full?
      {
         copySpaces();
      }
      return previous;
   }

   public Object remove( Object resourceName )
   {
      Object cr = m_newCache.get( resourceName );

      return m_newCache.remove(resourceName);
   }

   public Object get( Object resourceName )
   {
      Object result = m_newCache.get(resourceName); // try new space
      if (result != null)
        return result;
      result = m_oldCache.get(resourceName); // try old space
      if (result != null)
      {
        if( size() > m_capacity ) // cache full?
        {
           copySpaces();
        }
        m_oldCache.remove( resourceName ); // remove from old space
        m_newCache.put( resourceName, result ); // move to new space
      }
      return result;
   }

   private void copySpaces()
   {
      m_oldCache.clear(); // erase old space
      HashMap temp = m_oldCache; // flip spaces
      m_oldCache = m_newCache;
      m_newCache = temp;
   }

   public int size( )
   {
      return m_newCache.size();
   }

   public int capacity()
   {
       return m_capacity;
   }

   public boolean containsKey( final Object key )
   {
      boolean rc = m_newCache.containsKey( key );
      if( !rc )
      {
         rc = m_oldCache.containsKey( key );
      }
      return rc;
   }

   public Object[] keys()
   {
      Set newKeys =  m_newCache.keySet();
      Set oldKeys = m_oldCache.keySet();
      Vector v = new Vector( newKeys );
      v.addAll( oldKeys );
      return v.toArray();
   }
}

