formalize space type in generics

formalize space
This commit is contained in:
Jonathan Shook
2024-10-23 13:39:37 -05:00
parent 22ff75aa98
commit 7b8e9145d7
11 changed files with 141 additions and 48 deletions

View File

@@ -19,10 +19,11 @@ package io.nosqlbench.adapter.diag;
import io.nosqlbench.adapters.api.activityimpl.uniform.DriverAdapter;
import io.nosqlbench.adapters.api.activityimpl.uniform.Space;
import io.nosqlbench.adapters.api.activityimpl.uniform.flowtypes.Op;
import io.nosqlbench.nb.api.labels.NBLabels;
import io.nosqlbench.nb.api.components.core.NBComponent;
public interface DriverAdapterLoader {
public <A extends Op,B> DriverAdapter<A,B> load(NBComponent parent, NBLabels childLabels);
public <A extends Op,B extends Space> DriverAdapter<A,B> load(NBComponent parent, NBLabels childLabels);
}

View File

@@ -19,6 +19,7 @@ package io.nosqlbench.adapters.api.activityimpl;
import com.codahale.metrics.Timer;
import groovy.lang.Binding;
import io.nosqlbench.adapters.api.activityimpl.uniform.DriverAdapter;
import io.nosqlbench.adapters.api.activityimpl.uniform.Space;
import io.nosqlbench.adapters.api.activityimpl.uniform.flowtypes.Op;
import io.nosqlbench.adapters.api.evalctx.*;
import io.nosqlbench.adapters.api.metrics.ThreadLocalNamedTimers;
@@ -42,10 +43,10 @@ import java.util.concurrent.TimeUnit;
* Some details are tracked per op template, which aligns to the life-cycle of the op dispenser.
* Thus, each op dispenser is where the stats for all related operations are kept.
*
* @param <T>
* @param <OP>
* The type of operation
*/
public abstract class BaseOpDispenser<T extends Op, S> extends NBBaseComponent implements OpDispenser<T>{
public abstract class BaseOpDispenser<OP extends Op,SPACE extends Space> extends NBBaseComponent implements OpDispenser<OP>{
protected final static Logger logger = LogManager.getLogger(BaseOpDispenser.class);
public static final String VERIFIER = "verifier";
public static final String VERIFIER_INIT = "verifier-init";
@@ -55,7 +56,7 @@ public abstract class BaseOpDispenser<T extends Op, S> extends NBBaseComponent i
public static final String STOP_TIMERS = "stop-timers";
private final String opName;
protected final DriverAdapter<? extends T, ? extends S> adapter;
protected final DriverAdapter<? extends OP, ? extends SPACE> adapter;
private final NBLabels labels;
public final Timer verifierTimer;
private boolean instrument;
@@ -77,7 +78,7 @@ public abstract class BaseOpDispenser<T extends Op, S> extends NBBaseComponent i
private final CycleFunction<Boolean> _verifier;
private final ThreadLocal<CycleFunction<Boolean>> tlVerifier;
protected BaseOpDispenser(final DriverAdapter<? extends T, ? extends S> adapter, final ParsedOp op) {
protected BaseOpDispenser(final DriverAdapter<? extends OP, ? extends SPACE> adapter, final ParsedOp op) {
super(adapter);
opName = op.getName();
this.adapter = adapter;
@@ -177,7 +178,7 @@ public abstract class BaseOpDispenser<T extends Op, S> extends NBBaseComponent i
return this.opName;
}
public DriverAdapter<? extends T, ? extends S> getAdapter() {
public DriverAdapter<? extends OP, ? extends SPACE> getAdapter() {
return this.adapter;
}
@@ -227,8 +228,8 @@ public abstract class BaseOpDispenser<T extends Op, S> extends NBBaseComponent i
}
@Override
public final T apply(long value) {
T op = getOp(value);
public final OP apply(long value) {
OP op = getOp(value);
return op;
}
}

View File

@@ -16,6 +16,7 @@
package io.nosqlbench.adapters.api.activityimpl;
import io.nosqlbench.adapters.api.activityimpl.uniform.flowtypes.Op;
import io.nosqlbench.adapters.api.evalctx.CycleFunction;
import java.util.function.LongFunction;
@@ -64,11 +65,11 @@ import java.util.function.LongFunction;
* are easy to understand at the mapping level ({@link OpMapper}),
* and streamlined for fast execution at the synthesis level ({@link OpDispenser}).
*
* @param <T> The parameter type of the actual operation which will be used
* @param <OP> The parameter type of the actual operation which will be used
* to hold all the details for executing an operation,
* something that implements {@link Runnable}.
* something that implements {@link Op}.
*/
public interface OpDispenser<T> extends LongFunction<T>, OpResultTracker {
public interface OpDispenser<OP extends Op> extends LongFunction<OP>, OpResultTracker {
/**
* The apply method in an op dispenser should do all the work of
@@ -82,7 +83,7 @@ public interface OpDispenser<T> extends LongFunction<T>, OpResultTracker {
* @return an executable operation
*/
T getOp(long value);
OP getOp(long value);
CycleFunction<Boolean> getVerifier();

View File

@@ -17,17 +17,21 @@
package io.nosqlbench.adapters.api.activityimpl;
import io.nosqlbench.adapters.api.activityimpl.uniform.DriverAdapter;
import io.nosqlbench.adapters.api.activityimpl.uniform.Space;
import io.nosqlbench.adapters.api.activityimpl.uniform.flowtypes.Op;
import io.nosqlbench.adapters.api.templating.ParsedOp;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.IntFunction;
import java.util.function.LongFunction;
/**
* <p>
* <h2>Synopsis</h2>
* An OpMapper is responsible for converting parsed op templates
* into dispensers of operations based on the intention of the user.
*
* <p>
* Op Templates as expressed as a set of field values, some literal, and
* some dynamic, to be generated based on a specific cycle value.
* </p>
@@ -79,16 +83,19 @@ import java.util.function.Function;
* to hold all the details for executing an operation,
* generally something that implements {@link Runnable}.
*/
public interface OpMapper<OPTYPE extends Op> extends Function<ParsedOp, OpDispenser<? extends OPTYPE>> {
public interface OpMapper<OPTYPE extends Op, SPACETYPE extends Space>
extends BiFunction<ParsedOp, LongFunction<SPACETYPE>, OpDispenser<OPTYPE>> {
/**
* Interrogate the parsed command, and provide a new
*
* @param op The {@link ParsedOp} which is the parsed version of the user-provided op template.
* This contains all the fields provided by the user, as well as explicit knowledge of
* which ones are static and dynamic.
* @param op
* The {@link ParsedOp} which is the parsed version of the user-provided op template.
* This contains all the fields provided by the user, as well as explicit knowledge of
* which ones are static and dynamic.
* @param spaceInitF
* @return An OpDispenser which can be used to synthesize real operations.
*/
@Override
OpDispenser<? extends OPTYPE> apply(ParsedOp op);
OpDispenser<OPTYPE> apply(ParsedOp op, LongFunction<SPACETYPE> spaceInitF);
}

View File

@@ -18,6 +18,7 @@ package io.nosqlbench.adapters.api.activityimpl.docs;
import io.nosqlbench.adapter.diag.DriverAdapterLoader;
import io.nosqlbench.adapters.api.activityimpl.uniform.DriverAdapter;
import io.nosqlbench.adapters.api.activityimpl.uniform.Space;
import io.nosqlbench.adapters.api.activityimpl.uniform.flowtypes.Op;
import io.nosqlbench.nb.api.docsapi.BundledMarkdownManifest;
import io.nosqlbench.nb.api.docsapi.Docs;
@@ -40,7 +41,10 @@ public class BundledDriverAdapterDocs implements BundledMarkdownManifest {
List<SimpleServiceLoader.Component<? extends DriverAdapterLoader>> namedProviders = loader.getNamedProviders();
for (SimpleServiceLoader.Component<? extends DriverAdapterLoader> namedProvider : namedProviders) {
DriverAdapterLoader driverAdapterLoader = namedProvider.provider.get();
DriverAdapter<Op, Object> driverAdapter = driverAdapterLoader.load(NBComponent.EMPTY_COMPONENT, NBLabels.forKV());
DriverAdapter<Op, Space> driverAdapter = driverAdapterLoader.load(
NBComponent.EMPTY_COMPONENT,
NBLabels.forKV()
);
DocsBinder bundledDocs = driverAdapter.getBundledDocs();
docs = docs.merge(bundledDocs);
}

View File

@@ -32,12 +32,13 @@ import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.LongFunction;
import java.util.function.LongToIntFunction;
import java.util.stream.Collectors;
public abstract class BaseDriverAdapter<R extends Op, S> extends NBBaseComponent implements DriverAdapter<R, S>, NBConfigurable, NBReconfigurable {
public abstract class BaseDriverAdapter<R extends Op, S extends Space> extends NBBaseComponent implements DriverAdapter<R, S>, NBConfigurable, NBReconfigurable {
private final static Logger logger = LogManager.getLogger("ADAPTER");
private StringDriverSpaceCache<? extends S> spaceCache;
private ConcurrentSpaceCache<S> spaceCache;
private NBConfiguration cfg;
private LongFunction<S> spaceF;
@@ -62,7 +63,7 @@ public abstract class BaseDriverAdapter<R extends Op, S> extends NBBaseComponent
mappers.addAll(stmtRemappers);
mappers.addAll(getOpFieldRemappers());
if (mappers.size() == 0) {
if (mappers.isEmpty()) {
return (i) -> i;
}
@@ -121,7 +122,7 @@ public abstract class BaseDriverAdapter<R extends Op, S> extends NBBaseComponent
* <p>Provide a list of field remappers which operate on arbitrary fields.
* Each function is applied to the op template fields. </p>
*
* @return
* @return op field remappers, an empty list by default
*/
@Override
public List<Function<Map<String, Object>, Map<String, Object>>> getOpFieldRemappers() {
@@ -129,9 +130,9 @@ public abstract class BaseDriverAdapter<R extends Op, S> extends NBBaseComponent
}
@Override
public final synchronized StringDriverSpaceCache<? extends S> getSpaceCache() {
public final synchronized ConcurrentSpaceCache<S> getSpaceCache() {
if (spaceCache == null) {
spaceCache = new StringDriverSpaceCache<>(this, getSpaceInitializer(getConfiguration()));
spaceCache = new ConcurrentSpaceCache<S>(getSpaceInitializer(getConfiguration()));
}
return spaceCache;
}
@@ -192,8 +193,8 @@ public abstract class BaseDriverAdapter<R extends Op, S> extends NBBaseComponent
@Override
public LongFunction<S> getSpaceFunc(ParsedOp pop) {
LongFunction<String> spaceNameF = pop.getAsFunctionOr("space", "default");
StringDriverSpaceCache<? extends S> cache = getSpaceCache();
return l -> getSpaceCache().get(spaceNameF.apply(l));
LongToIntFunction spaceIdxF = pop.getAsFunctionOrInt("space", 0);
ConcurrentSpaceCache<? extends S> cache = getSpaceCache();
return l -> getSpaceCache().get(spaceIdxF.applyAsInt(l));
}
}

View File

@@ -0,0 +1,36 @@
package io.nosqlbench.adapters.api.activityimpl.uniform;
/*
* Copyright (c) 2022 nosqlbench
*
* 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.
*/
import java.util.function.IntFunction;
import java.util.function.LongFunction;
public class BaseSpace implements Space {
private final String spaceName;
public BaseSpace(long idx) {
this.spaceName = String.valueOf(idx);
}
@Override
public String getName() {
return spaceName;
}
}

View File

@@ -33,6 +33,7 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.IntFunction;
import java.util.function.LongFunction;
/**
@@ -55,7 +56,7 @@ import java.util.function.LongFunction;
* during construction of R type operations, or even for individual
* operations.
*/
public interface DriverAdapter<OPTYPE extends Op, SPACETYPE> extends NBComponent {
public interface DriverAdapter<OPTYPE extends Op, SPACETYPE extends Space> extends NBComponent {
/**
* <p>
@@ -101,7 +102,7 @@ public interface DriverAdapter<OPTYPE extends Op, SPACETYPE> extends NBComponent
*
* @return a synthesizer function for {@link OPTYPE} op generation
*/
OpMapper<OPTYPE> getOpMapper();
OpMapper<OPTYPE, SPACETYPE> getOpMapper();
/**
* The preprocessor function allows the driver adapter to remap
@@ -159,7 +160,7 @@ public interface DriverAdapter<OPTYPE extends Op, SPACETYPE> extends NBComponent
* @return A function which can initialize a new Space, which is a place to hold
* object state related to retained objects for the lifetime of a native driver.
*/
default Function<String, ? extends SPACETYPE> getSpaceInitializer(NBConfiguration cfg) {
default LongFunction<SPACETYPE> getSpaceInitializer(NBConfiguration cfg) {
return n -> null;
}

View File

@@ -0,0 +1,37 @@
package io.nosqlbench.adapters.api.activityimpl.uniform;
/*
* Copyright (c) 2022 nosqlbench
*
* 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.
*/
import io.nosqlbench.nb.api.components.core.NBNamedElement;
/**
* <P>A space is simply a separate namespace associated with an instance of a
* native client or driver. This allows for the emulation of many clients
* in testing scenarios. Within the operations for an adapter, the space
* may be needed, for example, to construct prepared statements, or other
* 'session-attached' objects. Put any state that you would normally
* associate with an instance of a native driver into a space, and use
* the {@link DriverAdapter#getSpaceCache()} to access it when needed.</P>
*/
public interface Space extends NBNamedElement, AutoCloseable {
@Override
default void close() throws Exception {
}
}