start direct driver module

This commit is contained in:
Jonathan Shook 2021-05-13 12:58:15 -05:00
parent 3f4cd9913f
commit 4a82fb4e7f
12 changed files with 319 additions and 0 deletions

35
driver-direct/pom.xml Normal file
View File

@ -0,0 +1,35 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>mvn-defaults</artifactId>
<groupId>io.nosqlbench</groupId>
<version>4.15.45-SNAPSHOT</version>
<relativePath>../mvn-defaults</relativePath>
</parent>
<artifactId>driver-direct</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>
A direct API nosqlbench ActivityType (AT) driver module
</description>
<dependencies>
<dependency>
<groupId>io.nosqlbench</groupId>
<artifactId>drivers-api</artifactId>
<version>4.15.45-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.nosqlbench</groupId>
<artifactId>engine-api</artifactId>
<version>4.15.45-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,11 @@
package io.nosqlbench.driver.direct;
import io.nosqlbench.engine.api.activityimpl.OpDispenser;
public class CallMapper implements OpDispenser<DirectCall> {
@Override
public DirectCall apply(long value) {
return null;
}
}

View File

@ -0,0 +1,25 @@
package io.nosqlbench.driver.direct;
import io.nosqlbench.engine.api.activityapi.core.SyncAction;
import io.nosqlbench.engine.api.activityimpl.OpDispenser;
public class DirectAction implements SyncAction {
private final int slot;
private final DirectActivity activity;
public DirectAction(int slot, DirectActivity activity) {
this.slot = slot;
this.activity = activity;
}
@Override
public int runCycle(long cycle) {
OpDispenser<? extends Runnable> dispenser = activity.getSequencer().apply(cycle);
Runnable apply = dispenser.apply(cycle);
return SyncAction.super.runCycle(cycle);
}
}

View File

@ -0,0 +1,21 @@
package io.nosqlbench.driver.direct;
import io.nosqlbench.engine.api.activityapi.core.Activity;
import io.nosqlbench.engine.api.activityconfig.yaml.OpTemplate;
import io.nosqlbench.engine.api.activityimpl.ActivityDef;
import io.nosqlbench.engine.api.activityimpl.OpDispenser;
import io.nosqlbench.engine.api.activityimpl.uniform.StandardActivity;
import java.util.function.Function;
public class DirectActivity extends StandardActivity<DirectCall> implements Activity {
public DirectActivity(ActivityDef activityDef) {
super(activityDef);
}
@Override
protected Function<OpTemplate, OpDispenser<DirectCall>> getOpMapperFunction() {
return DirectOpMapper::new;
}
}

View File

@ -0,0 +1,44 @@
package io.nosqlbench.driver.direct;
import io.nosqlbench.engine.api.activityapi.core.Action;
import io.nosqlbench.engine.api.activityapi.core.ActionDispenser;
import io.nosqlbench.engine.api.activityapi.core.ActivityType;
import io.nosqlbench.engine.api.activityimpl.ActivityDef;
import io.nosqlbench.nb.annotations.Service;
/**
* This activity type driver allows you to dynamically map any available
* Java API which is exposed to the NoSQLBench runtime, executing methods
* on this API by name, (optionally) storing named results, and re-using
* these named results as arguments to subsequent calls.
*
* It supports static method dispatch, instance methods, and per-thread
* object scoping.
*/
@Service(value = ActivityType.class,selector = "direct")
public class DirectActivityType implements ActivityType<DirectActivity> {
@Override
public DirectActivity getActivity(ActivityDef activityDef) {
return new DirectActivity(activityDef);
}
@Override
public ActionDispenser getActionDispenser(DirectActivity activity) {
return new DirectActionDispenser(activity);
}
private static class DirectActionDispenser implements ActionDispenser {
private final DirectActivity activity;
public DirectActionDispenser(DirectActivity activity) {
this.activity = activity;
}
@Override
public Action getAction(int slot) {
return new DirectAction(slot, activity);
}
}
}

View File

@ -0,0 +1,8 @@
package io.nosqlbench.driver.direct;
public class DirectCall implements Runnable {
@Override
public void run() {
}
}

View File

@ -0,0 +1,25 @@
package io.nosqlbench.driver.direct;
import io.nosqlbench.engine.api.activityconfig.yaml.OpTemplate;
import io.nosqlbench.engine.api.activityimpl.OpDispenser;
import java.util.function.LongFunction;
public class DirectOpMapper implements OpDispenser<DirectCall> {
private final OpTemplate opTemplate;
private final LongFunction<DirectCall> readyOp;
public DirectOpMapper(OpTemplate opTemplate) {
this.opTemplate = opTemplate;
this.readyOp = resolve(opTemplate);
}
private LongFunction<DirectCall> resolve(OpTemplate opTemplate) {
return new DynamicCallDispenser(opTemplate);
}
public DirectCall apply(long value) {
return readyOp.apply(value);
}
}

View File

@ -0,0 +1,16 @@
package io.nosqlbench.driver.direct;
import io.nosqlbench.engine.api.activityconfig.yaml.OpTemplate;
import java.util.function.LongFunction;
public class DynamicCallDispenser implements LongFunction<DirectCall> {
public DynamicCallDispenser(OpTemplate opTemplate) {
}
@Override
public DirectCall apply(long value) {
return null;
}
}

View File

@ -0,0 +1,73 @@
package io.nosqlbench.driver.direct.optypes;
import io.nosqlbench.virtdata.library.basics.core.threadstate.SharedState;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Parameter;
import java.util.Map;
public class DynamicMethodCall implements Runnable {
private final static Logger logger = LogManager.getLogger(DynamicMethodCall.class);
private final Map<String, Object> callinfo;
public DynamicMethodCall(Map<String,Object> callinfo) {
this.callinfo = callinfo;
}
// At this point, class and method should have been set, and args optionally
private void callMethod() {
String className = callinfo.get("class").toString();
String methodName = callinfo.get("method").toString();
Class<?> clazz;
Method method;
try {
clazz = Class.forName(className);
method = clazz.getMethod(methodName);
Object instance = null;
if (!Modifier.isStatic(method.getModifiers())) {
if (callinfo.containsKey("instance")) {
String instanceName = callinfo.get("instance").toString();
instance = SharedState.tl_ObjectMap.get().get(instanceName);
}
}
Parameter[] parameters = method.getParameters();
Object[] args = new Object[parameters.length];
for (int i = 0; i < args.length; i++) {
String posname = "arg" + i;
if (callinfo.containsKey(posname)) {
args[i] = callinfo.get(posname);
} else if (parameters[i].isNamePresent()) {
String argname = parameters[i].getName();
if (callinfo.containsKey(argname)) {
args[i]=callinfo.get(argname);
} else {
throw new RuntimeException("could not find arg named '" + posname + "', nor '" + argname + "' in op template for method " + method.toGenericString());
}
}
}
Object result = method.invoke(instance, args);
if (callinfo.containsKey("save")) {
String saveAs = callinfo.get("save").toString();
SharedState.tl_ObjectMap.get().put(saveAs,result);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void run() {
callMethod();
}
}

View File

@ -0,0 +1,5 @@
package io.nosqlbench.driver.direct.optypes;
public class ObjectCall {
}

View File

@ -0,0 +1,25 @@
# Direct Driver
This is a unique type of NoSQLBench driver which assumes no particular
runtime API, instead relying on runtime reflection to find and invoke
the methods as specified in the op template.
```yaml
statements:
- "java.lang.System.out.println(\"Testing\");"
- "System.out.println(\"Testing\");"
- op: "System.out.println(\"Testing\");"
- op:
class: java.lang.System
field: out
method: println
arg0: Testing
- op:
class: java.lang.System
field: out
method: println
_x: Testing
- op:
object: myobj
- myobj=System.out.println("testing");
```

View File

@ -0,0 +1,31 @@
package io.nosqlbench.engine.api.activityimpl.uniform;
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.function.Function;
/**
* If you provide a type of invokable element in this list, then it should
* automatically be handled by NB.
*/
public enum NBInvokerType {
NBRunnable(Runnable.class),
NBCallable(Callable.class),
NBFunction(Function.class);
private final Class<?> typeclass;
NBInvokerType(Class<?> typeClass) {
this.typeclass=typeClass;
}
public static Optional<NBInvokerType> valueOfType(Class<?> c) {
for (NBInvokerType type : NBInvokerType.values()) {
if (type.typeclass.equals(c)) {
return Optional.of(type);
}
}
return Optional.empty();
}
}