Class Cqld4GremlinOpMapper<CO extends Cqld4ScriptGraphOp>
- All Implemented Interfaces:
OpMapper<Cqld4ScriptGraphOp,Cqld4Space>
-
Field Summary
Fields inherited from class io.nosqlbench.adapter.cqld4.opmappers.Cqld4BaseOpMapper
adapter, logger -
Constructor Summary
ConstructorsConstructorDescriptionCqld4GremlinOpMapper(Cqld4DriverAdapter adapter, LongFunction<String> targetFunction) -
Method Summary
Modifier and TypeMethodDescriptionapply(NBComponent adapterC, ParsedOp op, LongFunction spaceF) This method is responsible for interrogating the fields in the providedParsedOptemplate object, determining what adapter-specific operation it maps to, and creating the associatedOpDispenserfor that type.
-
Constructor Details
-
Cqld4GremlinOpMapper
-
-
Method Details
-
apply
Description copied from interface:OpMapperThis method is responsible for interrogating the fields in the providedParsedOptemplate object, determining what adapter-specific operation it maps to, and creating the associatedOpDispenserfor that type.Implementation Notes
It is important to be familiar with the structure of the
ParsedOp, since this is the runtime model API for an op template. It provides everything you need to turn various op fields into proper lambdas, which can then be composed together to make higher-order lambdas. The returnedOpDispenseris essentially a singularLongFunctionwhich captures all of the just-in-time construction patterns needed within.Op Mapping
Generally speaking, implementations of this method should interrogate the op fields in the ParsedOp to determine the specific op that matches the user's intentions. It is Highly reccommended that each of the valid op types is presented as an example in the associated adapter documentation. (Each adapter must have a self-named markdown help file in it's source tree.) Good op mappers are based on specific examples which are documented, as this is the only way a user knows what op types are available.
What determines the type of op can be based on something explicit, like the value of a
typefield, or it can be based on whether certain fields are present or not. Advanced implementations might take into account which fields are provided as static values and which are specified as (dynamic) bindings. 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.All of the effective logic for op mapping must be contained within the
OpMapper.apply(NBComponent, ParsedOp, LongFunction)method. This includes what happens within the constructor of anyOpDispenser. What happens withinOpDispenserimplementations (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. This suggest the following conventions:- Type-mapping logic (determine which op type) is done in the main body of
OpMapper.apply(NBComponent, ParsedOp, LongFunction), and nothing else. Once the desired op dispenser (based on the intended op type) is determined, it is immediately constructed and returned. - Lambda-construction logic is contained in the constructor of the returned op dispenser. This pre-bakes as much of the op construction behavior as possible, building only a single lambda to do the heavy lifting later.
- When
LongFunction.apply(long) is called with a cycle value, it only needs to call the lambda to
return a fully-formed op, ready to be executed via its
CycleOp.apply(long)method.- Specified by:
applyin interfaceOpMapper<Cqld4ScriptGraphOp,Cqld4Space> - Specified by:
applyin classCqld4BaseOpMapper<Cqld4ScriptGraphOp>- Parameters:
adapterC- The adapter component. This is passed as anNBComponentbecause it is not valid to rely on the driver adapter instance directly for anything. All logic for an op should be captured in its mapper and dispenser, and all (other) state for it should be captured within the space. However, the mapper exists within the nosqlbench runtime as part of the component tree, so it is included for that reason alone. (You'll need it for super construtors in some cases)op- TheParsedOpwhich 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. It provides convenient lambda-construction methods to streamline the effort of creating the top-level op lambda.spaceF- This is the pre-baked lambda needed to access the specificOpMapperfor a given cycle, if or when it is needed. Not all op types need this, since they may have all the state needed fully captured within the native type. For those that do, ensure that you are accessing the value through this function lazily and only within the stack. Using this function to do anything but build more lambdas is probably a programming error.- Returns:
- An OpDispenser which can be used to synthesize directly executable operations.
- Type-mapping logic (determine which op type) is done in the main body of
-