/*
 * JBoss, the OpenSource J2EE webOS
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */
package org.jboss.cache.eviction;

import junit.framework.TestCase;
import org.jboss.cache.Fqn;

import java.util.Iterator;

/**
 * Unit tests for FIFOAlgorithm.
 *
 * @author Daniel Huang (dhuang@jboss.org)
 * @version $Revision: 1.4 $
 */
public class FIFOAlgorithmTest extends TestCase
{

   RegionManager regionManager;
   FIFOAlgorithm algo;

   public FIFOAlgorithmTest(String s)
   {
      super(s);
   }

   public void setUp() throws Exception
   {
      super.setUp();

      DummyEvictionPolicy policy = new DummyEvictionPolicy();
      algo = new FIFOAlgorithm();
      FIFOConfiguration config = new FIFOConfiguration();
      regionManager = new RegionManager();
      regionManager.createRegion("/a/b", policy, config);
   }

   public void tearDown() throws Exception
   {
      super.tearDown();
   }

   public void testMaxNodes1() throws Exception
   {
      Region region = regionManager.getRegion("/a/b");
      FIFOConfiguration config = (FIFOConfiguration) region.getEvictionConfiguration();
      config.setMaxNodes(5);

      for (int i = 0; i < 8; i++)
      {
         Fqn fqn = Fqn.fromString("/a/b/" + Integer.toString(i));
         region.setAddedNode(fqn);
      }

      algo.process(region);
      FIFOQueue queue = (FIFOQueue) algo.evictionQueue;
      assertEquals(5, algo.getEvictionQueue().getNumberOfNodes());

      // now verify the order.
      Iterator it = queue.iterate();
      int index = 3;
      while (it.hasNext())
      {
         NodeEntry ne = (NodeEntry) it.next();
         String fqn = ne.getFqn().toString();
         assertTrue(fqn.endsWith("/" + Integer.toString(index)));
         index++;
      }

      // now verify the same order still exists after visiting the nodes.
      for (int i = 3; i < 8; i++)
      {
         Fqn fqn = Fqn.fromString("/a/b/" + Integer.toString(i));
         region.setVisitedNode(fqn);
      }
      for (int i = 3; i < 5; i++)
      {
         Fqn fqn = Fqn.fromString("/a/b/" + Integer.toString(i));
         region.setVisitedNode(fqn);
      }

      algo.process(region);

      assertEquals(5, algo.getEvictionQueue().getNumberOfNodes());

      it = queue.iterate();
      index = 3;
      while (it.hasNext())
      {
         NodeEntry ne = (NodeEntry) it.next();
         String fqn = ne.getFqn().toString();
         assertTrue(fqn.endsWith("/" + Integer.toString(index)));
         index++;
      }
   }

   public void testMaxNodes2() throws Exception
   {
      Region region = regionManager.getRegion("/a/b");
      FIFOConfiguration config = (FIFOConfiguration) region.getEvictionConfiguration();
      config.setMaxNodes(50000);

      for (int i = 0; i < 50000; i++)
      {
         Fqn fqn = Fqn.fromString("/a/b/" + Integer.toString(i));
         region.setAddedNode(fqn);
      }

      algo.process(region);
      FIFOQueue queue = (FIFOQueue) algo.evictionQueue;
      assertEquals(50000, algo.getEvictionQueue().getNumberOfNodes());

      Iterator it = queue.iterate();
      int index = 0;
      while (it.hasNext())
      {
         NodeEntry ne = (NodeEntry) it.next();
         assertTrue(ne.getFqn().toString().endsWith("/" + Integer.toString(index)));
         index++;
      }

      for (int i = 50000; i < 60000; i++)
      {
         Fqn fqn = Fqn.fromString("/a/b/" + Integer.toString(i));
         region.setAddedNode(fqn);
      }

      algo.process(region);

      it = queue.iterate();
      index = 10000;
      while (it.hasNext())
      {
         NodeEntry ne = (NodeEntry) it.next();
         assertTrue(ne.getFqn().toString().endsWith("/" + Integer.toString(index)));
         index++;
      }
   }
}
