/*
* $Header: IDFactoryTest.java, 26/08/2005 01:04:53 luisantonioa Exp $
*
* $Author: luisantonioa $
* $Date: 26/08/2005 01:04:53 $
* $Revision: 1 $
* $Log: IDFactoryTest.java,v $
* Revision 1 26/08/2005 01:04:53 luisantonioa
* Added copyright notice
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.gameserver.idfactory;
import java.util.Vector;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import junit.framework.TestCase;
import com.l2jserver.Config;
import com.l2jserver.Config.IdFactoryType;
import com.l2jserver.Server;
import com.l2jserver.util.Rnd;
/**
* This class ...
*
* @version $Revision: 1.2 $ $Date: 2004/06/27 08:12:59 $
*/
public class IDFactoryTest extends TestCase
{
private static final boolean _debug = false;
// Compaction, BitSet, Stack, (null to use config)
private static final IdFactoryType FORCED_TYPE = IdFactoryType.Stack;
protected IdFactory _idFactory;
protected AtomicInteger _count = new AtomicInteger(0), _adds = new AtomicInteger(0), _removes = new AtomicInteger(0);
protected static final int REQUESTER_THREADS = 50;
protected static final int REQUESTER_THREAD_REQUESTS = 1000;
protected static final int REQUESTER_THREAD_RANDOM_DELAY = 30;
protected static final int RELEASER_THREADS = 50;
protected static final int RELEASER_THREAD_RELEASES = 1000;
protected static final int RELEASER_THREAD_RANDOM_DELAY = 35;
private static final long F_SLEEP_INTERVAL = 100;
CountDownLatch _latch = new CountDownLatch(REQUESTER_THREADS + RELEASER_THREADS);
protected static Vector<Integer> _map = new Vector<Integer>();
public static void main(String[] args)
{
}
/**
* Constructor for IDFactoryTest.
* @param arg0
*/
public IDFactoryTest(String arg0)
{
super(arg0);
Server.serverMode = Server.MODE_GAMESERVER;
Config.load();
if(FORCED_TYPE != null)
Config.IDFACTORY_TYPE = FORCED_TYPE;
_idFactory = IdFactory.getInstance();
}
/*
* @see TestCase#setUp()
*/
@Override
protected void setUp() throws Exception
{
super.setUp();
System.out.println("Initial Free ID's: "+IdFactory.FREE_OBJECT_ID_SIZE);
System.out.println("IdFactoryType: "+Config.IDFACTORY_TYPE.name());
/*long startMemoryUse = getMemoryUse();
BitSet freeIds = new BitSet(0x6FFFFFFF);
long endMemoryUse = getMemoryUse();
freeIds.clear();
long approximateSize = ( endMemoryUse - startMemoryUse ) / (1024*1024);
System.out.println("Size: "+approximateSize+"Mb.");*/
}
/*
* @see TestCase#tearDown()
*/
@Override
protected void tearDown() throws Exception
{
super.tearDown();
_idFactory = null;
}
/*
* Test method for 'com.l2jserver.gameserver.idfactory.IdFactory.getNextId()'
*/
public final void testFactory()
{
System.out.println("Free ID's: "+_idFactory.size());
System.out.println("Used ID's: "+(IdFactory.FREE_OBJECT_ID_SIZE - _idFactory.size()));
_map.add(_idFactory.getNextId());
for (int i=0; i<REQUESTER_THREADS; i++)
{
new Thread(new RequestID(), "Request-Thread-"+i).start();
}
for (int i=0; i<RELEASER_THREADS; i++)
{
new Thread(new ReleaseID(), "Release-Thread-"+i).start();
}
try
{
_latch.await();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("Free ID's: "+_idFactory.size());
System.out.println("Used ID's: "+(IdFactory.FREE_OBJECT_ID_SIZE - _idFactory.size()));
System.out.println("Count: "+_count.get());
}
public class RequestID implements Runnable
{
long _time1;
long _time2;
AtomicInteger _myCount = new AtomicInteger(0);
public void run()
{
for (int i=0; i<REQUESTER_THREAD_REQUESTS; i++)
{
synchronized (_map)
{
_time1 = System.nanoTime();
int newId = _idFactory.getNextId();
_time2 = System.nanoTime() - _time1;
_count.incrementAndGet();
_adds.incrementAndGet();
_myCount.incrementAndGet();
_map.add(newId);
if (_debug) System.out.println("Got new ID "+newId);
if (Rnd.nextInt(10) == 0)
{
System.out.println(" Total ID requests: "+_adds.get()+". "+_time2+"ns");
}
}
try
{
Thread.sleep(Rnd.nextInt(REQUESTER_THREAD_RANDOM_DELAY));
}
catch (InterruptedException e)
{
System.out.println(Thread.currentThread().getName()+" was Interupted.");
}
}
if (_debug) System.out.println(getName()+ " myCount is "+_myCount.get()+"/100.");
_latch.countDown();
}
}
public class ReleaseID implements Runnable
{
AtomicInteger _myCount = new AtomicInteger(100);
long _time1;
long _time2;
public void run()
{
for (int i=0; i<RELEASER_THREAD_RELEASES; i++)
{
synchronized (_map)
{
int size = _map.size();
if (_map.size() <= 0)
{
i--;
continue;
}
//if (size > 0)
//{
int pos = Rnd.nextInt(size);
int id = _map.get(pos);
_time1 = System.nanoTime();
_idFactory.releaseId(id);
_time2 = System.nanoTime() - _time1;
_map.remove(pos);
_count.decrementAndGet();
_myCount.decrementAndGet();
_removes.incrementAndGet();
if (_debug) System.out.println("Released ID "+id);
if (Rnd.nextInt(10) == 0)
{
System.out.println("Total ID releases: "+_removes.get()+". "+_time2+"ns");
}
//}
}
try
{
Thread.sleep(Rnd.nextInt(RELEASER_THREAD_RANDOM_DELAY));
}
catch (InterruptedException e)
{
}
}
if (_debug) System.out.println(getName()+ " count is "+_myCount.get()+"/100.");
_latch.countDown();
}
}
@SuppressWarnings("unused")
private static long getMemoryUse(){
putOutTheGarbage();
long totalMemory = Runtime.getRuntime().totalMemory();
putOutTheGarbage();
long freeMemory = Runtime.getRuntime().freeMemory();
return (totalMemory - freeMemory);
}
private static void putOutTheGarbage() {
collectGarbage();
collectGarbage();
}
private static void collectGarbage() {
try {
System.gc();
Thread.sleep(F_SLEEP_INTERVAL);
System.runFinalization();
Thread.sleep(F_SLEEP_INTERVAL);
}
catch (InterruptedException ex){
ex.printStackTrace();
}
}
}