Package org.radargun.stages.cache.background

Source Code of org.radargun.stages.cache.background.PrivateLogChecker$Pool

package org.radargun.stages.cache.background;

import java.util.Random;

import org.radargun.stages.helpers.Range;

/**
* Checker used for {@link PrivateLogValue non-shared log values}
*
* @author Radim Vansa <rvansa@redhat.com>
*/
public class PrivateLogChecker extends LogChecker {

   public PrivateLogChecker(int id, Pool logCheckerPool, BackgroundOpsManager manager) {
      super("PrivateLogChecker-" + id, manager, logCheckerPool);
   }

   @Override
   protected AbstractStressorRecord newRecord(AbstractStressorRecord record, long operationId, long seed) {
      return new StressorRecord((StressorRecord) record, operationId, seed);
   }

   @Override
   protected Object findValue(AbstractStressorRecord record) throws Exception {
      // We cannot atomically get the two vars - the stressor could move backup to main or back between the two
      // gets. But the chance for doing this 100 times is small enough.
      Object value = null;
      long keyId = record.getKeyId();
      for (int i = 0; i < 100; ++i) {
         value = basicCache.get(keyGenerator.generateKey(keyId));
         if (value == null) {
            if (keyId < 0 && record.getLastStressorOperation() < record.getOperationId()) {
               // do not poll it 100x when we're not sure that the operation is written, try just twice
               break;
            }
            keyId = ~keyId;
            if (keyId > 0) {
               // we yield because of the first entry to empty cache
               Thread.yield();
            }
         } else {
            break;
         }
      }
      return value;
   }

   @Override
   protected boolean containsOperation(Object value, AbstractStressorRecord record) {
      if (value == null) {
         return false;
      }
      if (!(value instanceof PrivateLogValue)) {
         log.error("Key " + record.getKeyId() + " has unexpected value " + value);
         return false;
      }
      PrivateLogValue logValue = (PrivateLogValue) value;
      if (logValue.getThreadId() == record.getThreadId()) {
         for (int i = logValue.size() - 1; i >= 0; --i) {
            if (logValue.getOperationId(i) == record.getOperationId()) {
               return true;
            }
         }
      } else {
         log.error("Expected value from threadId " + record.getThreadId() + " but found from " + logValue.getThreadId());
      }
      return false;
   }

   public static class Pool extends LogChecker.Pool {

      public Pool(int numSlaves, int numThreads, int numEntries, BackgroundOpsManager manager) {
         super(numThreads, numSlaves, manager);
         for (int slaveId = 0; slaveId < numSlaves; ++slaveId) {
            Range slaveKeyRange = Range.divideRange(numEntries, numSlaves, slaveId);
            for (int threadId = 0; threadId < numThreads; ++threadId) {
               Range threadKeyRange = Range.divideRange(slaveKeyRange.getSize(), numThreads, threadId);
               Range range = threadKeyRange.shift(slaveKeyRange.getStart());
               log.trace("Expecting range " + range + " for thread " + (slaveId * numThreads + threadId));
               addNew(new StressorRecord(slaveId * numThreads + threadId, range));
            }
         }
         registerListeners();
      }

      @Override
      public void created(Object key, Object value) {
         log.trace("Created " + key + " -> " + value);
         modified(key, value);
      }

      @Override
      public void updated(Object key, Object value) {
         log.trace("Updated " + key + " -> " + value);
         modified(key, value);
      }

      @Override
      protected void modified(Object key, Object value) {
         if (value instanceof PrivateLogValue) {
            PrivateLogValue logValue = (PrivateLogValue) value;
            notify(logValue.getThreadId(), logValue.getOperationId(logValue.size() - 1), key);
         } else super.modified(key, value);
      }
   }

   private static class StressorRecord extends AbstractStressorRecord {
      private final long keyRangeStart;
      private final int keyRangeSize;

      public StressorRecord(int threadId, Range keyRange) {
         super(new Random(threadId), threadId);
         this.keyRangeStart = keyRange.getStart();
         this.keyRangeSize = keyRange.getSize();
         next();
      }

      public StressorRecord(StressorRecord record, long operationId, long seed) {
         super(seed, record.threadId, operationId);
         this.keyRangeStart = record.keyRangeStart;
         this.keyRangeSize = record.keyRangeSize;
         next();
      }

      @Override
      public void next() {
         currentKeyId = keyRangeStart + rand.nextInt(keyRangeSize);
         discardNotification(currentOp++);
      }
   }

}
TOP

Related Classes of org.radargun.stages.cache.background.PrivateLogChecker$Pool

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.