Author: knopp
Date: Sat Apr 4 00:53:11 2009
New Revision: 761848
URL: http://svn.apache.org/viewvc?rev=761848&view=rev
Log:
datastore test
Added:
wicket/sandbox/knopp/experimental/wicket-ng/src/test/java/org/apache/wicket/page/persistent/disk/DiskDataStoreTest.java
(with props)
wicket/sandbox/knopp/experimental/wicket-ng/src/test/resources/
wicket/sandbox/knopp/experimental/wicket-ng/src/test/resources/log4j.properties
(with props)
Modified:
wicket/sandbox/knopp/experimental/wicket-ng-webapp/src/main/java/org/apache/wicket/ngwebapp/TestPage1.java
wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/page/persistent/disk/DiskDataStore.java
Modified:
wicket/sandbox/knopp/experimental/wicket-ng-webapp/src/main/java/org/apache/wicket/ngwebapp/TestPage1.java
URL:
http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket-ng-webapp/src/main/java/org/apache/wicket/ngwebapp/TestPage1.java?rev=761848&r1=761847&r2=761848&view=diff
==============================================================================
---
wicket/sandbox/knopp/experimental/wicket-ng-webapp/src/main/java/org/apache/wicket/ngwebapp/TestPage1.java
(original)
+++
wicket/sandbox/knopp/experimental/wicket-ng-webapp/src/main/java/org/apache/wicket/ngwebapp/TestPage1.java
Sat Apr 4 00:53:11 2009
@@ -31,9 +31,6 @@
l1.setLabel("Link 1 - Add Some Parameters");
add(l1);
-
-
-
Link l2 = new Link("l2")
{
private static final long serialVersionUID = 1L;
Modified:
wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/page/persistent/disk/DiskDataStore.java
URL:
http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/page/persistent/disk/DiskDataStore.java?rev=761848&r1=761847&r2=761848&view=diff
==============================================================================
---
wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/page/persistent/disk/DiskDataStore.java
(original)
+++
wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/page/persistent/disk/DiskDataStore.java
Sat Apr 4 00:53:11 2009
@@ -11,6 +11,7 @@
import java.io.Serializable;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
@@ -90,7 +91,7 @@
{
synchronized (sessionEntry)
{
- sessionEntryMap.remove(sessionEntry);
+ sessionEntryMap.remove(sessionEntry.sessionId);
sessionEntry.unbind();
}
}
@@ -98,7 +99,7 @@
public void storeData(String sessionId, int id, byte[] data)
{
- SessionEntry sessionEntry = getSessionEntry(sessionId, false);
+ SessionEntry sessionEntry = getSessionEntry(sessionId, true);
if (sessionEntry != null)
{
sessionEntry.savePage(id, data);
@@ -114,16 +115,18 @@
else
{
SessionEntry entry = new SessionEntry(this, sessionId);
- entry = sessionEntryMap.putIfAbsent(sessionId, entry);
- return entry;
+ SessionEntry existing =
sessionEntryMap.putIfAbsent(sessionId, entry);
+ return existing != null ? existing : entry;
}
}
+ private static final String INDEX_FILE_NAME = "DiskDataStoreIndex";
+
@SuppressWarnings("unchecked")
private void loadIndex()
{
File storeFolder = getStoreFolder();
- File index = new File(storeFolder, "DiskPageStoreIndex");
+ File index = new File(storeFolder, INDEX_FILE_NAME);
if (index.exists() && index.length() > 0)
{
try
@@ -146,7 +149,7 @@
}
catch (Exception e)
{
- log.error("Couldn't load DiskPageStore index
from file " + index + ".", e);
+ log.error("Couldn't load DiskDataStore index
from file " + index + ".", e);
}
}
index.delete();
@@ -157,18 +160,26 @@
File storeFolder = getStoreFolder();
if (storeFolder.exists())
{
- File index = new File(storeFolder,
"DiskPageStoreIndex");
+ File index = new File(storeFolder, INDEX_FILE_NAME);
index.delete();
try
{
OutputStream stream = new
FileOutputStream(index);
ObjectOutputStream oos = new
ObjectOutputStream(stream);
- oos.writeObject(sessionEntryMap);
+ Map<String, SessionEntry> map = new
HashMap<String, SessionEntry>(sessionEntryMap.size());
+ for (Entry<String, SessionEntry> e :
sessionEntryMap.entrySet())
+ {
+ if (e.getValue().unbound == false)
+ {
+ map.put(e.getKey(),
e.getValue());
+ }
+ }
+ oos.writeObject(map);
stream.close();
}
catch (Exception e)
{
- log.error("Couldn't write DiskPageStore index
to file " + index + ".", e);
+ log.error("Couldn't write DiskDataStore index
to file " + index + ".", e);
}
}
}
Added:
wicket/sandbox/knopp/experimental/wicket-ng/src/test/java/org/apache/wicket/page/persistent/disk/DiskDataStoreTest.java
URL:
http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket-ng/src/test/java/org/apache/wicket/page/persistent/disk/DiskDataStoreTest.java?rev=761848&view=auto
==============================================================================
---
wicket/sandbox/knopp/experimental/wicket-ng/src/test/java/org/apache/wicket/page/persistent/disk/DiskDataStoreTest.java
(added)
+++
wicket/sandbox/knopp/experimental/wicket-ng/src/test/java/org/apache/wicket/page/persistent/disk/DiskDataStoreTest.java
Sat Apr 4 00:53:11 2009
@@ -0,0 +1,292 @@
+package org.apache.wicket.page.persistent.disk;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import junit.framework.TestCase;
+
+import org.apache.wicket.page.persistent.DataStore;
+import org.apache.wicket.util.lang.Check;
+
+public class DiskDataStoreTest extends TestCase
+{
+
+ public DiskDataStoreTest()
+ {
+
+ }
+
+ private static final Random random = new Random();
+ private static final int FILE_SIZE_MIN = 1024 * 20;
+ private static final int FILE_SIZE_MAX = 1024 * 30;
+ private static final int MAX_SIZE_PER_SESSION = 1000000;
+ private static final int FILE_CHANNEL_POOL_CAPACITY = 100;
+ private static final int SESSION_COUNT = 100;
+ private static final int FILES_COUNT = 1000;
+ private static final int SLEEP_MAX = 10;
+ private static final int THREAD_COUNT = 20;
+
+ private static class File
+ {
+ private final String sessionId;
+ private final int id;
+
+ private byte first;
+ private byte last;
+ private int length;
+
+ public File(String sessionId, int id)
+ {
+ this.sessionId = sessionId;
+ this.id = id;
+ }
+
+ public String getSessionId()
+ {
+ return sessionId;
+ }
+
+ public int getId()
+ {
+ return id;
+ }
+
+ public byte[] generateData()
+ {
+ length = FILE_SIZE_MIN + random.nextInt(FILE_SIZE_MAX -
FILE_SIZE_MIN);
+ byte data[] = new byte[length];
+ random.nextBytes(data);
+ first = data[0];
+ last = data[data.length - 1];
+ return data;
+ }
+
+ public boolean checkData(byte data[])
+ {
+ Check.argumentNotNull(data, "data");
+ if (data.length != length)
+ {
+ return false;
+ }
+ if (first != data[0])
+ {
+ return false;
+ }
+ if (last != data[data.length - 1])
+ {
+ return false;
+ }
+ return true;
+ }
+ }
+
+ private Map<String, AtomicInteger> sessionCounter = new
ConcurrentHashMap<String, AtomicInteger>();
+ private ConcurrentLinkedQueue<File> filesToSave = new
ConcurrentLinkedQueue<File>();
+ private ConcurrentLinkedQueue<File> filesToRead1 = new
ConcurrentLinkedQueue<File>();
+ private ConcurrentLinkedQueue<File> filesToRead2 = new
ConcurrentLinkedQueue<File>();
+
+ private AtomicInteger read1Count = new AtomicInteger(0);
+ private AtomicInteger read2Count = new AtomicInteger(0);
+ private AtomicInteger saveCount = new AtomicInteger(0);
+
+ private AtomicBoolean saveDone = new AtomicBoolean(false);
+ private AtomicBoolean read1Done = new AtomicBoolean(false);
+ private AtomicBoolean read2Done = new AtomicBoolean(false);
+
+ private AtomicInteger failures = new AtomicInteger();
+
+ private AtomicInteger bytesWritten = new AtomicInteger(0);
+ private AtomicInteger bytesRead = new AtomicInteger(0);
+
+ private String randomSessionId()
+ {
+ List<String> s = new ArrayList<String>(sessionCounter.keySet());
+ return s.get(random.nextInt(s.size()));
+ }
+
+ private int nextSessionId(String sessionId)
+ {
+ AtomicInteger i = sessionCounter.get(sessionId);
+ return i.incrementAndGet();
+ }
+
+ private void generateFiles()
+ {
+ for (int i = 0; i < SESSION_COUNT; ++i)
+ {
+ sessionCounter.put(UUID.randomUUID().toString(), new
AtomicInteger(0));
+ }
+ for (int i = 0; i < FILES_COUNT; ++i)
+ {
+ String session = randomSessionId();
+ File file = new File(session, nextSessionId(session));
+ filesToSave.add(file);
+ }
+
+ }
+
+ private DataStore dataStore;
+
+ private class SaveRunnable implements Runnable
+ {
+ public void run()
+ {
+ File file;
+
+ while ((file = filesToSave.poll()) != null ||
saveCount.get() < FILES_COUNT)
+ {
+ if (file != null)
+ {
+ byte data[] = file.generateData();
+
dataStore.storeData(file.getSessionId(), file.getId(), data);
+ filesToRead1.add(file);
+ saveCount.incrementAndGet();
+ bytesWritten.addAndGet(data.length);
+ }
+
+ try
+ {
+ Thread.sleep(random.nextInt(SLEEP_MAX));
+ }
+ catch (InterruptedException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ saveDone.set(true);
+ }
+ };
+
+ private class Read1Runnable implements Runnable
+ {
+ public void run()
+ {
+ File file;
+ while ((file = filesToRead1.poll()) != null ||
!saveDone.get() || read1Count.get() < FILES_COUNT)
+ {
+ if (file != null)
+ {
+ byte bytes[] =
dataStore.getData(file.getSessionId(), file.getId());
+ if (file.checkData(bytes) == false)
+ {
+ failures.incrementAndGet();
+ }
+ filesToRead2.add(file);
+ read1Count.incrementAndGet();
+ bytesRead.addAndGet(bytes.length);
+ }
+
+ try
+ {
+ Thread.sleep(random.nextInt(SLEEP_MAX));
+ }
+ catch (InterruptedException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ read1Done.set(true);
+ }
+ };
+
+
+ private class Read2Runnable implements Runnable
+ {
+ public void run()
+ {
+ File file;
+ while ((file = filesToRead2.poll()) != null ||
!read1Done.get() || read2Count.get() < FILES_COUNT)
+ {
+ if (file != null)
+ {
+ byte bytes[] =
dataStore.getData(file.getSessionId(), file.getId());
+ if (file.checkData(bytes) == false)
+ {
+ failures.incrementAndGet();
+ }
+ read2Count.incrementAndGet();
+ bytesRead.addAndGet(bytes.length);
+ }
+
+ try
+ {
+ Thread.sleep(random.nextInt(SLEEP_MAX));
+ }
+ catch (InterruptedException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ read2Done.set(true);
+ }
+ };
+
+ private void doTestDataStore()
+ {
+ System.out.println("Starting...");
+ long start = System.currentTimeMillis();
+
+ for (int i = 0; i < THREAD_COUNT; ++i)
+ {
+ new Thread(new SaveRunnable()).start();
+ }
+
+ for (int i = 0; i < THREAD_COUNT; ++i)
+ {
+ new Thread(new Read1Runnable()).start();
+ }
+
+ for (int i = 0; i < THREAD_COUNT; ++i)
+ {
+ new Thread(new Read2Runnable()).start();
+ }
+
+ while(!(read1Done.get() && read2Done.get() && saveDone.get()))
+ {
+ try
+ {
+ Thread.sleep(5);
+ }
+ catch (InterruptedException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ long duration = System.currentTimeMillis() - start;
+
+ System.out.println("Took: " + duration + " ms");
+ System.out.println("Save: " + saveCount.intValue() + " files, "
+ bytesWritten.get() +" bytes");
+ System.out.println("Read: " + bytesRead.get() + " bytes");
+
+ assertEquals(0, failures.get());
+
+ for (String s : sessionCounter.keySet())
+ {
+ dataStore.removeData(s);
+ }
+ }
+
+ public void test1()
+ {
+ generateFiles();
+
+ dataStore = new DiskDataStore("app1", MAX_SIZE_PER_SESSION,
FILE_CHANNEL_POOL_CAPACITY);
+
+ doTestDataStore();
+
+ dataStore.destroy();
+ }
+
+
+}
Propchange:
wicket/sandbox/knopp/experimental/wicket-ng/src/test/java/org/apache/wicket/page/persistent/disk/DiskDataStoreTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added:
wicket/sandbox/knopp/experimental/wicket-ng/src/test/resources/log4j.properties
URL:
http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket-ng/src/test/resources/log4j.properties?rev=761848&view=auto
==============================================================================
---
wicket/sandbox/knopp/experimental/wicket-ng/src/test/resources/log4j.properties
(added)
+++
wicket/sandbox/knopp/experimental/wicket-ng/src/test/resources/log4j.properties
Sat Apr 4 00:53:11 2009
@@ -0,0 +1,20 @@
+log4j.debug=false
+
+log4j.rootLogger=DEBUG,Stdout
+log4j.logger.org=INFO
+log4j.logger.com=INFO
+log4j.logger.net=INFO
+log4j.logger.nl=INFO
+
+log4j.logger.org.apache.wicket=INFO
+
+log4j.logger.org.apache.wicket.protocol.http.HttpSessionStore=INFO
+log4j.logger.org.apache.catalina.cluster=DEBUG
+
+log4j.logger.org.apache.wicket.version=INFO
+log4j.logger.org.apache.wicket.RequestCycle=INFO
+
+log4j.appender.Stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.Stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.Stdout.layout.conversionPattern=%-5p - %-26.26c{1} - %m\n
+
Propchange:
wicket/sandbox/knopp/experimental/wicket-ng/src/test/resources/log4j.properties
------------------------------------------------------------------------------
svn:mime-type = text/plain