refactoring complete and integration passing

This commit is contained in:
Jonathan Shook
2020-04-01 22:56:51 -05:00
714 changed files with 2455 additions and 2482 deletions

View File

@@ -1,13 +0,0 @@
@startuml
scale 350 width
[*] --> long
long --> long
long --> int
long --> double
int --> String
double --> String
long --> String
long --> Date
long --> Bytes
long --> T
@enduml

View File

@@ -13,18 +13,20 @@
<name>virtdata-api</name>
<url>http://nosqlbench.io/</url>
<description>
The internal API module for Virtual Data Set modules. Each module that provides
mapping functions should only have to depend on this module to get all the dependencies
it needs.
</description>
<dependencies>
<dependency>
<groupId>io.nosqlbench</groupId>
<artifactId>virtdata-processors</artifactId>
<version>3.12.75-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.nosqlbench</groupId>
<artifactId>virtdata-annotations</artifactId>
<version>3.12.75-SNAPSHOT</version>
<artifactId>nb-api</artifactId>
</dependency>
<dependency>
<groupId>io.nosqlbench</groupId>
<artifactId>virtdata-lang</artifactId>
@@ -32,15 +34,6 @@
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
@@ -48,13 +41,7 @@
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core-java8</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
@@ -65,9 +52,10 @@
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<groupId>com.squareup</groupId>
<artifactId>javapoet</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -1,308 +0,0 @@
/*
*
* Copyright 2016 jshook
* 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.
* /
*/
package io.nosqlbench.virtdata.api;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.CharBuffer;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.spi.FileSystemProvider;
import java.util.*;
import java.util.stream.Collectors;
public class VirtDataResources {
public final static String DATA_DIR = "data";
private final static Logger logger = LogManager.getLogger(VirtDataResources.class);
public static CharBuffer readDataFileToCharBuffer(String basename) {
return loadFileToCharBuffer(basename, DATA_DIR);
}
public static List<String> readDataFileLines(String basename) {
return readFileLines(basename, DATA_DIR);
}
public static String readDataFileString(String basename) {
return readFileString(basename, DATA_DIR);
}
public static InputStream findRequiredStreamOrFile(String basename, String extension, String... searchPaths) {
Optional<InputStream> optionalStreamOrFile = findOptionalStreamOrFile(basename, extension, searchPaths);
return optionalStreamOrFile.orElseThrow(() -> new RuntimeException(
"Unable to find " + basename + " with extension " + extension + " in file system or in classpath, with"
+ " search paths: " + Arrays.stream(searchPaths).collect(Collectors.joining(","))
));
}
public static Reader findRequiredReader(String basename, String extension, String... searchPaths) {
Optional<Reader> optionalReader = findOptionalReader(basename, extension, searchPaths);
return optionalReader.orElseThrow(() -> new RuntimeException(
"Unable to find " + basename + " with extension " + extension + " in file system or in classpath, with"
+ " search paths: " + Arrays.stream(searchPaths).collect(Collectors.joining(","))
));
}
public static Optional<Reader> findOptionalReader(String basename, String extenion, String... searchPaths) {
return findOptionalStreamOrFile(basename, extenion, searchPaths)
.map(InputStreamReader::new)
.map(BufferedReader::new);
}
public static Optional<Path> findOptionalDirPath(String pathName) {
URL systemResource = ClassLoader.getSystemResource(pathName);
if (systemResource != null) {
try {
return Optional.of(Path.of(systemResource.toURI()));
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
return Optional.empty();
}
public static Optional<InputStream> findOptionalStreamOrFile(String basename, String extension, String... searchPaths) {
boolean needsExtension = (extension != null && !extension.isEmpty() && !basename.endsWith("." + extension));
String filename = basename + (needsExtension ? "." + extension : "");
ArrayList<String> paths = new ArrayList<String>() {{
add(filename);
if (!isRemote(basename)) {
addAll(Arrays.stream(searchPaths).map(s -> s + File.separator + filename)
.collect(Collectors.toCollection(ArrayList::new)));
}
}};
for (String path : paths) {
Optional<InputStream> stream = getInputStream(path);
if (stream.isPresent()) {
return stream;
}
}
return Optional.empty();
}
private static boolean isRemote(String path) {
return (path.toLowerCase().startsWith("http:")
|| path.toLowerCase().startsWith("https:"));
}
public static Optional<InputStream> getInputStream(String path) {
// URLs, if http: or https:
if (isRemote(path)) {
Optional<InputStream> inputStream = getInputStreamForUrl(path);
if (inputStream != null) return inputStream;
}
// Files
try {
InputStream stream = new FileInputStream(path);
return Optional.of(stream);
} catch (FileNotFoundException ignored) {
}
// Classpath
ClassLoader classLoader = VirtDataResources.class.getClassLoader();
InputStream stream = classLoader.getResourceAsStream(path);
if (stream != null) {
return Optional.of(stream);
}
return Optional.empty();
}
public static Optional<InputStream> getInputStreamForUrl(String path) {
URL url;
try {
url = new URL(path);
InputStream inputStream = url.openStream();
if (inputStream != null) {
return Optional.of(inputStream);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return null;
}
public static List<String> readFileLines(String basename, String... searchPaths) {
InputStream requiredStreamOrFile = findRequiredStreamOrFile(basename, "", DATA_DIR);
try (BufferedReader buffer = new BufferedReader((new InputStreamReader(requiredStreamOrFile)))) {
List<String> collected = buffer.lines().collect(Collectors.toList());
return collected;
} catch (IOException ioe) {
throw new RuntimeException("Error while reading required file to string", ioe);
}
}
public static String readFileString(String basename, String... searchPaths) {
InputStream requiredStreamOrFile = findRequiredStreamOrFile(basename, "", searchPaths);
try (BufferedReader buffer = new BufferedReader((new InputStreamReader(requiredStreamOrFile)))) {
String filedata = buffer.lines().collect(Collectors.joining("\n"));
return filedata;
} catch (IOException ioe) {
throw new RuntimeException("Error while reading required file to string", ioe);
}
}
public static CSVParser readFileCSV(String basename, String... searchPaths) {
Reader reader = findRequiredReader(basename, "csv", searchPaths);
CSVFormat format = CSVFormat.newFormat(',').withFirstRecordAsHeader();
try {
CSVParser parser = new CSVParser(reader, format);
return parser;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static CharBuffer loadFileToCharBuffer(String filename, String... searchPaths) {
InputStream stream = findRequiredStreamOrFile(filename, "", searchPaths);
CharBuffer linesImage;
try {
InputStreamReader isr = new InputStreamReader(stream);
linesImage = CharBuffer.allocate(1024 * 1024);
while (isr.read(linesImage) > 0) {
}
isr.close();
} catch (IOException e) {
logger.error(e.getMessage());
throw new RuntimeException(e);
}
linesImage.flip();
return linesImage.asReadOnlyBuffer();
}
/**
* <p>Look in all the provided path specifiers for an extant Path, and return
* the first one found.</p>
*
* <p>If the final character of any path specifier is the default file
* separator, then the request is for a directory. During searching,
* if a directory is found when a file is requested, or vice-versa, then
* an error is thrown withouth looking further.</p>
*
* <p>The locations that are searched include:</p>
* <OL>
* <LI>URLs. If the path specifier is a URI, then it is checked for a positive response
* before the path is returned. URLs can not be used for directories.</LI>
* <LI>The local filesystem, starting from the current directory of the process.</LI>
* <LI>The class path.</LI>
* </OL>
*
* @param pathspecs A specifier for a URL, a directory with a trailing slash, or a file
* with no trailing slash.
* @return A Path
* @throws RuntimeException if none of the specified paths is found in any of the locations
*/
public static Path findPathIn(String... pathspecs) {
Optional<Path> found = FindOptionalPathIn(pathspecs);
return found.orElseThrow();
}
public static Optional<Path> FindOptionalPathIn(String... pathspecs) {
Path foundPath = null;
for (String pathspec : pathspecs) {
if (isRemote(pathspec)) {
try {
Optional<InputStream> inputStreamForUrl = getInputStreamForUrl(pathspec);
if (inputStreamForUrl.isPresent()) {
foundPath = Path.of(URI.create(pathspec));
logger.debug("Found accessible remote file at " + foundPath.toString());
}
} catch (Exception ignored) {
}
} else {
boolean wantsADirectory = pathspec.endsWith(FileSystems.getDefault().getSeparator());
String candidatePath = wantsADirectory ? pathspec.substring(0, pathspec.length() - 1) : pathspec;
Path candidate = Path.of(candidatePath);
try {
FileSystemProvider provider = candidate.getFileSystem().provider();
provider.checkAccess(candidate, AccessMode.READ);
BasicFileAttributes attrs = provider.readAttributes(candidate, BasicFileAttributes.class);
boolean foundADirectory = attrs.isDirectory();
if (wantsADirectory != foundADirectory) {
throw new RuntimeException("for path " + pathspec + ", user wanted a " +
(wantsADirectory ? "directory" : "file") + ", but found a " +
(foundADirectory ? "directory" : "file") + " while searching paths " +
Arrays.toString(pathspecs));
}
foundPath = candidate;
} catch (Exception ignored) {
}
if (foundPath == null) {
try {
URL url = ClassLoader.getSystemResource(candidatePath);
if (url != null) {
URI uri = URI.create(url.toExternalForm());
foundPath = getPathInFilesystem(uri);
logger.debug("Found path in classpath: " + candidatePath + ": " + foundPath.toString());
}
} catch (Exception e) {
logger.trace("Error while looking in classpath for " + e.getMessage(), e);
}
}
}
}
return Optional.ofNullable(foundPath);
}
private synchronized static Path getPathInFilesystem(URI uri) {
FileSystem fileSystem = null;
try {
fileSystem = FileSystems.getFileSystem(uri);
} catch (FileSystemNotFoundException ignored) {
try {
fileSystem = FileSystems.newFileSystem(uri, new HashMap<>());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return Path.of(uri);
}
public static CSVParser readDelimFile(String basename, char delimiter, String... searchPaths) {
Reader reader = findRequiredReader(basename, "csv", searchPaths);
CSVFormat format = CSVFormat.newFormat(delimiter).withFirstRecordAsHeader();
try {
CSVParser parser = new CSVParser(reader, format);
return parser;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -0,0 +1,16 @@
package io.nosqlbench.virtdata.api.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Direct the user to additional resources
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Categories {
Category[] value();
}

View File

@@ -0,0 +1,12 @@
package io.nosqlbench.virtdata.api.annotations;
public enum Category {
datetime,
state,
distributions,
diagnostics,
conversion,
collections,
premade,
nulls, functional, general
}

View File

@@ -0,0 +1,28 @@
package io.nosqlbench.virtdata.api.annotations;/*
* Copyright 2016 jshook
* 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.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* This marks functions as deprecated, with a reason.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface DeprecatedFunction {
String value();
}

View File

@@ -0,0 +1,12 @@
package io.nosqlbench.virtdata.api.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Description {
String value();
}

View File

@@ -0,0 +1,18 @@
package io.nosqlbench.virtdata.api.annotations;
import java.lang.annotation.Repeatable;
/**
* The example annotation allows for a function developer to attach illustrative
* examples for any given constructor. You can have multiple
* <pre>@Example</pre> annotation per constructor.
*
*
* A few key formats are allowed
*/
@Repeatable(value = Examples.class)
public @interface Example {
String[] value();
}

View File

@@ -0,0 +1,109 @@
package io.nosqlbench.virtdata.api.annotations;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* <H2>Formatting conventions</H2>
* The following example formats are supported:
*
* <ul>
* <li><pre>CtorName(param,...)</pre> - as the constructor would be called.</li>
* <li><pre>[1,2,3]</pre> - a sequence of integer values</li>
* <li><pre>[longs1]</pre> - a name of a pre-defined set of sample inputs</li>
* </ul>
*/
public class ExampleData {
public static Pattern CTOR_PATTERN = Pattern.compile("(?<funcname>[^)]+)\\((?<args>.+)\\)");
public static Pattern VALS_PATTERN = Pattern.compile("\\[(?<values>-?\\d+([,-. ]+-?\\d+)*)]");
private Pattern COMMA_VALS = Pattern.compile("\\[(?<vals>-?\\d+(,-?\\d+)*)]");
private Pattern RANGE_VALS = Pattern.compile("\\[(?<from>-?\\d+)\\.\\.(?<to>-?\\d+)( +(?<step>-?\\d+))?]");
public String[] parts;
public ExampleData(String[] parts) {
this.parts = parts;
}
public static void validateExamples(List<List<String>> examples) {
for (List<String> example : examples) {
for (String examplePart : example) {
if (CTOR_PATTERN.matcher(examplePart).matches()) {
continue;
}
if (VALS_PATTERN.matcher(examplePart).matches()) {
continue;
}
if (!examplePart.startsWith("[")) {
return;
}
throw new RuntimeException("Unable to match a valid pattern for example fragment '"+examplePart +"')" +
". See javadoc for the Example annotation for details.");
}
}
}
public long[] getLongInputs() {
long[] vals = new long[0];
for (String part : parts) {
if (VALS_PATTERN.matcher(part).matches()) {
String[] specs = part.split(";");
long[][] genvals = new long[specs.length][];
int len =0;
for (int i = 0; i < genvals.length; i++) {
String spec = specs[i];
genvals[i] = parseRange(spec);
len+=genvals[i].length;
}
vals = new long[len];
int atlen=0;
for (int i = 0; i < genvals.length; i++) {
System.arraycopy(genvals[i],0,vals,atlen,genvals[i].length);
atlen+=genvals[i].length;
}
}
}
return vals;
}
private long[] parseRange(String spec) {
Matcher comma_matcher = COMMA_VALS.matcher(spec);
if (comma_matcher.matches()) {
String vals = comma_matcher.group("vals");
long[] longvals = Arrays.stream(vals.split(",")).mapToLong(Long::valueOf).toArray();
return longvals;
}
Matcher range_matcher = RANGE_VALS.matcher(spec);
if (range_matcher.matches()) {
long from=Long.parseLong(range_matcher.group("from"));
long to=Long.parseLong(range_matcher.group("to"));
String step_size = range_matcher.group("step");
long step = 1L;
if (step_size!=null) {
step = Long.parseLong(step_size);
}
if (from<to && step<=0) {
throw new RuntimeException("for increasing from-to of (" +from+"-"+to+":, stepsize must be positive.");
}
if (from>to && step>=0) {
throw new RuntimeException("for decreasing from-to of (" +from+"-"+to+":, stepsize must be negative.");
}
long sizeL = (Math.abs(from-to) / Math.abs(step))+1;
if (sizeL>Integer.MAX_VALUE) {
throw new RuntimeException("example size " + sizeL + " is too big.");
}
long[] vals = new long[(int)sizeL];
long sign = (step>0 ? 1L : -1L);
for (int i = 0; i < vals.length; i++) {
vals[i]=from+(step*i);
}
return vals;
}
throw new RuntimeException("Unable to parse spec pattern: '"+spec+"'");
}
}

View File

@@ -0,0 +1,12 @@
package io.nosqlbench.virtdata.api.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.CONSTRUCTOR)
public @interface Examples {
Example[] value();
}

View File

@@ -0,0 +1,30 @@
package io.nosqlbench.virtdata.api.annotations;/*
* Copyright 2016 jshook
* 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.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* This annotation is used to mark the input type for a functional interface which
* uses generics, like LongFunction, IntFunction, or Function.
* It is only used when then input type of a function can't be found via reflection.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Input {
Range value();
}

View File

@@ -0,0 +1,30 @@
package io.nosqlbench.virtdata.api.annotations;/*
* Copyright 2016 jshook
* 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.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* This annotation is used to mark the output type for a functional interface which
* uses generics, like LongFunction, IntFunction, or Function.
* It is only used when then input type of a function can't be found via reflection.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Output {
Range value();
}

View File

@@ -0,0 +1,29 @@
package io.nosqlbench.virtdata.api.annotations;/*
* Copyright 2016 jshook
* 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.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* A PerThreadMapper will be instantiated once for each thread,
* for each scope in which it is used. Mapper developers should
* endeavor to implement {@link ThreadSafeMapper}s instead.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface PerThreadMapper {
}

View File

@@ -0,0 +1,21 @@
package io.nosqlbench.virtdata.api.annotations;
public enum Range {
NonNegativeLongs("All positive long values and zero: 0L.." + Long.MAX_VALUE),
NonNegativeInts("All positive integer values and zero: 0.." + Integer.MAX_VALUE),
Longs("All long values: " + Long.MIN_VALUE + "L.." + Long.MAX_VALUE+"L"),
Integers("All int values: " + Integer.MIN_VALUE + ".." + Integer.MAX_VALUE),
DoubleUnitInterval("The unit interval in double precision: 0.0D..1.0D"),
FloatUnitInterval("The unit interval in single precision: 0.0F..1.0F"),
Doubles("All double values: " + Double.MIN_VALUE + "D.." + Double.MAX_VALUE+"D");
private final String description;
public String getDescription() {
return description;
}
Range(String description) {
this.description = description;
}
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright 2016 jshook
* 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.
*/
package io.nosqlbench.virtdata.api.annotations;
import java.lang.annotation.*;
/**
* Direct the user to additional resources
*/
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(SeeList.class)
@Target(ElementType.TYPE)
public @interface See {
String name();
String url();
}

View File

@@ -0,0 +1,15 @@
package io.nosqlbench.virtdata.api.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Direct the user to additional resources
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface SeeList {
See[] value();
}

View File

@@ -0,0 +1,28 @@
package io.nosqlbench.virtdata.api.annotations;/*
* Copyright 2016 jshook
* 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.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* A ThreadSafeMapper will only be instantiated once in a scope, to be
* shared among all threads in that scope.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ThreadSafeMapper {
}

View File

@@ -1,4 +1,4 @@
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.api.bindings;
/**
* A public class which holds global values. This is used for holding

View File

@@ -1,4 +1,4 @@
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.api.bindings;
import org.apache.commons.lang3.ClassUtils;

View File

@@ -1,52 +0,0 @@
/*
* Copyright (C) 2014-2016 Markus Junginger, greenrobot (http://greenrobot.org)
*
* 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.
*/
package io.nosqlbench.virtdata.api.murmur;
import java.math.BigInteger;
import java.util.zip.Checksum;
/**
* Checksum interface to access 128 bit in various ways.
*/
public interface Checksum128 extends Checksum {
/**
* @return Returns the higher 64 bits of the 128 bit hash.
*/
long getValueHigh();
/**
* @return Positive value.
*/
BigInteger getValueBigInteger();
/**
* @return Padded with leading 0s to ensure length of 32.
*/
String getValueHexString();
/**
* Big endian is the default in Java / network byte order.
* @return Big Endian bytes
*/
byte[] getValueBytesBigEndian();
/**
* Big endian is used by most machines natively.
* @return Little Endian bytes
*/
byte[] getValueBytesLittleEndian();
}

View File

@@ -1,337 +0,0 @@
/*
* Copyright (C) 2014-2016 Markus Junginger, greenrobot (http://greenrobot.org)
*
* 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.
*/
package io.nosqlbench.virtdata.api.murmur;
import java.math.BigInteger;
/** Murmur3F (MurmurHash3_x64_128) */
public class Murmur3F implements Checksum128 {
private static final long C1 = 0x87c37b91114253d5L;
private static final long C2 = 0x4cf5ad432745937fL;
private final long seed;
private long h1;
private long h2;
private int length;
private int partialPos;
private long partialK1;
private long partialK2;
private boolean finished;
private long finishedH1;
private long finishedH2;
/**
* This constructor allows you to require that an unsafe implementation of
* primitive array operations is used, for added speed on platforms that you
* know can support it. This allows callers to have an easy way to
* exclusively opt in or out of unsafe behavior at a class-loader level,
* rather than forcing an unsafe behavior before the caller gets a chance
* to intervene. The choice is either/or, not "optional, but fall back if not
* supported." Callers can instrument for this with exception handling if it
* is needed. Effectively, setting the unsafe value chooses an implementation.
*
* @param seed A seed to initialize this hash with, or the input when using it
* as a function.
* @param unsafe Whether to require that the implementation relies on an unsafe
* calls.
*/
public Murmur3F(int seed, boolean unsafe) {
this.seed = seed & 0xffffffffL;
h1 = h2 = this.seed;
}
public Murmur3F() {
this(0,false);
}
public Murmur3F(int seed) {
this(seed,false);
}
@Override
public void update(int b) {
finished = false;
switch (partialPos) {
case 0:
partialK1 = 0xff & b;
break;
case 1:
partialK1 |= (0xff & b) << 8;
break;
case 2:
partialK1 |= (0xff & b) << 16;
break;
case 3:
partialK1 |= (0xffL & b) << 24;
break;
case 4:
partialK1 |= (0xffL & b) << 32;
break;
case 5:
partialK1 |= (0xffL & b) << 40;
break;
case 6:
partialK1 |= (0xffL & b) << 48;
break;
case 7:
partialK1 |= (0xffL & b) << 56;
break;
case 8:
partialK2 = 0xff & b;
break;
case 9:
partialK2 |= (0xff & b) << 8;
break;
case 10:
partialK2 |= (0xff & b) << 16;
break;
case 11:
partialK2 |= (0xffL & b) << 24;
break;
case 12:
partialK2 |= (0xffL & b) << 32;
break;
case 13:
partialK2 |= (0xffL & b) << 40;
break;
case 14:
partialK2 |= (0xffL & b) << 48;
break;
case 15:
partialK2 |= (0xffL & b) << 56;
break;
}
partialPos++;
if (partialPos == 16) {
applyKs(partialK1, partialK2);
partialPos = 0;
}
length++;
}
/**
* Special update method to hash long values very efficiently using Java's native little endian (LE) byte order.
* Note, that you cannot mix this with other (previous) hash updates, because it only supports 8-bytes alignment.
* @param value The long value to update
*/
public void updateLongLE(long value) {
finished = false;
switch (partialPos) {
case 0:
partialK1 = value;
break;
case 8:
partialK2 = value;
break;
default:
throw new IllegalStateException("Cannot mix long with other alignments than 8: " + partialPos);
}
partialPos += 8;
if (partialPos == 16) {
applyKs(partialK1, partialK2);
partialPos = 0;
}
length += 8;
}
/**
* Consider {@link #updateLongLE(long)} for better performance if you do not rely on big endian (BE) byte order.
* @param value value to update
*/
public void updateLongBE(long value) {
updateLongLE(Long.reverseBytes(value));
}
public void update(byte[] b) {
update(b, 0, b.length);
}
@Override
public void update(byte[] b, int off, int len) {
finished = false;
while (partialPos != 0 && len > 0) {
update(b[off]);
off++;
len--;
}
int remainder = len & 0xF;
int stop = off + len - remainder;
for (int i = off; i < stop; i += 16) {
long k1 = getLongLE(b, i);
long k2 = getLongLE(b, i + 8);
applyKs(k1, k2);
}
length += stop - off;
for (int i = 0; i < remainder; i++) {
update(b[stop + i]);
}
}
private void applyKs(long k1, long k2) {
k1 *= C1;
k1 = Long.rotateLeft(k1, 31);
k1 *= C2;
h1 ^= k1;
h1 = Long.rotateLeft(h1, 27);
h1 += h2;
h1 = h1 * 5 + 0x52dce729;
k2 *= C2;
k2 = Long.rotateLeft(k2, 33);
k2 *= C1;
h2 ^= k2;
h2 = Long.rotateLeft(h2, 31);
h2 += h1;
h2 = h2 * 5 + 0x38495ab5;
}
private void checkFinished() {
if (!finished) {
finished = true;
finishedH1 = h1;
finishedH2 = h2;
if (partialPos > 0) {
if (partialPos > 8) {
long k2 = partialK2 * C2;
k2 = Long.rotateLeft(k2, 33);
k2 *= C1;
finishedH2 ^= k2;
}
long k1 = partialK1 * C1;
k1 = Long.rotateLeft(k1, 31);
k1 *= C2;
finishedH1 ^= k1;
}
finishedH1 ^= length;
finishedH2 ^= length;
finishedH1 += finishedH2;
finishedH2 += finishedH1;
finishedH1 = fmix64(finishedH1);
finishedH2 = fmix64(finishedH2);
finishedH1 += finishedH2;
finishedH2 += finishedH1;
}
}
private long fmix64(long k) {
k ^= k >>> 33;
k *= 0xff51afd7ed558ccdL;
k ^= k >>> 33;
k *= 0xc4ceb9fe1a85ec53L;
k ^= k >>> 33;
return k;
}
@Override
/** Returns the lower 64 bits of the 128 bit hash (you can use just this value this as a 64 bit hash). */
public long getValue() {
checkFinished();
return finishedH1;
}
/** Returns the higher 64 bits of the 128 bit hash. */
public long getValueHigh() {
checkFinished();
return finishedH2;
}
/** Positive value. */
public BigInteger getValueBigInteger() {
byte[] bytes = getValueBytesBigEndian();
return new BigInteger(1, bytes);
}
/** Padded with leading 0s to ensure length of 32. */
public String getValueHexString() {
checkFinished();
return getPaddedHexString(finishedH2) + getPaddedHexString(finishedH1);
}
private String getPaddedHexString(long value) {
String string = Long.toHexString(value);
while (string.length() < 16) {
string = '0' + string;
}
return string;
}
public byte[] getValueBytesBigEndian() {
checkFinished();
byte[] bytes = new byte[16];
for (int i = 0; i < 8; i++) {
bytes[i] = (byte) ((finishedH2 >>> (56 - i * 8)) & 0xff);
}
for (int i = 0; i < 8; i++) {
bytes[8 + i] = (byte) ((finishedH1 >>> (56 - i * 8)) & 0xff);
}
return bytes;
}
public byte[] getValueBytesLittleEndian() {
checkFinished();
byte[] bytes = new byte[16];
for (int i = 0; i < 8; i++) {
bytes[i] = (byte) ((finishedH1 >>> (i * 8)) & 0xff);
}
for (int i = 0; i < 8; i++) {
bytes[8 + i] = (byte) ((finishedH2 >>> (i * 8)) & 0xff);
}
return bytes;
}
@Override
public void reset() {
h1 = h2 = seed;
length = 0;
partialPos = 0;
finished = false;
// The remainder is not really necessary, but looks nicer when debugging
partialK1 = partialK2 = 0;
finishedH1 = finishedH2 = 0;
}
private static long getLongBE(byte[] bytes, int index) {
return (bytes[index + 7] & 0xff) | ((bytes[index + 6] & 0xff) << 8) |
((bytes[index + 5] & 0xff) << 16) | ((bytes[index + 4] & 0xffL) << 24) |
((bytes[index + 3] & 0xffL) << 32) | ((bytes[index + 2] & 0xffL) << 40) |
((bytes[index + 1] & 0xffL) << 48) | (((long) bytes[index]) << 56);
}
private static long getLongLE(byte[] bytes, int index) {
return (bytes[index] & 0xff) | ((bytes[index + 1] & 0xff) << 8) |
((bytes[index + 2] & 0xff) << 16) | ((bytes[index + 3] & 0xffL) << 24) |
((bytes[index + 4] & 0xffL) << 32) | ((bytes[index + 5] & 0xffL) << 40) |
((bytes[index + 6] & 0xffL) << 48) | (((long) bytes[index + 7]) << 56);
}
}

View File

@@ -0,0 +1,27 @@
package io.nosqlbench.virtdata.api.processors;
import java.util.List;
import java.util.Map;
public interface DocCtorData {
/**
* @return the {@link Class#getSimpleName()} of the documented ctor.
*/
String getClassName();
/**
* @return javadoc for the documented ctor, or null if it isn't provided
*/
String getCtorJavaDoc();
/**
* @return an ordered map of the arguments of the documented constructor in name,type form.
*/
Map<String, String> getArgs();
/**
* @return a list of examples, where each is list of (example syntax, comment..)
*/
List<List<String>> getExamples();
}

View File

@@ -0,0 +1,92 @@
package io.nosqlbench.virtdata.api.processors;
import io.nosqlbench.virtdata.api.annotations.Category;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
public class DocForFunc implements DocFuncData {
private String packageName;
private String className;
private String classJavadoc;
private String inType;
private String outType;
private ArrayList<DocCtorData> ctors = new ArrayList<>();
private Category[] categories = new Category[] { };
public void setPackageName(String packageName) {
this.packageName = packageName;
}
@Override
public String getPackageName() {
return this.packageName;
}
@Override
public Category[] getCategories() {
return categories;
}
public void setClassName(String className) {
this.className = className;
}
@Override
public String getClassName() {
return className;
}
public void setClassJavadoc(String classJavadoc) {
this.classJavadoc = classJavadoc;
}
@Override
public String getClassJavadoc() {
return classJavadoc;
}
public void setInType(String inType) {
this.inType = inType;
}
@Override
public String getInType() {
return inType;
}
public void setOutType(String outType) {
this.outType = outType;
}
@Override
public String getOutType() {
return outType;
}
public void addCtor(String ctorDoc, LinkedHashMap<String, String> args, List<List<String>> examples) {
if (this.className==null || this.className.isEmpty()) {
throw new RuntimeException("Unable to document ctor without known class name first.");
}
DocForFuncCtor ctor = new DocForFuncCtor(getClassName(), ctorDoc, args, examples);
ctors.add(ctor);
}
@Override
public ArrayList<DocCtorData> getCtors() {
return this.ctors;
}
@Override
public String toString() {
return "DocForFunction{" +
"packageName='" + packageName + '\'' +
", className='" + className + '\'' +
", classJavadoc='" + classJavadoc + '\'' +
", inType='" + inType + '\'' +
", outType='" + outType + '\'' +
", ctors=" + ctors +
'}';
}
public void addCategories(Category[] categories) {
this.categories = categories;
}
}

View File

@@ -0,0 +1,55 @@
package io.nosqlbench.virtdata.api.processors;
import io.nosqlbench.virtdata.api.annotations.ExampleData;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class DocForFuncCtor implements DocCtorData {
private Map<String, String> args = new LinkedHashMap<>();
private String ctorDoc;
private String className;
private List<List<String>> examples = new ArrayList<>();
public DocForFuncCtor(String className, String ctorDoc, Map<String, String> args, List<List<String>> examples) {
this.className = className;
this.ctorDoc = ctorDoc;
this.args.putAll(args);
ExampleData.validateExamples(examples);
this.examples.addAll(examples);
}
@Override
public String getClassName() {
return this.className;
}
@Override
public String getCtorJavaDoc() {
return ctorDoc;
}
@Override
public String toString() {
return "Ctor{" +
"class=" + className +
", args=" + args +
", ctorDoc='" + ctorDoc + '\'' +
'}';
}
@Override
public Map<String, String> getArgs() {
return args;
}
@Override
public List<List<String>> getExamples() {
return examples;
}
}

View File

@@ -0,0 +1,52 @@
package io.nosqlbench.virtdata.api.processors;
import io.nosqlbench.virtdata.api.annotations.Category;
import java.util.List;
/**
* Provide data about a function, suitable for building a documentation site.
*/
public interface DocFuncData {
/**
* @return the package name for the documented type
*/
String getPackageName();
/**
* @return Return the categories for this function.
*/
Category[] getCategories();
/**
* @return the the {@link Class#getSimpleName()} of the class element
*/
String getClassName();
/**
* Javadoc for the class, or null if there is none.
* @return a String of class javadoc data, or null if none
*/
String getClassJavadoc();
/**
* The input type for the apply method in the documented function class.
* Documented function classes must always implement a Java 8 functional interface.
* @return the input type name
*/
String getInType();
/**
* The output type for the apply method in the documented function class.
* Documented function classes must always implement a Java 8 functional interface.
* @return the output type name
*/
String getOutType();
/**
* The list of constructors for this documented type.
* @return a list of constructor models
*/
List<DocCtorData> getCtors();
}

View File

@@ -0,0 +1,94 @@
package io.nosqlbench.virtdata.api.processors;
import io.nosqlbench.virtdata.api.annotations.Category;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
/**
* Example class doc.
*
* Example unordered list:
* <UL>
* <LI>An item1</LI>
* <LI>An item2</LI>
* </UL>
*
* An example class doc paragraph.
*
*/
public class ExampleDocData implements DocFuncData {
@Override
public String getPackageName() {
return "packagename";
}
@Override
public Category[] getCategories() {
return new Category[] { Category.general };
}
@Override
public String getClassName() {
return "classname";
}
@Override
public String getClassJavadoc() {
return "javadoc";
}
@Override
public String getInType() {
return "intype";
}
@Override
public String getOutType() {
return "outtype";
}
@Override
public List<DocCtorData> getCtors() {
ArrayList<DocCtorData> ctors = new ArrayList<>();
// for each ctor
LinkedHashMap<String, String> args = new LinkedHashMap<>();
args.put("arg1", "val1");
List<List<String>> examples = new ArrayList<>();
examples.add(new ArrayList<>() {{ add("example"); add("one"); }});
DocForFuncCtor ctordoc = new DocForFuncCtor("name", "ctordoc", args, examples);
ctors.add(ctordoc);
return ctors;
}
public List<DocForFuncCtor> getCtorsAlternate() {
return new ArrayList<>() {{
add(new DocForFuncCtor("name", "ctordoc",
new LinkedHashMap<>() {{
put("aname", "atype");
}},
new ArrayList<>() {{
add(new ArrayList<>() {{
add("example");
add("description");
}});
}}
));
add(new DocForFuncCtor("name", "ctordoc",
new LinkedHashMap<>() {{
put("aname", "atype");
}},
new ArrayList<>() {{
add(new ArrayList<>() {{
add("example");
}});
}}
));
}};
}
}

View File

@@ -0,0 +1,31 @@
package io.nosqlbench.virtdata.api.processors;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
public class ExampleManifest {
public List<DocFuncData> getDocs() {
ArrayList<DocFuncData> docFuncData = new ArrayList<>();
docFuncData.add(new DocForFunc() {{
setClassName("classname");
setPackageName("packagename");
setClassJavadoc("javadoc");
setInType("intype");
setOutType("outtype");
addCtor("ctordoc",
new LinkedHashMap<String, String>() {{
put("vname", "vtype");
}},
new ArrayList<List<String>>() {{
add(new ArrayList<String>() {{
add("syntax");
add("comment)");
}});
}});
}});
return docFuncData;
}
}

View File

@@ -0,0 +1,76 @@
package io.nosqlbench.virtdata.api.processors;
import io.nosqlbench.virtdata.api.annotations.Category;
import javax.annotation.processing.Filer;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
/**
* This enumerator receives stateful updates out of order from the annotation
* processor and constructs consistent view of document models for listeners.
*/
public class FuncEnumerator {
private final Types types;
private final Elements elements;
private final Filer filer;
private DocForFunc model;
private List<Listener> listeners = new ArrayList<>();
private String anchorPackage;
private String anchorSimpleName;
public FuncEnumerator(Types types, Elements elements, Filer filer) {
this.types = types;
this.elements = elements;
this.filer = filer;
}
public void addListener(Listener listener) {
this.listeners.add(listener);
}
public void onClass(String packageName, String simpleClassName, String classJavadoc) {
if (model!=null) {
throw new RuntimeException("The DocModel was overwritten. Perhaps you are not calling flush() ?");
}
model = new DocForFunc();
model.setPackageName(packageName);
model.setClassName(simpleClassName);
model.setClassJavadoc(classJavadoc);
}
public void onApplyTypes(String inType, String outType) {
model.setInType(inType);
model.setOutType(outType);
}
public void onConstructor(LinkedHashMap<String, String> args, String ctorJavaDoc, List<List<String>> examples) {
model.addCtor(ctorJavaDoc, args, examples);
}
public void flush() {
this.listeners.forEach(l -> l.onFunctionModel(model));
model=null;
}
public void onCategories(Category[] categories) {
model.addCategories(categories);
}
/**
* These Listeners handle data that has been found by the FuncEnumerator.
*/
public interface Listener {
/**
* Handle each logical function model that has been found.
* @param functionDoc the documentation model for a single mapping function
*/
public void onFunctionModel(DocForFunc functionDoc);
}
}

View File

@@ -0,0 +1,216 @@
package io.nosqlbench.virtdata.api.processors;
//io.nosqlbench.virtdata.api.processors.FunctionDocInfoProcessor
//io.nosqlbench.virtdata.api.processors.FunctionDocInfoProcessor
import io.nosqlbench.virtdata.api.annotations.Categories;
import io.nosqlbench.virtdata.api.annotations.Category;
import io.nosqlbench.virtdata.api.annotations.Example;
import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.*;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import javax.tools.Diagnostic;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static io.nosqlbench.virtdata.api.processors.ProcessorClassNames.PerThreadMapper;
import static io.nosqlbench.virtdata.api.processors.ProcessorClassNames.ThreadSafeMapper;/**
* This documentation processor is responsible for finding all the enumerated that feed documentation
* manifests. It simply calls listener interfaces to do the rest of the work.
*/
@SupportedOptions({"title"})
@SupportedSourceVersion(SourceVersion.RELEASE_12)
@SupportedAnnotationTypes({
ThreadSafeMapper,
PerThreadMapper
})
public class FunctionDocInfoProcessor extends AbstractProcessor {
public final static String AUTOSUFFIX = "AutoDocsInfo";
private static Pattern packageNamePattern = Pattern.compile("(?<packageName>.+)?\\.(?<className>.+)");
private Filer filer;
private Map<String, String> options;
private Elements elementUtils;
private Messager messenger;
private SourceVersion sourceVersion;
private Types typeUtils;
private FuncEnumerator enumerator;
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
this.filer = processingEnv.getFiler();
this.options = processingEnv.getOptions();
this.elementUtils = processingEnv.getElementUtils();
this.messenger = processingEnv.getMessager();
this.sourceVersion = processingEnv.getSourceVersion();
this.typeUtils = processingEnv.getTypeUtils();
this.enumerator = new FuncEnumerator(this.typeUtils, this.elementUtils, this.filer);
// enumerator.addListener(new StdoutListener());
// enumerator.addListener(new YamlDocsEnumerator(this.filer, this.messenger));
enumerator.addListener(new FunctionDocInfoWriter(this.filer, this.messenger, AUTOSUFFIX));
}
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
List<Element> ts = new ArrayList<>();
ts.addAll(roundEnv.getElementsAnnotatedWith(io.nosqlbench.virtdata.api.annotations.ThreadSafeMapper.class));
ts.addAll(roundEnv.getElementsAnnotatedWith(io.nosqlbench.virtdata.api.annotations.PerThreadMapper.class));
for (Element classElem : ts) {
if (classElem.getKind() != ElementKind.CLASS) {
throw new RuntimeException("Unexpected kind of element: " + classElem.getKind() + " for " + classElem.toString());
}
// package and Class Name
Name qualifiedName = ((TypeElement) classElem).getQualifiedName();
Matcher pnm = packageNamePattern.matcher(qualifiedName);
if (!pnm.matches()) {
throw new RuntimeException("Unable to match qualified name for package and name: " + qualifiedName);
}
String packageName = pnm.group("packageName");
String simpleClassName = pnm.group("className");
// Class JavaDoc
String classDoc = elementUtils.getDocComment(classElem);
classDoc = classDoc == null ? "" : cleanJavadoc(classDoc);
classDoc = inheritDocs(classDoc,classElem);
enumerator.onClass(packageName, simpleClassName, classDoc);
Categories categoryAnnotation = classElem.getAnnotation(Categories.class);
if (categoryAnnotation!=null) {
Category[] value = categoryAnnotation.value();
enumerator.onCategories(value);
}
// apply method types
boolean foundApply=false;
Element applyMethodElem = null;
Element applyInClassElem = classElem;
while (applyMethodElem==null && applyInClassElem!=null) {
for (Element candidateApplyElem : applyInClassElem.getEnclosedElements()) {
if (candidateApplyElem.getKind() == ElementKind.METHOD) {
if (candidateApplyElem.getSimpleName().toString().startsWith("apply")) {
applyMethodElem = candidateApplyElem;
break;
}
}
}
if (applyMethodElem!=null) {
break;
}
applyInClassElem = elementUtils.getTypeElement(((TypeElement) applyInClassElem).getSuperclass().toString());
}
if (applyMethodElem==null) {
messenger.printMessage(Diagnostic.Kind.ERROR, "Unable to enumerate input and output types for " + simpleClassName);
return false;
}
VariableElement inParam = ((ExecutableElement) applyMethodElem).getParameters().get(0);
String inType = inParam.asType().toString();
String outType = ((ExecutableElement) applyMethodElem).getReturnType().toString();
enumerator.onApplyTypes(inType, outType);
// Ctors
for (Element ctorElem : classElem.getEnclosedElements()) {
if (ctorElem.getKind() == ElementKind.CONSTRUCTOR) {
// Ctor Args
List<? extends VariableElement> parameters = ((ExecutableElement) ctorElem).getParameters();
LinkedHashMap<String, String> args = new LinkedHashMap<>();
boolean isVarArgs = ((ExecutableElement) ctorElem).isVarArgs();
for (int i = 0; i < parameters.size(); i++) {
VariableElement var = parameters.get(i);
String varName = var.getSimpleName().toString();
String varType = var.asType().toString() + (i == parameters.size() - 1 ? (isVarArgs ? "..." : "") : "");
args.put(varName, varType);
}
// Ctor Javadoc
String ctorDoc = elementUtils.getDocComment(ctorElem);
ctorDoc = ctorDoc == null ? "" : cleanJavadoc(ctorDoc);
// Examples
List<List<String>> exampleData = new ArrayList<>();
Example[] exampleAnnotations = ctorElem.getAnnotationsByType(Example.class);
for (Example example : exampleAnnotations) {
example.value();
exampleData.add(Arrays.asList(example.value()));
}
enumerator.onConstructor(args, ctorDoc, exampleData);
}
}
enumerator.flush();
}
return false;
}
private static Pattern inheritDocPattern = Pattern.compile("(?ms)(?<pre>.*)(?<inherit>\\{@inheritDoc})(?<post>.*)$");
private String inheritDocs(String classDoc, Element classElem) {
if (classDoc==null) {
return null;
}
Matcher matcher = inheritDocPattern.matcher(classDoc);
if (!matcher.matches()) {
return classDoc;
}
StringBuilder docData = new StringBuilder();
String pre = matcher.group("pre");
String post = matcher.group("post");
Optional<TypeElement> inheritFromElement = Optional.ofNullable(((TypeElement) classElem).getSuperclass())
.map(String::valueOf)
.map(elementUtils::getTypeElement);
if (!inheritFromElement.isPresent()) {
messenger.printMessage(Diagnostic.Kind.ERROR, "Element " + classElem.toString() + " has '{@inheritDoc}', but a superclass was not found.");
return pre + "UNABLE TO FIND ELEMENT TO INHERIT DOCS FROM for " + classElem.toString() + " " + post;
}
TypeElement inheritFromType = inheritFromElement.get();
String inheritedDocs = elementUtils.getDocComment(inheritFromType);
if (inheritedDocs==null) {
messenger.printMessage(Diagnostic.Kind.ERROR, "javadocs are missing on " + inheritFromElement.toString() + ", but "
+ classElem.toString() + " is trying to inherit docs from it.");
return pre + "UNABLE TO FIND INHERITED DOCS for " + classElem.toString() + " " + post;
}
if (inheritDocPattern.matcher(inheritedDocs).matches()) {
return pre + inheritDocs(inheritedDocs,inheritFromType) + post;
} else {
return pre + inheritedDocs + post;
}
}
private String cleanJavadoc(String ctorDoc) {
return ctorDoc.replaceAll("(?m)^ ", "");
}
private static class StdoutListener implements FuncEnumerator.Listener {
@Override
public void onFunctionModel(DocForFunc functionDoc) {
System.out.println(functionDoc);
}
}
}

View File

@@ -0,0 +1,143 @@
package io.nosqlbench.virtdata.api.processors;
import com.squareup.javapoet.*;
import io.nosqlbench.nb.api.annotations.Service;
import io.nosqlbench.virtdata.api.annotations.Category;
import javax.annotation.processing.Filer;
import javax.annotation.processing.Messager;
import javax.lang.model.element.Modifier;
import javax.tools.Diagnostic;
import java.io.IOException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
public class FunctionDocInfoWriter implements FuncEnumerator.Listener {
private final String suffix;
private Filer filer;
private Messager messenger;
public FunctionDocInfoWriter(Filer filer, Messager messenger, String suffix) {
this.filer = filer;
this.messenger = messenger;
this.suffix = suffix;
}
@Override
public void onFunctionModel(DocForFunc functionDoc) {
TypeSpec typeSpec = this.createInlineClassForDocFuncData(functionDoc,
functionDoc.getClassName() + suffix);
JavaFile javafile = JavaFile.builder(functionDoc.getPackageName(), typeSpec)
.addFileComment("This file is auto-generated.")
.build();
try {
javafile.writeTo(this.filer);
} catch (IOException e) {
messenger.printMessage(Diagnostic.Kind.ERROR, "Error writing javafile " + javafile.packageName + "." + javafile.typeSpec.toString());
throw new RuntimeException(e);
}
}
private TypeSpec createInlineClassForDocFuncData(DocForFunc doc, String newClassName) {
List<MethodSpec> methods = new ArrayList<>();
MethodSpec getClassName = MethodSpec.methodBuilder("getClassName")
.addModifiers(Modifier.PUBLIC)
.returns(String.class)
.addStatement("return $S", doc.getClassName())
.build();
methods.add(getClassName);
MethodSpec getPackageName = MethodSpec.methodBuilder("getPackageName")
.addModifiers(Modifier.PUBLIC)
.returns(String.class)
.addStatement("return $S", doc.getPackageName())
.build();
methods.add(getPackageName);
MethodSpec getClassJavaDoc = MethodSpec.methodBuilder("getClassJavadoc")
.addModifiers(Modifier.PUBLIC)
.returns(String.class)
.addStatement("return $S", doc.getClassJavadoc())
.build();
methods.add(getClassJavaDoc);
MethodSpec getInType = MethodSpec.methodBuilder("getInType")
.addModifiers(Modifier.PUBLIC)
.returns(String.class)
.addStatement("return $S", doc.getInType())
.build();
methods.add(getInType);
MethodSpec getOutType = MethodSpec.methodBuilder("getOutType")
.addModifiers(Modifier.PUBLIC)
.returns(String.class)
.addStatement("return $S", doc.getOutType())
.build();
methods.add(getOutType);
CodeBlock ctorsHead = CodeBlock.builder().add("return new $T<$T>() {{$>\n", ArrayList.class, DocCtorData.class).build();
CodeBlock ctorsTail = CodeBlock.builder().add("$<}}").build();
CodeBlock.Builder ctors = CodeBlock.builder().add(ctorsHead);
for (DocCtorData ctor : doc.getCtors()) {
ctors.add("add(new $T($S, $S, \n$>new $T<String, String>() {{\n$>", DocForFuncCtor.class, ctor.getClassName(), ctor.getCtorJavaDoc(), LinkedHashMap.class);
for (Map.Entry<String, String> arg : ctor.getArgs().entrySet()) {
ctors.add("put($S,$S);\n", arg.getKey(), arg.getValue());
}
ctors.add("$<}},\n");
ctors.add("new $T<$T<$T>>() {{\n$>", ArrayList.class, List.class, String.class);
for (List<String> example : ctor.getExamples()) {
ctors.add("add(new $T<$T>() {{$>\n", ArrayList.class, String.class);
for (String s : example) {
Matcher m = Pattern.compile(Matcher.quoteReplacement("$")).matcher(s);
s=m.replaceAll(m.quoteReplacement("$$"));
ctors.add("add(\"" + s + "\");\n");
}
ctors.add("$<}});\n");
}
ctors.add("$<}}");
ctors.add("\n$<));\n");
}
ctors.add(ctorsTail);
MethodSpec getCategoriesMethod = MethodSpec.methodBuilder("getCategories")
.addModifiers(Modifier.PUBLIC)
.returns(ArrayTypeName.of(Category.class))
.addStatement("return new $T[] { " +
Arrays.stream(doc.getCategories()).map(c -> "Category." + c)
.collect(Collectors.joining(","))+" }", Category.class).build();
methods.add(getCategoriesMethod);
MethodSpec getCtorsMethod = MethodSpec.methodBuilder("getCtors")
.addModifiers(Modifier.PUBLIC)
.returns(ParameterizedTypeName.get(List.class, DocCtorData.class))
.addStatement(ctors.build())
.build();
methods.add(getCtorsMethod);
AnnotationSpec serviceAnnotation = AnnotationSpec.builder(Service.class)
.addMember("value","$T.class",DocFuncData.class)
.build();
TypeSpec manifestType = TypeSpec.classBuilder(newClassName)
.addAnnotation(serviceAnnotation)
.addModifiers(Modifier.PUBLIC)
.addMethods(methods)
.addSuperinterface(DocFuncData.class)
.build();
return manifestType;
}
}

View File

@@ -0,0 +1,76 @@
package io.nosqlbench.virtdata.api.processors;
import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
import javax.tools.StandardLocation;
import java.io.Writer;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import static io.nosqlbench.virtdata.api.processors.ProcessorClassNames.PerThreadMapper;
import static io.nosqlbench.virtdata.api.processors.ProcessorClassNames.ThreadSafeMapper;
/**
* This annotation processor is responsible for finding all annotated functions and adding
* them to the manifest file for the current project.
* Specifically, any class annotated as {@link io.nosqlbench.virtdata.api.annotations.ThreadSafeMapper}
* or {@link io.nosqlbench.virtdata.api.annotations.PerThreadMapper} are recorded in
* <pre>classes/META-INF/functions</pre>
*
* This operates slightly differently than the service loader facility. The point is to
* enumerate candidate functions without requiring them to have a no-args constructor.
*/
@SupportedOptions({"title"})
@SupportedSourceVersion(SourceVersion.RELEASE_12)
@SupportedAnnotationTypes({
ThreadSafeMapper,
PerThreadMapper
})
public class FunctionManifestProcessor extends AbstractProcessor {
private Filer filer;
private Messager messenger;
private Writer writer;
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
this.filer = processingEnv.getFiler();
this.messenger = processingEnv.getMessager();
}
@SuppressWarnings("unchecked")
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
List<Element> ts = new ArrayList<>();
try {
if (writer==null) {
writer = filer.createResource(StandardLocation.CLASS_OUTPUT, "", "META-INF/functions")
.openWriter();
}
for (String annotationType : this.getSupportedAnnotationTypes()) {
Class<? extends Annotation> annotationClass =
(Class<? extends Annotation>) Class.forName(annotationType);
Set<? extends Element> tsms = roundEnv.getElementsAnnotatedWith(annotationClass);
if (tsms.size() > 0) {
for (Element e : tsms) {
writer.write(((TypeElement) e).getQualifiedName() + "\n");
}
}
}
writer.close();
} catch (Exception e) {
messenger.printMessage(Diagnostic.Kind.ERROR, e.toString());
}
return false;
}
}

View File

@@ -0,0 +1,12 @@
package io.nosqlbench.virtdata.api.processors;
/**
* Statically defined names which need to be visible for refactoring
* and safe source manipulation.
*/
public class ProcessorClassNames {
public final static String ThreadSafeMapper =
"io.nosqlbench.virtdata.api.annotations.ThreadSafeMapper";
public final static String PerThreadMapper =
"io.nosqlbench.virtdata.api.annotations.PerThreadMapper";
}

View File

@@ -1,4 +1,4 @@
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.core.bindings;
/***
* A Binder is a type that knows how to return a result object given a long value

View File

@@ -16,7 +16,7 @@
*
*/
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.core.bindings;
//
@@ -36,7 +36,8 @@ import java.util.*;
* directly on your provided objects. See the detailed method docs for more information.</p>
*/
public class Bindings {
private final static Logger logger = LogManager.getLogger(Bindings.class);private BindingsTemplate template;
private final static Logger logger = LogManager.getLogger(Bindings.class);
private BindingsTemplate template;
private List<DataMapper<?>> dataMappers = new ArrayList<DataMapper<?>>();
private ThreadLocal<Map<String, DataMapper<?>>> nameCache;

View File

@@ -12,7 +12,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.core.bindings;
import java.util.HashMap;
import java.util.Map;

View File

@@ -16,11 +16,11 @@
*
*/
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.core.bindings;
//
import io.nosqlbench.virtdata.api.templates.BindPoint;
import io.nosqlbench.virtdata.core.templates.BindPoint;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
@@ -38,7 +38,8 @@ import java.util.Optional;
* bindings will be used in.
*/
public class BindingsTemplate {
private final static Logger logger = LogManager.getLogger(BindingsTemplate.class);private List<String> bindPointNames = new ArrayList<>();
private final static Logger logger = LogManager.getLogger(BindingsTemplate.class);
private List<String> bindPointNames = new ArrayList<>();
private List<String> specifiers = new ArrayList<>();
// public BindingsTemplate(Map<String,String> specs) {

View File

@@ -1,4 +1,4 @@
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.core.bindings;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
@@ -11,7 +11,9 @@ import java.util.regex.Pattern;
public class CompatibilityFixups {
private final static Logger logger = LogManager.getLogger(CompatibilityFixups.class);// Not all of these are simple upper-case changes
private final static Logger logger = LogManager.getLogger(CompatibilityFixups.class);
// Not all of these are simple upper-case changes
private final static Map<String,String> funcs = new HashMap<String,String>() {{
put("log_normal","LogNormal");
put("normal", "Normal");

View File

@@ -1,4 +1,4 @@
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.core.bindings;
/**
* <p>A thread-local template that describes a set of data mappers, a context object,

View File

@@ -1,4 +1,4 @@
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.core.bindings;
/**
* <p>A thread-local template that describes a set of data mappers, a context object, and a method for applying

View File

@@ -1,4 +1,4 @@
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.core.bindings;
/**
* A template that maps a set of specifiers, a context object, and a method for applying

View File

@@ -1,4 +1,4 @@
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.core.bindings;
/**
* A template that maps a set of specifiers, a context object, and a method for applying

View File

@@ -1,4 +1,4 @@
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.core.bindings;
import java.util.HashMap;
import java.util.Map;

View File

@@ -1,4 +1,4 @@
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.core.bindings;
public interface DataMapper<R> {
R get(long input);

View File

@@ -1,7 +1,4 @@
package io.nosqlbench.virtdata.api;
import io.nosqlbench.virtdata.api.FunctionType;
import io.nosqlbench.virtdata.api.DataMapper;
package io.nosqlbench.virtdata.core.bindings;
import java.util.function.*;

View File

@@ -1,4 +1,4 @@
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.core.bindings;
import java.util.List;
import java.util.Optional;

View File

@@ -12,9 +12,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.core.bindings;
import io.nosqlbench.virtdata.api.DataMapperLibrary;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;

View File

@@ -1,4 +1,4 @@
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.core.bindings;
import java.util.function.*;

View File

@@ -1,4 +1,4 @@
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.core.bindings;
import java.lang.reflect.Method;
import java.util.Arrays;

View File

@@ -12,7 +12,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.core.bindings;
import java.util.*;

View File

@@ -1,4 +1,4 @@
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.core.bindings;
public interface Named {
/**

View File

@@ -1,4 +1,4 @@
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.core.bindings;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method;

View File

@@ -1,4 +1,4 @@
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.core.bindings;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
@@ -9,7 +9,9 @@ import java.util.Optional;
public class ResolverDiagnostics {
private final static Logger logger = LogManager.getLogger(ResolverDiagnostics.class);private ResolvedFunction resolvedFunction;
private final static Logger logger = LogManager.getLogger(ResolverDiagnostics.class);
private ResolvedFunction resolvedFunction;
private final StringBuilder log = new StringBuilder();
private Throwable error;

View File

@@ -1,4 +1,4 @@
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.core.bindings;
import java.math.BigDecimal;
import java.math.BigInteger;

View File

@@ -1,4 +1,4 @@
package io.nosqlbench.virtdata.api;/*
package io.nosqlbench.virtdata.core.bindings;/*
* Copyright 2016 jshook
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,6 +1,6 @@
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.core.bindings;
import io.nosqlbench.virtdata.api.templates.StringCompositor;
import io.nosqlbench.virtdata.core.templates.StringCompositor;
/**
* <p>ValuesArrayBinder provides a way to apply an array of object values to a template

View File

@@ -1,4 +1,4 @@
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.core.bindings;
/**
* <p>ValuesBinder provides a way to apply an map of named object values to a template

View File

@@ -1,4 +1,4 @@
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.core.bindings;
import java.util.Map;

View File

@@ -1,8 +1,8 @@
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.core.bindings;
import io.nosqlbench.virtdata.lang.ast.VirtDataFlow;
import io.nosqlbench.virtdata.lang.parser.VirtDataDSL;
import io.nosqlbench.virtdata.api.templates.BindPoint;
import io.nosqlbench.virtdata.core.templates.BindPoint;
import org.apache.commons.lang3.ClassUtils;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
@@ -10,7 +10,8 @@ import org.apache.logging.log4j.LogManager;
import java.util.*;
public class VirtData {
private final static Logger logger = LogManager.getLogger(VirtData.class);/**
private final static Logger logger = LogManager.getLogger(VirtData.class);
/**
* Create a bindings template from the pair-wise names and specifiers.
* Each even-numbered (starting with zero) argument is a binding name,
* and each odd-numbered (starting with one) argument is a binding spec.

View File

@@ -1,6 +1,6 @@
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.core.bindings;
import io.nosqlbench.virtdata.api.composers.FunctionAssembly;
import io.nosqlbench.virtdata.core.composers.FunctionAssembly;
import io.nosqlbench.virtdata.lang.ast.FunctionCall;
import io.nosqlbench.virtdata.lang.ast.VirtDataFlow;
import io.nosqlbench.virtdata.lang.parser.VirtDataDSL;
@@ -50,7 +50,8 @@ import java.util.stream.Collectors;
public class VirtDataComposer {
private final static String PREAMBLE = "compose ";
private final static Logger logger = LogManager.getLogger(DataMapperLibrary.class);private final static MethodHandles.Lookup lookup = MethodHandles.publicLookup();
private final static Logger logger = LogManager.getLogger(DataMapperLibrary.class);
private final static MethodHandles.Lookup lookup = MethodHandles.publicLookup();
private final VirtDataFunctionLibrary functionLibrary;
private final Map<String,Object> customElements = new HashMap<>();

View File

@@ -1,7 +1,7 @@
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.core.bindings;
import io.nosqlbench.virtdata.processors.DocFuncData;
import io.nosqlbench.virtdata.processors.FunctionDocInfoProcessor;
import io.nosqlbench.virtdata.api.processors.DocFuncData;
import io.nosqlbench.virtdata.api.processors.FunctionDocInfoProcessor;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
@@ -11,8 +11,8 @@ import java.util.List;
/**
* This is the top-level API supporting access to the documentation models
* for all known {@link io.nosqlbench.virtdata.annotations.ThreadSafeMapper} and
* {@link io.nosqlbench.virtdata.annotations.PerThreadMapper} instances in the runtime.
* for all known {@link io.nosqlbench.virtdata.api.annotations.ThreadSafeMapper} and
* {@link io.nosqlbench.virtdata.api.annotations.PerThreadMapper} instances in the runtime.
*/
public class VirtDataDocs {

View File

@@ -1,6 +1,6 @@
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.core.bindings;
import io.nosqlbench.virtdata.processors.DocFuncData;
import io.nosqlbench.virtdata.api.processors.DocFuncData;
import java.util.ArrayList;
import java.util.List;
@@ -19,4 +19,4 @@ public class VirtDataFunctionFinder {
List<String> cleaned = names.stream().sorted().distinct().collect(Collectors.toList());
return cleaned;
}
}
}

View File

@@ -1,4 +1,4 @@
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.core.bindings;
import io.nosqlbench.virtdata.lang.ast.Expression;
import io.nosqlbench.virtdata.lang.ast.FunctionCall;

View File

@@ -1,7 +1,7 @@
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.core.bindings;
import io.nosqlbench.virtdata.annotations.ThreadSafeMapper;
import io.nosqlbench.virtdata.api.config.ConfigAware;
import io.nosqlbench.virtdata.api.annotations.ThreadSafeMapper;
import io.nosqlbench.virtdata.core.config.ConfigAware;
import org.apache.commons.lang3.ClassUtils;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
@@ -16,7 +16,8 @@ import java.util.*;
import java.util.stream.Collectors;
public class VirtDataFunctionResolver {
private final static Logger logger = LogManager.getLogger(VirtDataFunctionResolver.class);private final static MethodHandles.Lookup lookup = MethodHandles.publicLookup();
private final static Logger logger = LogManager.getLogger(VirtDataFunctionResolver.class);
private final static MethodHandles.Lookup lookup = MethodHandles.publicLookup();
private final VirtDataFunctionFinder virtDataFunctionFinder = new VirtDataFunctionFinder();
public List<ResolvedFunction> resolveFunctions(Class<?> returnType, Class<?> inputType, String functionName, Map<String,?> customParameters, Object... parameters) {

View File

@@ -1,4 +1,4 @@
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.core.bindings;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
@@ -9,7 +9,8 @@ import java.util.List;
import java.util.Map;
public class VirtDataLibraries implements VirtDataFunctionLibrary {
private final static Logger logger = LogManager.getLogger(VirtDataLibraries.class);private static VirtDataLibraries instance = new VirtDataLibraries();
private final static Logger logger = LogManager.getLogger(VirtDataLibraries.class);
private static VirtDataLibraries instance = new VirtDataLibraries();
private final Map<String,DataMapper<?>> threadSafeCache = new HashMap<>();
private final VirtDataFunctionResolver resolver = new VirtDataFunctionResolver();

View File

@@ -1,4 +1,4 @@
package io.nosqlbench.virtdata.api;
package io.nosqlbench.virtdata.core.bindings;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;

View File

@@ -1,7 +1,7 @@
package io.nosqlbench.virtdata.api.composers;
package io.nosqlbench.virtdata.core.composers;
import io.nosqlbench.virtdata.api.FunctionType;
import io.nosqlbench.virtdata.api.ValueType;
import io.nosqlbench.virtdata.core.bindings.FunctionType;
import io.nosqlbench.virtdata.core.bindings.ValueType;
import java.util.function.*;

View File

@@ -1,6 +1,6 @@
package io.nosqlbench.virtdata.api.composers;
package io.nosqlbench.virtdata.core.composers;
import io.nosqlbench.virtdata.api.FunctionType;
import io.nosqlbench.virtdata.core.bindings.FunctionType;
import java.util.function.*;

View File

@@ -1,6 +1,6 @@
package io.nosqlbench.virtdata.api.composers;
package io.nosqlbench.virtdata.core.composers;
import io.nosqlbench.virtdata.api.FunctionType;
import io.nosqlbench.virtdata.core.bindings.FunctionType;
import java.util.function.*;

View File

@@ -1,6 +1,6 @@
package io.nosqlbench.virtdata.api.composers;
package io.nosqlbench.virtdata.core.composers;
import io.nosqlbench.virtdata.api.FunctionType;
import io.nosqlbench.virtdata.core.bindings.FunctionType;
import java.util.function.*;

View File

@@ -1,7 +1,7 @@
package io.nosqlbench.virtdata.api.composers;
package io.nosqlbench.virtdata.core.composers;
import io.nosqlbench.virtdata.api.FunctionType;
import io.nosqlbench.virtdata.api.ValueType;
import io.nosqlbench.virtdata.core.bindings.FunctionType;
import io.nosqlbench.virtdata.core.bindings.ValueType;
import java.util.function.*;

View File

@@ -1,7 +1,7 @@
package io.nosqlbench.virtdata.api.composers;
package io.nosqlbench.virtdata.core.composers;
import io.nosqlbench.virtdata.api.FunctionType;
import io.nosqlbench.virtdata.api.ValueType;
import io.nosqlbench.virtdata.core.bindings.FunctionType;
import io.nosqlbench.virtdata.core.bindings.ValueType;
import java.util.function.*;

View File

@@ -1,6 +1,6 @@
package io.nosqlbench.virtdata.api.composers;
package io.nosqlbench.virtdata.core.composers;
import io.nosqlbench.virtdata.api.FunctionType;
import io.nosqlbench.virtdata.core.bindings.FunctionType;
import java.util.function.*;

View File

@@ -1,6 +1,6 @@
package io.nosqlbench.virtdata.api.composers;
package io.nosqlbench.virtdata.core.composers;
import io.nosqlbench.virtdata.api.FunctionType;
import io.nosqlbench.virtdata.core.bindings.FunctionType;
import java.util.function.*;

View File

@@ -1,6 +1,6 @@
package io.nosqlbench.virtdata.api.composers;
package io.nosqlbench.virtdata.core.composers;
import io.nosqlbench.virtdata.api.FunctionType;
import io.nosqlbench.virtdata.core.bindings.FunctionType;
import java.util.function.*;

View File

@@ -1,14 +1,15 @@
package io.nosqlbench.virtdata.api.composers;
package io.nosqlbench.virtdata.core.composers;
import io.nosqlbench.virtdata.api.FunctionType;
import io.nosqlbench.virtdata.api.ValueType;
import io.nosqlbench.virtdata.core.bindings.FunctionType;
import io.nosqlbench.virtdata.core.bindings.ValueType;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import java.util.function.*;
public class ComposerForLongFunction implements FunctionComposer<LongFunction<?>> {
private final static Logger logger = LogManager.getLogger(ComposerForLongFunction.class);private final LongFunction<?> inner;
private final static Logger logger = LogManager.getLogger(ComposerForLongFunction.class);
private final LongFunction<?> inner;
public ComposerForLongFunction(LongFunction<?> inner) {
this.inner = inner;

View File

@@ -1,6 +1,6 @@
package io.nosqlbench.virtdata.api.composers;
package io.nosqlbench.virtdata.core.composers;
import io.nosqlbench.virtdata.api.FunctionType;
import io.nosqlbench.virtdata.core.bindings.FunctionType;
import java.util.function.*;

View File

@@ -1,6 +1,6 @@
package io.nosqlbench.virtdata.api.composers;
package io.nosqlbench.virtdata.core.composers;
import io.nosqlbench.virtdata.api.FunctionType;
import io.nosqlbench.virtdata.core.bindings.FunctionType;
import java.util.function.*;

View File

@@ -1,6 +1,6 @@
package io.nosqlbench.virtdata.api.composers;
package io.nosqlbench.virtdata.core.composers;
import io.nosqlbench.virtdata.api.FunctionType;
import io.nosqlbench.virtdata.core.bindings.FunctionType;
import java.util.function.*;

View File

@@ -1,13 +1,14 @@
package io.nosqlbench.virtdata.api.composers;
package io.nosqlbench.virtdata.core.composers;
import io.nosqlbench.virtdata.api.FunctionType;
import io.nosqlbench.virtdata.core.bindings.FunctionType;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import java.util.function.*;
public class FunctionAssembly implements FunctionComposer {
private final static Logger logger = LogManager.getLogger(FunctionAssembly.class);private FunctionComposer<?> composer = null;
private final static Logger logger = LogManager.getLogger(FunctionAssembly.class);
private FunctionComposer<?> composer = null;
@Override
public Object getFunctionObject() {

View File

@@ -1,9 +1,9 @@
package io.nosqlbench.virtdata.api.composers;
package io.nosqlbench.virtdata.core.composers;
import io.nosqlbench.virtdata.annotations.ThreadSafeMapper;
import io.nosqlbench.virtdata.api.DataMapper;
import io.nosqlbench.virtdata.api.DataMapperFunctionMapper;
import io.nosqlbench.virtdata.api.ResolvedFunction;
import io.nosqlbench.virtdata.api.annotations.ThreadSafeMapper;
import io.nosqlbench.virtdata.core.bindings.DataMapper;
import io.nosqlbench.virtdata.core.bindings.DataMapperFunctionMapper;
import io.nosqlbench.virtdata.core.bindings.ResolvedFunction;
public interface FunctionComposer<T> {

View File

@@ -1,4 +1,4 @@
package io.nosqlbench.virtdata.api.config;
package io.nosqlbench.virtdata.core.config;
import java.util.Map;

View File

@@ -1,4 +1,4 @@
package io.nosqlbench.virtdata.api.config;
package io.nosqlbench.virtdata.core.config;
import java.util.List;

View File

@@ -1,4 +1,4 @@
package io.nosqlbench.virtdata.api.config;
package io.nosqlbench.virtdata.core.config;
import java.util.ArrayList;
import java.util.Collections;

View File

@@ -1,4 +1,4 @@
package io.nosqlbench.virtdata.api.templates;
package io.nosqlbench.virtdata.core.templates;
import java.util.Objects;

View File

@@ -1,7 +1,7 @@
package io.nosqlbench.virtdata.api.templates;
package io.nosqlbench.virtdata.core.templates;
import io.nosqlbench.virtdata.api.Binder;
import io.nosqlbench.virtdata.api.Bindings;
import io.nosqlbench.virtdata.core.bindings.Binder;
import io.nosqlbench.virtdata.core.bindings.Bindings;
public class CSVBindings implements Binder<String> {

View File

@@ -1,7 +1,7 @@
package io.nosqlbench.virtdata.api.templates;
package io.nosqlbench.virtdata.core.templates;
import io.nosqlbench.virtdata.api.Bindings;
import io.nosqlbench.virtdata.api.BindingsTemplate;
import io.nosqlbench.virtdata.core.bindings.Bindings;
import io.nosqlbench.virtdata.core.bindings.BindingsTemplate;
public class CSVBindingsTemplate {

View File

@@ -15,7 +15,7 @@
* /
*/
package io.nosqlbench.virtdata.api.templates;
package io.nosqlbench.virtdata.core.templates;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
@@ -87,7 +87,8 @@ public class ParsedTemplate {
Pattern.compile("\\{(?<anchor>\\w+[-_\\d\\w.]*)}"),
Pattern.compile("\\?(?<anchor>\\w+[-_\\d\\w.]*)")
};
private final static Logger logger = LogManager.getLogger(ParsedTemplate.class);private final Pattern[] patterns;
private final static Logger logger = LogManager.getLogger(ParsedTemplate.class);
private final Pattern[] patterns;
// Spans is an even-odd form of (literal, variable, ..., ..., literal)
private final String rawtemplate;
private final String[] spans;

View File

@@ -1,7 +1,7 @@
package io.nosqlbench.virtdata.api.templates;
package io.nosqlbench.virtdata.core.templates;
import io.nosqlbench.virtdata.api.Binder;
import io.nosqlbench.virtdata.api.Bindings;
import io.nosqlbench.virtdata.core.bindings.Binder;
import io.nosqlbench.virtdata.core.bindings.Bindings;
/**
* Allows the generation of strings from a string template and bindings template.

View File

@@ -1,7 +1,7 @@
package io.nosqlbench.virtdata.api.templates;
package io.nosqlbench.virtdata.core.templates;
import io.nosqlbench.virtdata.api.Bindings;
import io.nosqlbench.virtdata.api.BindingsTemplate;
import io.nosqlbench.virtdata.core.bindings.Bindings;
import io.nosqlbench.virtdata.core.bindings.BindingsTemplate;
import java.util.HashSet;

View File

@@ -1,7 +1,7 @@
package io.nosqlbench.virtdata.api.templates;
package io.nosqlbench.virtdata.core.templates;
import io.nosqlbench.virtdata.api.ValuesBinder;
import io.nosqlbench.virtdata.api.Bindings;
import io.nosqlbench.virtdata.core.bindings.ValuesBinder;
import io.nosqlbench.virtdata.core.bindings.Bindings;
import java.util.ArrayList;
import java.util.Collections;

View File

@@ -1,6 +1,6 @@
package io.nosqlbench.virtdata.api.templates;
package io.nosqlbench.virtdata.core.templates;
import io.nosqlbench.virtdata.api.ValuesArrayBinder;
import io.nosqlbench.virtdata.core.bindings.ValuesArrayBinder;
import java.util.ArrayList;
import java.util.List;

View File

@@ -1,5 +1,6 @@
package io.nosqlbench.virtdata.annotations;
import io.nosqlbench.virtdata.api.annotations.ExampleData;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
@@ -27,4 +28,4 @@ public class ExampleDataTest {
assertThat(afew).containsExactly(1L,2L,-3L);
}
}
}

View File

@@ -1,6 +1,6 @@
package io.nosqlbench.virtdata.core;
import io.nosqlbench.virtdata.api.CompatibilityFixups;
import io.nosqlbench.virtdata.core.bindings.CompatibilityFixups;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
@@ -33,4 +33,4 @@ public class CompatibilityFixupsTest {
}
}
}

View File

@@ -1,6 +1,6 @@
package io.nosqlbench.virtdata.core;
import io.nosqlbench.virtdata.api.ResolvedFunction;
import io.nosqlbench.virtdata.core.bindings.ResolvedFunction;
import org.junit.Test;
import java.util.function.LongUnaryOperator;
@@ -48,4 +48,4 @@ public class ResolvedFunctionTest {
return a + operand;
}
}
}
}

View File

@@ -1,7 +1,7 @@
package io.nosqlbench.virtdata.core;
import io.nosqlbench.virtdata.api.ResolverDiagnostics;
import io.nosqlbench.virtdata.api.VirtDataComposer;
import io.nosqlbench.virtdata.core.bindings.ResolverDiagnostics;
import io.nosqlbench.virtdata.core.bindings.VirtDataComposer;
import org.junit.Test;
public class VirtDataComposerTest {
@@ -19,4 +19,4 @@ public class VirtDataComposerTest {
@Test
public void testResolveFunctionFlow1() {
}
}
}

View File

@@ -1,7 +1,7 @@
package io.nosqlbench.virtdata.core;
import io.nosqlbench.virtdata.api.BindingsTemplate;
import io.nosqlbench.virtdata.api.VirtData;
import io.nosqlbench.virtdata.core.bindings.BindingsTemplate;
import io.nosqlbench.virtdata.core.bindings.VirtData;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
@@ -14,4 +14,4 @@ public class VirtDataTest {
assertThat(bt).isNotNull();
}
}
}

View File

@@ -1,10 +1,8 @@
package io.nosqlbench.virtdata.composers;
package io.nosqlbench.virtdata.core.composers;
import io.nosqlbench.virtdata.api.DataMapper;
import io.nosqlbench.virtdata.api.FunctionType;
import io.nosqlbench.virtdata.api.composers.FunctionAssembly;
import io.nosqlbench.virtdata.api.composers.FunctionComposer;
import io.nosqlbench.virtdata.api.DataMapperFunctionMapper;
import io.nosqlbench.virtdata.core.bindings.DataMapper;
import io.nosqlbench.virtdata.core.bindings.FunctionType;
import io.nosqlbench.virtdata.core.bindings.DataMapperFunctionMapper;
import org.junit.Test;
import java.util.ArrayList;

View File

@@ -1,8 +1,6 @@
package io.nosqlbench.virtdata.composers;
package io.nosqlbench.virtdata.core.composers;
import io.nosqlbench.virtdata.api.DataMapper;
import io.nosqlbench.virtdata.api.composers.FunctionAssembly;
import io.nosqlbench.virtdata.api.composers.FunctionComposer;
import io.nosqlbench.virtdata.core.bindings.DataMapper;
import org.junit.Test;
import java.util.function.Function;
@@ -129,4 +127,4 @@ public class FunctionAssemblerTest {
}
}
}
}

View File

@@ -1,5 +1,7 @@
package io.nosqlbench.virtdata.api.templates;
package io.nosqlbench.virtdata.core.templates;
import io.nosqlbench.virtdata.core.templates.BindPoint;
import io.nosqlbench.virtdata.core.templates.ParsedTemplate;
import org.junit.Test;
import java.security.InvalidParameterException;
@@ -114,4 +116,4 @@ public class ParsedTemplateTest {
}
}
}

View File

@@ -1,6 +1,6 @@
package io.nosqlbench.virtdata.api.templates;
package io.nosqlbench.virtdata.core.templates;
import io.nosqlbench.virtdata.api.BindingsTemplate;
import io.nosqlbench.virtdata.core.bindings.BindingsTemplate;
import org.junit.Test;
public class StringBindingsTemplateTest {
@@ -15,4 +15,4 @@ public class StringBindingsTemplateTest {
StringBindings resolved = sbt.resolve();
}
}
}

Some files were not shown because too many files have changed in this diff Show More