package org.juxtapose.bundle.persistanttest; import java.util.HashSet; import java.util.Random; import java.util.Set; import java.util.concurrent.atomic.AtomicReference; import com.trifork.clj_ds.IPersistentMap; import com.trifork.clj_ds.PersistentHashMap; public class Test { static boolean SYNC = false; public static class STM { private AtomicReference<IPersistentMap<Integer, String>> m_theMap = new AtomicReference<IPersistentMap<Integer,String>>(); public volatile int m_retrys = 0; public STM() { IPersistentMap<Integer, String> map = PersistentHashMap.emptyMap(); m_theMap.set(map); } public IPersistentMap<Integer, String> getData() { return m_theMap.get(); } public void addValue( Integer inKey, String inValue ) { if( SYNC ) { synchronized (m_theMap) { m_theMap.set( getData().assoc( inKey, inValue ) ); } } else { IPersistentMap<Integer, String> oldMap; IPersistentMap<Integer, String> newMap; int retry = 0; do { if( retry > 0 ) m_retrys++; oldMap = getData(); newMap = oldMap.assoc(inKey, inValue); retry++; } while( !m_theMap.compareAndSet(oldMap, newMap)); } } } static int ENTRYS = 10000; static Random RANDOM = new Random(); static STM STM = new STM(); public class Agent { volatile Test m_test; volatile public int m_id; public Agent( final Test inTest, final int inId ) { m_test = inTest; m_id = inId; } public void start() { Thread myThread = new Thread(new Runnable() { @Override public void run() { for( int i = 0; i < ENTRYS; i++ ) { Integer key = RANDOM.nextInt( Integer.MAX_VALUE ); String value = key.toString(); STM.addValue( key, value ); if( !STM.getData().containsKey( key ) ) { throw new NullPointerException("THE STM DOESN'T CONTAIN THE NEW KEY"); } } m_test.imDone( m_id ); } }); myThread.start(); } } Set<Integer> m_agentIds = new HashSet<Integer>(); volatile long m_start; int THREADS = 4; public Test() { synchronized( m_agentIds ) { m_start = System.nanoTime(); for( int i = 0; i < THREADS; i++ ) { Agent agent = new Agent( this, i); m_agentIds.add( i ); agent.start(); } } } public void imDone( int inAgentId ) { synchronized( m_agentIds ) { m_agentIds.remove( inAgentId ); if( m_agentIds.isEmpty() ) { long time = System.nanoTime() - m_start; long timePerEntry = time / (ENTRYS * THREADS); time /= 1000; System.out.println("It took: "+time+" us retrys: "+STM.m_retrys+" time per entry: "+timePerEntry+" ns"); } } } public static void main( String... inArgs ) { Test test = new Test(); } }