/**
* Copyright (c) 2010 Yahoo! Inc. All rights reserved.
*
* Licensed 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. See accompanying
* LICENSE file.
*/
package com.couchbase.loadgen.workloads;
import com.couchbase.loadgen.DataStore;
import com.couchbase.loadgen.exception.WorkloadException;
/**
* One experiment scenario. One object of this type will be instantiated and
* shared among all client threads. This class should be constructed using a
* no-argument constructor, so we can load it dynamically. Any argument-based
* initialization should be done by init().
*
* If you extend this class, you should support the "insertstart" property. This
* allows the load phase to proceed from multiple clients on different machines,
* in case the client is the bottleneck. For example, if we want to load 1
* million records from 2 machines, the first machine should have insertstart=0
* and the second insertstart=500000. Additionally, the "insertcount" property,
* which is interpreted by Client, can be used to tell each instance of the
* client how many inserts to do. In the example above, both clients should have
* insertcount=500000.
*/
public abstract class Workload {
/**
* Initialize the scenario. Create any generators and other shared objects
* here. Called once, in the main client thread, before any operations are
* started.
*/
public void init() throws WorkloadException {
}
/**
* Initialize any state for a particular client thread. Since the scenario
* object will be shared among all threads, this is the place to create any
* state that is specific to one thread. To be clear, this means the
* returned object should be created anew on each call to initThread(); do
* not return the same object multiple times. The returned object will be
* passed to invocations of doInsert() and doTransaction() for this thread.
* There should be no side effects from this call; all state should be
* encapsulated in the returned object. If you have no state to retain for
* this thread, return null. (But if you have no state to retain for this
* thread, probably you don't need to override initThread().)
*
* @return false if the workload knows it is done for this thread. Client
* will terminate the thread. Return true otherwise. Return true for
* workloads that rely on operationcount. For workloads that read
* traces from a file, return true when there are more to do, false
* when you are done.
*/
public Object initThread(int mythreadid, int threadcount)
throws WorkloadException {
return null;
}
/**
* Cleanup the scenario. Called once, in the main client thread, after all
* operations have completed.
*/
public void cleanup() throws WorkloadException {
}
/**
* Do one insert operation. Because it will be called concurrently from
* multiple client threads, this function must be thread safe. However,
* avoid synchronized, or the threads will block waiting for each other, and
* it will be difficult to reach the target throughput. Ideally, this
* function would have no side effects other than DB operations and
* mutations on threadstate. Mutations to threadstate do not need to be
* synchronized, since each thread has its own threadstate instance.
*/
public abstract boolean doInsert(DataStore db);
/**
* Do one transaction operation. Because it will be called concurrently from
* multiple client threads, this function must be thread safe. However,
* avoid synchronized, or the threads will block waiting for each other, and
* it will be difficult to reach the target throughput. Ideally, this
* function would have no side effects other than DB operations and
* mutations on threadstate. Mutations to threadstate do not need to be
* synchronized, since each thread has its own threadstate instance.
*
* @return false if the workload knows it is done for this thread. Client
* will terminate the thread. Return true otherwise. Return true for
* workloads that rely on operationcount. For workloads that read
* traces from a file, return true when there are more to do, false
* when you are done.
*/
public abstract boolean doTransaction(DataStore db);
public abstract boolean doOperation(DataStore db);
}