Package org.apache.wicket.page.persistent.disk

Source Code of org.apache.wicket.page.persistent.disk.DiskDataStoreTest$Read1Runnable

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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.pageStore.AsynchronousDataStore;
import org.apache.wicket.pageStore.DiskDataStore;
import org.apache.wicket.pageStore.IDataStore;
import org.apache.wicket.util.lang.Checks;

public class DiskDataStoreTest extends TestCase
{

  public DiskDataStoreTest()
  {

  }

  private static final Random random = new Random();
  private static final int FILE_SIZE_MIN = 1024 * 200;
  private static final int FILE_SIZE_MAX = 1024 * 300;
  private static final int MAX_SIZE_PER_SESSION = 1000000;
  private static final int FILE_CHANNEL_POOL_CAPACITY = 100;
  private static final int SESSION_COUNT = 50;
  private static final int FILES_COUNT = 1000;
  private static final int SLEEP_MAX = 10;
  private static final int THREAD_COUNT = 20;
  private static final int READ_MODULO = 100;

  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[])
    {
      Checks.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 final Map<String, AtomicInteger> sessionCounter = new ConcurrentHashMap<String, AtomicInteger>();
  private final ConcurrentLinkedQueue<File> filesToSave = new ConcurrentLinkedQueue<File>();
  private final ConcurrentLinkedQueue<File> filesToRead1 = new ConcurrentLinkedQueue<File>();
  private final ConcurrentLinkedQueue<File> filesToRead2 = new ConcurrentLinkedQueue<File>();

  private final AtomicInteger read1Count = new AtomicInteger(0);
  private final AtomicInteger read2Count = new AtomicInteger(0);
  private final AtomicInteger saveCount = new AtomicInteger(0);

  private final AtomicBoolean saveDone = new AtomicBoolean(false);
  private final AtomicBoolean read1Done = new AtomicBoolean(false);
  private final AtomicBoolean read2Done = new AtomicBoolean(false);

  private final AtomicInteger failures = new AtomicInteger();

  private final AtomicInteger bytesWritten = new AtomicInteger(0);
  private final AtomicInteger bytesRead = new AtomicInteger(0);

  private final AtomicInteger saveTime = 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));
      long now = System.nanoTime();
      filesToSave.add(file);
      long duration = System.nanoTime() - now;
      saveTime.addAndGet((int)duration);
    }

  }

  private IDataStore 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);

          if (saveCount.get() % READ_MODULO == 0)
          {
            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())
      {
        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())
      {
        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: " + (read1Count.get() + read2Count.get()) + " files, " +
      bytesRead.get() + " bytes");

    System.out.println("Average save time (ns): " + (double)saveTime.get() /
      (double)saveCount.get());

    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);
    dataStore = new AsynchronousDataStore(dataStore);

    doTestDataStore();

    dataStore.destroy();
  }


}
TOP

Related Classes of org.apache.wicket.page.persistent.disk.DiskDataStoreTest$Read1Runnable

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.