more DriverAdapter docs

This commit is contained in:
Jonathan Shook 2021-07-22 17:39:57 -05:00
parent b227f0bccc
commit ab24cc5aef
2 changed files with 50 additions and 19 deletions

View File

@ -59,7 +59,7 @@ public interface DriverAdapter<R extends Runnable, S> {
* </p>
*
* <p>
* <H2>A note on implementation strategy</H2>
* <H2>A note on implementation strategy:</H2>
* Generally speaking, implementations of this method should interrogate the op fields
* in the ParsedCommand and return an OpDispenser that matches the user's intentions.
* This can be based on something explicit, like the value of a {@code type} field,
@ -67,8 +67,8 @@ public interface DriverAdapter<R extends Runnable, S> {
* might take into account which fields are provided as static values and which are
* specified as bindings. In any case, the op mapping phase is meant to qualify and
* pre-check that the fields provided are valid and specific for a given type of operation.
* What happens within {@link OpDispenser} implementations, however, should do
* as little qualification of field value as possible, focusing simply on constructing
* What happens within {@link OpDispenser} implementations (the second phase), however, should do
* as little qualification of field values as possible, focusing simply on constructing
* the type of operation for which they are designed.
* </p>
*
@ -101,29 +101,28 @@ public interface DriverAdapter<R extends Runnable, S> {
}
/**
* During Adapter Initialization, Op Mapping, Op Synthesis, or
* Op Execution, you may need access to some shared context that
* could change over time. You can build the type of context
* needed and then provide this function to provide new instances
* when needed.
* The cache of all objects needed within a single instance
* of a DriverAdapter which are not operations. These are generally
* things needed by operations, or things needed during the
* construction of operations.
*
* These instance are generally called <em>spaces</em> and are
* cached in a {@link DriverSpaceCache<S>}.
* See {@link DriverSpaceCache} for details on when and how to use this function.
* <p>During Adapter Initialization, Op Mapping, Op Synthesis, or Op Execution,
* you may need access to the objects in (the or a) space cache. You can build the
* type of context needed and then provide this function to provide new instances
* when needed.</p>
*
* @return A cache of named objects
*/
DriverSpaceCache<? extends S> getSpaceCache();
/**
* @return A function which can initialize a new S
*/
default Function<String, ? extends S> getSpaceInitializer() {
return n -> null;
}
/**
* The cache of all objects needed within a single instance
* of a DriverAdapter which are not operations. These are generally
* things needed by operations, or things needed during the
* construction of operations.
*
* @return A cache of named objects
*/
DriverSpaceCache<? extends S> getSpaceCache();
}

View File

@ -3,9 +3,41 @@ package io.nosqlbench.engine.api.activityimpl.uniform;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
/**
* <p>A DriverSpaceCache is simply a place to hold something like a
* client instance and all associated objects for quick and easy access. Each
* space cache is simply a named and separate cache of objects. This is provided
* as a convenient way to keep object state around which may be needed during the
* course of executing operations with a driver or API. By naming each space, it
* becomes possible for tests to create and use separate logical instances of
* a client API for advanced testing. The default instance should simply be named
* {@code default}</p>
*
* <p>Most native drivers use some combination of fluent, functional, and declarative
* patterns. These usually require you to keep access to a set of core
* state-holding objects in order to construct new elements to drive operations with.
* An example of this would be creating a statement from a session. It is necessary
* to keep the session around in for when you create new statements. Maintaining
* the session object is considered an essential part of idiomatic and efficient
* use of the API. Further, you may have builders or factories that are created
* from the session which should be cached as well. Keeping all these objects
* together requires attaching them to a cohesive owning object -- That is the space
* cache.</p>
*
* <p>You might want to create multiple session contexts in order to test out
* non-trivial behavior in advanced testing scenarios. To do this dynamically, i.e.
* acquire some named space cache, simply call the {@link #get(String)}</p> method
* with the name of the space you want to use. This value can be provided as a
* dynamic field in your op mapping ({@link io.nosqlbench.engine.api.activityimpl.OpMapper})
* or synthesis ({@link io.nosqlbench.engine.api.activityimpl.OpDispenser})
* implementation.
*
* @param <S> The type which will represent the cache for a given type of adapter.
*/
public class DriverSpaceCache<S> {
private final ConcurrentHashMap<String,S> cache = new ConcurrentHashMap<>();
private final Function<String, S> newSpaceFunction;
public DriverSpaceCache(Function<String,S> newSpaceFunction) {