/*
 * 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;

/**
 * @author Daniel Huang
 * @version $Revision: 1.1 $
 */
public class ElementSizeAlgorithmTest extends TestCase
{
   RegionManager regionManager;
   ElementSizeAlgorithm algo;

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

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

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

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

   public void testMaxElements() throws Exception
   {
      Region region = regionManager.getRegion("/a/b");
      ElementSizeConfiguration config = (ElementSizeConfiguration) region.getEvictionConfiguration();
      config.setMaxNodes(10);
      config.setMaxElementsPerNode(6);

      for (int i = 0; i < 10; i++)
      {
         Fqn fqn = Fqn.fromString("/a/b/" + Integer.toString(i));
         region.setAddedNode(fqn);
         if (i % 2 == 0)
         {
            for (int k = 0; k < i; k++)
            {
               region.putNodeEvent(fqn, EvictedEventNode.ADD_ELEMENT_EVENT);
            }
         }
      }

      algo.process(region);

      ElementSizeQueue queue = (ElementSizeQueue) algo.evictionQueue;
      assertEquals(9, algo.getEvictionQueue().getNumberOfNodes());
      assertEquals(12, algo.getEvictionQueue().getNumberOfElements());
      // now verify the order.
      Iterator it = queue.iterate();
      int count = 6;
      while (it.hasNext())
      {
         NodeEntry ne = (NodeEntry) it.next();
         System.out.println(ne);

         if (count > 0)
         {
            assertEquals(count, ne.getNumberOfElements());
         }
         else
         {
            assertEquals(0, ne.getNumberOfElements());
         }
         count -= 2;
      }

      for (int i = 0; i < 7; i++)
      {
         region.putNodeEvent(Fqn.fromString("/a/b/9"), EvictedEventNode.ADD_ELEMENT_EVENT);
         region.putNodeEvent(Fqn.fromString("/a/b/7"), EvictedEventNode.ADD_ELEMENT_EVENT);
      }

      algo.process(region);

      assertEquals(7, queue.getNumberOfNodes());
   }

   public void testMaxNodesAndMaxElements() throws Exception
   {
      Region region = regionManager.getRegion("/a/b");
      ElementSizeConfiguration config = (ElementSizeConfiguration) region.getEvictionConfiguration();
      config.setMaxNodes(10);
      config.setMaxElementsPerNode(100);

      for (int i = 0; i < 20; i++)
      {
         Fqn fqn = Fqn.fromString("/a/b/" + Integer.toString(i));
         region.setAddedNode(fqn);
         for (int k = 0; k < i; k++)
         {
            region.putNodeEvent(fqn, EvictedEventNode.ADD_ELEMENT_EVENT);
         }
      }

      algo.process(region);

      ElementSizeQueue queue = (ElementSizeQueue) algo.evictionQueue;
      assertEquals(10, algo.getEvictionQueue().getNumberOfNodes());
      assertEquals(45, algo.getEvictionQueue().getNumberOfElements());

      // now verify the order.
      Iterator it = queue.iterate();
      int num = 9;
      while (it.hasNext())
      {
         NodeEntry ne = (NodeEntry) it.next();
         assertEquals(num, ne.getNumberOfElements());
         num--;
      }

   }

}
