markrmiller commented on a change in pull request #214:
URL: https://github.com/apache/solr/pull/214#discussion_r672482454



##########
File path: solr/test-framework/src/java/org/apache/solr/util/RandomizeSSL.java
##########
@@ -104,10 +105,10 @@ public SSLRandomizer(double ssl, double clientAuth, 
String debug) {
     public SSLTestConfig createSSLTestConfig() {
       // even if we know SSL is disabled, always consume the same amount of 
randomness
       // that way all other test behavior should be consistent even if a user 
adds/removes @SuppressSSL
-      
-      final boolean useSSL = TestUtil.nextInt(LuceneTestCase.random(), 0, 999) 
<
+      Random random = new Random();

Review comment:
       Because we use randoms differently in the benchmark stuff and don't want 
to be stuck with Randomized testing randoms.
   
   This change was not intended to stick here though, that was from early 
workarounds.
   
   I don't really want the random enforcement / support from the test framework 
for a couple reasons, but this is simply something not removed - the problem 
being if you used the mincluster and jetty with jetty.testMode=true and did not 
launch things via carrot randomized runner, it will *sometimes* detect you dont 
have a test randomized context for a thread and fail you - but we are not using 
randomized runner or junit. Currently, I work around needing this workaround by 
not using the jetty.testMode sys prop path and adding another sys prop hack atm 
for where starting the mini cluster is a bit too tied into the test framework 
and carrot random reqs.
   
   Java 7 and up has essentially made Random obsolete, so there needs to be 
some separate regardless, because we don't use carrot2 junit runners for 
benchmarks, but it's also much preferable, faster, improved to avoid Random 
entirely and use ThreadLocalRandom and SplittableRandom instead, so i try and 
use them in the benchmarks.

##########
File path: solr/test-framework/src/java/org/apache/solr/util/RandomizeSSL.java
##########
@@ -104,10 +105,10 @@ public SSLRandomizer(double ssl, double clientAuth, 
String debug) {
     public SSLTestConfig createSSLTestConfig() {
       // even if we know SSL is disabled, always consume the same amount of 
randomness
       // that way all other test behavior should be consistent even if a user 
adds/removes @SuppressSSL
-      
-      final boolean useSSL = TestUtil.nextInt(LuceneTestCase.random(), 0, 999) 
<
+      Random random = new Random();

Review comment:
       Because we use randoms differently in the benchmark stuff and don't want 
to be stuck with Randomized testing randoms.
   
   This change was not intended to stick here though, that was from early 
workarounds.
   
   I don't really want the random enforcement / support from the test framework 
for a couple reasons, but this is simply something not removed - the problem 
being if you used the mincluster and jetty with jetty.testMode=true and did not 
launch things via carrot randomized runner, it will *sometimes* detect you dont 
have a test randomized context for a thread and fail you - but we are not using 
randomized runner or junit. Currently, I work around needing this workaround by 
not using the jetty.testMode sys prop path and adding another sys prop hack atm 
for where starting the mini cluster is a bit too tied into the test framework 
and carrot random reqs.
   
   Java 7 and up has essentially made Random obsolete, so there needs to be 
some separation regardless, because we don't use carrot2 junit runners for 
benchmarks, but it's also much preferable, faster, improved to avoid Random 
entirely and use ThreadLocalRandom and SplittableRandom instead, so i try and 
use them in the benchmarks.

##########
File path: 
solr/test-framework/src/java/org/apache/solr/cloud/SolrCloudTestCase.java
##########
@@ -124,8 +124,18 @@ public Builder(int nodeCount, Path baseDir) {
       // By default the MiniSolrCloudCluster being built will randomly (seed 
based) decide which collection API strategy
       // to use (distributed or Overseer based) and which cluster update 
strategy to use (distributed if collection API
       // is distributed, but Overseer based or distributed randomly chosen if 
Collection API is Overseer based)
-      this.useDistributedCollectionConfigSetExecution = 
LuceneTestCase.random().nextInt(2) == 0;
-      this.useDistributedClusterStateUpdate = 
useDistributedCollectionConfigSetExecution || 
LuceneTestCase.random().nextInt(2) == 0;
+
+      Boolean skipDistRandomSetup = 
Boolean.getBoolean("solr.tests.skipDistributedConfigAndClusterStateRandomSetup");

Review comment:
       This is essentially a get it working hack at the moment. Ideally, it's 
simpler to use MiniSolrCluster without having to worry about this 
SolrCloudTestCase / carrot random tie in.
   
   You really want a consistent experience when using the class itself. It's 
running things via tests that should enable the randomization.

##########
File path: solr/test-framework/build.gradle
##########
@@ -19,10 +19,131 @@ apply plugin: 'java-library'
 
 description = 'Solr Test Framework'
 
+sourceSets {
+  // Note that just declaring this sourceset creates two configurations.
+  jmh {
+    java.srcDirs = ['src/jmh']
+  }
+}
+
+compileJmhJava {
+  doFirst {
+    options.compilerArgs.remove("-Werror")
+    options.compilerArgs.remove("-proc:none")
+  }
+}
+
+forbiddenApisJmh {
+  bundledSignatures += [
+          'jdk-unsafe',
+          'jdk-deprecated',
+          'jdk-non-portable',
+  ]
+
+  suppressAnnotations += [
+          "**.SuppressForbidden"
+  ]
+}
+
+
+task jmh(type: JavaExec) {
+  dependsOn("jmhClasses")
+  group = "benchmark"
+  main = "org.openjdk.jmh.Main"
+  classpath = sourceSets.jmh.compileClasspath + sourceSets.jmh.runtimeClasspath
+
+  standardOutput(System.out)
+  errorOutput(System.err)
+
+  def include = project.properties.get('include');
+  def exclude = project.properties.get('exclude');
+  def format = project.properties.get('format', 'json');
+  def profilers = project.properties.get('profilers');
+  def jvmArgs = project.properties.get('jvmArgs')
+  def verify = project.properties.get('verify');
+
+  def resultFile = file("build/reports/jmh/result.${format}")
+
+  if (include) {
+    args include
+  }
+  if (exclude) {
+    args '-e', exclude
+  }
+  if (verify != null) {
+    // execute benchmarks with the minimum amount of execution (only to check 
if they are working)
+    println "≥≥ Running in verify mode"
+    args '-f', 1
+    args '-wi', 1
+    args '-i', 1
+  }
+  args '-foe', 'true'   //fail-on-error
+  args '-v', 'NORMAL'   //verbosity [SILENT, NORMAL, EXTRA]
+  if (profilers) {
+    profilers.split(',').each {
+      args '-prof', it
+    }
+  }
+
+  args '-jvmArgsPrepend', '-Xms4g'
+  args '-jvmArgsPrepend', '-Djmh.separateClassLoader=true'
+  args '-jvmArgsPrepend', '-Dlog4j2.is.webapp=false'
+  args '-jvmArgsPrepend', '-Dlog4j2.garbagefreeThreadContextMap=true'
+  args '-jvmArgsPrepend', '-Dlog4j2.enableDirectEncoders=true'
+  args '-jvmArgsPrepend', '-Dlog4j2.enable.threadlocals=true'
+//  args '-jvmArgsPrepend', '-XX:ConcGCThreads=2'
+//  args '-jvmArgsPrepend', '-XX:ParallelGCThreads=3'
+//  args '-jvmArgsPrepend', '-XX:+UseG1GC'
+  args '-jvmArgsPrepend', '-Djetty.insecurerandom=1'
+  args '-jvmArgsPrepend', '-Djava.security.egd=file:/dev/./urandom'
+  args '-jvmArgsPrepend', '-XX:-UseBiasedLocking'
+  args '-jvmArgsPrepend', '-XX:+PerfDisableSharedMem'
+  args '-jvmArgsPrepend', '-XX:+ParallelRefProcEnabled'
+//  args '-jvmArgsPrepend', '-XX:MaxGCPauseMillis=250'
+  args '-jvmArgsPrepend', '-Dsolr.log.dir='
+
+  if (jvmArgs) {
+    for (jvmArg in jvmArgs.split(' ')) {
+      args '-jvmArgsPrepend', jvmArg
+    }
+  }
+
+  args '-rf', format
+  args '-rff', resultFile
+
+  doFirst {
+    // println "\nClasspath:" + jmh.classpath.toList()
+    println "\nExecuting JMH with: $args \n"
+
+    args '-jvmArgsPrepend', '-Djava.class.path='+ toPath(getClasspath().files)
+    resultFile.parentFile.mkdirs()
+  }
+
+  doLast {
+    // jvmArgs "java.class.path", toPath(jmh.classpath)
+  }
+
+}
+
+
+private String toPath(Set<File> classpathUnderTest) {

Review comment:
       I still need to work out if this is still needed. It was needed because 
when running via gradle and using jmh's fork option, the classpath was not 
propagated. I have sense simplified the integration (realizing I was jumping 
hoops because our build was putting in -proc:none for all java compile tasks) 
and I have to double check to make sure this is still necessary.

##########
File path: solr/test-framework/build.gradle
##########
@@ -19,10 +19,131 @@ apply plugin: 'java-library'
 
 description = 'Solr Test Framework'
 
+sourceSets {
+  // Note that just declaring this sourceset creates two configurations.
+  jmh {
+    java.srcDirs = ['src/jmh']
+  }
+}
+
+compileJmhJava {
+  doFirst {
+    options.compilerArgs.remove("-Werror")
+    options.compilerArgs.remove("-proc:none")
+  }
+}
+
+forbiddenApisJmh {
+  bundledSignatures += [
+          'jdk-unsafe',
+          'jdk-deprecated',
+          'jdk-non-portable',
+  ]
+
+  suppressAnnotations += [
+          "**.SuppressForbidden"
+  ]
+}
+
+
+task jmh(type: JavaExec) {
+  dependsOn("jmhClasses")
+  group = "benchmark"
+  main = "org.openjdk.jmh.Main"
+  classpath = sourceSets.jmh.compileClasspath + sourceSets.jmh.runtimeClasspath
+
+  standardOutput(System.out)
+  errorOutput(System.err)
+
+  def include = project.properties.get('include');
+  def exclude = project.properties.get('exclude');
+  def format = project.properties.get('format', 'json');
+  def profilers = project.properties.get('profilers');
+  def jvmArgs = project.properties.get('jvmArgs')
+  def verify = project.properties.get('verify');
+
+  def resultFile = file("build/reports/jmh/result.${format}")
+
+  if (include) {
+    args include
+  }
+  if (exclude) {
+    args '-e', exclude
+  }
+  if (verify != null) {
+    // execute benchmarks with the minimum amount of execution (only to check 
if they are working)
+    println "≥≥ Running in verify mode"
+    args '-f', 1
+    args '-wi', 1
+    args '-i', 1
+  }
+  args '-foe', 'true'   //fail-on-error
+  args '-v', 'NORMAL'   //verbosity [SILENT, NORMAL, EXTRA]
+  if (profilers) {
+    profilers.split(',').each {
+      args '-prof', it
+    }
+  }
+
+  args '-jvmArgsPrepend', '-Xms4g'
+  args '-jvmArgsPrepend', '-Djmh.separateClassLoader=true'
+  args '-jvmArgsPrepend', '-Dlog4j2.is.webapp=false'
+  args '-jvmArgsPrepend', '-Dlog4j2.garbagefreeThreadContextMap=true'
+  args '-jvmArgsPrepend', '-Dlog4j2.enableDirectEncoders=true'
+  args '-jvmArgsPrepend', '-Dlog4j2.enable.threadlocals=true'
+//  args '-jvmArgsPrepend', '-XX:ConcGCThreads=2'
+//  args '-jvmArgsPrepend', '-XX:ParallelGCThreads=3'
+//  args '-jvmArgsPrepend', '-XX:+UseG1GC'
+  args '-jvmArgsPrepend', '-Djetty.insecurerandom=1'
+  args '-jvmArgsPrepend', '-Djava.security.egd=file:/dev/./urandom'
+  args '-jvmArgsPrepend', '-XX:-UseBiasedLocking'
+  args '-jvmArgsPrepend', '-XX:+PerfDisableSharedMem'
+  args '-jvmArgsPrepend', '-XX:+ParallelRefProcEnabled'
+//  args '-jvmArgsPrepend', '-XX:MaxGCPauseMillis=250'
+  args '-jvmArgsPrepend', '-Dsolr.log.dir='
+
+  if (jvmArgs) {
+    for (jvmArg in jvmArgs.split(' ')) {
+      args '-jvmArgsPrepend', jvmArg
+    }
+  }
+
+  args '-rf', format
+  args '-rff', resultFile
+
+  doFirst {
+    // println "\nClasspath:" + jmh.classpath.toList()
+    println "\nExecuting JMH with: $args \n"
+
+    args '-jvmArgsPrepend', '-Djava.class.path='+ toPath(getClasspath().files)
+    resultFile.parentFile.mkdirs()
+  }
+
+  doLast {
+    // jvmArgs "java.class.path", toPath(jmh.classpath)
+  }
+
+}
+
+
+private String toPath(Set<File> classpathUnderTest) {

Review comment:
       I still need to work out if this is still needed. It was needed because 
when running via gradle and using jmh's fork option, the classpath was not 
propagated. I have since simplified the integration (realizing I was jumping 
hoops because our build was putting in -proc:none for all java compile tasks) 
and I have to double check to make sure this is still necessary.

##########
File path: 
solr/core/src/java/org/apache/solr/client/solrj/embedded/JettySolrRunner.java
##########
@@ -313,22 +313,23 @@ private void init(int port) {
         if (config.onlyHttp1) {
           connector = new ServerConnector(server, new 
HttpConnectionFactory(configuration));
         } else {
-          connector = new ServerConnector(server, new 
HttpConnectionFactory(configuration),
-              new HTTP2CServerConnectionFactory(configuration));
+          connector = new ServerConnector(server, new 
HttpConnectionFactory(configuration), new 
HTTP2CServerConnectionFactory(configuration));
         }
       }
 
       connector.setReuseAddress(true);
       connector.setPort(port);
       connector.setHost("127.0.0.1");
       connector.setIdleTimeout(THREAD_POOL_MAX_IDLE_TIME_MS);
-      connector.setStopTimeout(0);
+
       server.setConnectors(new Connector[] {connector});
       server.setSessionIdManager(new DefaultSessionIdManager(server, new 
Random()));
     } else {
       HttpConfiguration configuration = new HttpConfiguration();
-      ServerConnector connector = new ServerConnector(server, new 
HttpConnectionFactory(configuration));
+      ServerConnector connector = new ServerConnector(server, new 
HttpConnectionFactory(configuration), new 
HTTP2CServerConnectionFactory(configuration));

Review comment:
       Because it currently does not work with http2, though I have spun these 
fixes into: SOLR-15547

##########
File path: solr/test-framework/src/jmh/org/apache/solr/bench/DocMakerRamGen.java
##########
@@ -0,0 +1,269 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.bench;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.commons.lang3.Validate;
+import org.apache.lucene.util.TestUtil;
+import org.apache.solr.common.SolrInputDocument;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Queue;
+import java.util.Random;
+import java.util.SplittableRandom;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class DocMakerRamGen {
+
+  private final static Map<String,Queue<SolrInputDocument>> CACHE = new 
ConcurrentHashMap<>();
+
+  private Queue<SolrInputDocument> docs = new ConcurrentLinkedQueue<>();
+
+  private final Map<String, FieldDef> fields = new HashMap<>();
+
+  private static final AtomicInteger ID = new AtomicInteger();
+  private final boolean cacheResults;
+
+  private ExecutorService executorService;
+
+  private SplittableRandom threadRandom;
+
+  public DocMakerRamGen() {
+   this(true);
+ }
+
+  public DocMakerRamGen(boolean cacheResults) {
+    this.cacheResults = cacheResults;
+
+    Long seed = Long.getLong("threadLocalRandomSeed");
+    if (seed == null) {
+      System.setProperty("threadLocalRandomSeed", Long.toString(new 
Random().nextLong()));
+    }
+
+    threadRandom = new SplittableRandom(Long.getLong("threadLocalRandomSeed"));
+  }
+
+  public void preGenerateDocs(int numDocs) throws InterruptedException {
+    executorService = 
Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() + 1);
+    if (cacheResults) {
+      docs = CACHE.compute(Integer.toString(hashCode()), (key, value) -> {
+        if (value == null) {
+          for (int i = 0; i < numDocs; i++) {

Review comment:
       This is likely a fair bit to do on cleaning up / finalizing this 
docmaker - still pulling a bit from elsewhere to it and then I'll do some 
cleanup - next update.

##########
File path: solr/test-framework/src/jmh/org/apache/solr/bench/DocMakerRamGen.java
##########
@@ -0,0 +1,269 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.bench;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.commons.lang3.Validate;
+import org.apache.lucene.util.TestUtil;
+import org.apache.solr.common.SolrInputDocument;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Queue;
+import java.util.Random;
+import java.util.SplittableRandom;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class DocMakerRamGen {
+
+  private final static Map<String,Queue<SolrInputDocument>> CACHE = new 
ConcurrentHashMap<>();
+
+  private Queue<SolrInputDocument> docs = new ConcurrentLinkedQueue<>();
+
+  private final Map<String, FieldDef> fields = new HashMap<>();
+
+  private static final AtomicInteger ID = new AtomicInteger();
+  private final boolean cacheResults;
+
+  private ExecutorService executorService;
+
+  private SplittableRandom threadRandom;
+
+  public DocMakerRamGen() {
+   this(true);
+ }
+
+  public DocMakerRamGen(boolean cacheResults) {
+    this.cacheResults = cacheResults;
+
+    Long seed = Long.getLong("threadLocalRandomSeed");
+    if (seed == null) {
+      System.setProperty("threadLocalRandomSeed", Long.toString(new 
Random().nextLong()));
+    }
+
+    threadRandom = new SplittableRandom(Long.getLong("threadLocalRandomSeed"));
+  }
+
+  public void preGenerateDocs(int numDocs) throws InterruptedException {
+    executorService = 
Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() + 1);
+    if (cacheResults) {
+      docs = CACHE.compute(Integer.toString(hashCode()), (key, value) -> {
+        if (value == null) {
+          for (int i = 0; i < numDocs; i++) {
+            executorService.submit(() -> {
+              SolrInputDocument doc = getDocument();
+              docs.add(doc);
+            });
+          }
+          return docs;
+        }
+        for (int i = value.size(); i < numDocs; i++) {
+          executorService.submit(() -> {
+            SolrInputDocument doc = getDocument();
+            value.add(doc);
+          });
+        }
+        return value;
+      });
+    } else {
+      for (int i = 0; i < numDocs; i++) {
+        executorService.submit(() -> {
+          SolrInputDocument doc = getDocument();
+          docs.add(doc);
+        });
+      }
+    }
+
+    executorService.shutdown();
+    boolean result = executorService.awaitTermination(10, TimeUnit.MINUTES);
+    if (!result) {
+      throw new RuntimeException("Timeout waiting for doc adds to finish");
+    }
+  }
+
+  public Iterator<SolrInputDocument> getGeneratedDocsIterator() {
+    return docs.iterator();
+  }
+
+  public SolrInputDocument getDocument() {
+    SolrInputDocument doc = new SolrInputDocument();
+
+    for (Map.Entry<String,FieldDef> entry : fields.entrySet()) {
+      doc.addField(entry.getKey(), getValue(entry.getValue()));
+    }
+
+    return doc;
+  }
+
+  public void addField(String name, FieldDef.FieldDefBuilder builder) {
+    fields.put(name, builder.build());
+  }
+
+  private Object getValue(FieldDef value) {
+    switch (value.getContent()) {
+      case UNIQUE_INT:
+        return ID.incrementAndGet();
+      case INTEGER:
+        if (value.getMaxCardinality() > 0) {
+          long start = value.getCardinalityStart();
+          long seed = nextLong(start, start + value.getMaxCardinality(), 
threadRandom);
+          SplittableRandom random = new SplittableRandom(seed);
+          return nextInt(0, Integer.MAX_VALUE, random);
+        }
+
+        return ThreadLocalRandom.current().nextInt(Integer.MAX_VALUE);
+      case ALPHEBETIC:
+        if (value.getNumTokens() > 1) {
+          StringBuilder sb = new StringBuilder(value.getNumTokens() * 
(Math.max(value.getLength(),value.getMaxLength()) + 1));
+          for (int i = 0; i < value.getNumTokens(); i++) {
+            if (i > 0) {
+              sb.append(' ');
+            }
+            sb.append(getAlphabeticString(value));
+          }
+          return sb.toString();
+        }
+        return getAlphabeticString(value);
+      case UNICODE:
+        if (value.getNumTokens() > 1) {
+          StringBuilder sb = new StringBuilder(value.getNumTokens() * 
(Math.max(value.getLength(),value.getMaxLength()) + 1));
+          for (int i = 0; i < value.getNumTokens(); i++) {
+            if (i > 0) {
+              sb.append(' ');
+            }
+            sb.append(getUnicodeString(value));
+          }
+          return sb.toString();
+        }
+        return getUnicodeString(value);
+      default:
+        throw new UnsupportedOperationException("Unsupported content type 
type=" + value.getContent());
+    }
+
+  }
+
+  private String getUnicodeString(FieldDef value) {
+    if (value.getMaxCardinality() > 0) {
+      long start = value.getCardinalityStart();
+      long seed = nextLong(start, start + value.getMaxCardinality(), 
threadRandom);
+      SplittableRandom random = new SplittableRandom(seed);
+      if (value.getLength() > -1) {
+        return TestUtil.randomRealisticUnicodeString(new Random(seed), 
value.getLength(), value.getLength());
+      } else {
+        return TestUtil.randomRealisticUnicodeString(new Random(seed), 1, 
value.getMaxLength());
+      }
+    }
+
+    if (value.getLength() > -1) {
+      return 
TestUtil.randomRealisticUnicodeString(ThreadLocalRandom.current(), 
value.getLength(), value.getLength());
+    } else {
+      return 
TestUtil.randomRealisticUnicodeString(ThreadLocalRandom.current(), 1, 
value.getMaxLength());
+    }
+  }
+
+  private String getAlphabeticString(FieldDef value) {
+    if (value.getMaxCardinality() > 0) {
+      long start = value.getCardinalityStart();
+      long seed = nextLong(start, start + value.getMaxCardinality(), 
threadRandom);
+      SplittableRandom random = new SplittableRandom(seed);
+      if (value.getLength() > -1) {
+        return RandomStringUtils.random(nextInt(value.getLength(), 
value.getLength(), random), 0, 0, true, false, null, new Random(seed));
+      } else {
+        return RandomStringUtils.random(nextInt(1, value.getMaxLength(), 
random), 0, 0, true, false, null, new Random(seed));
+      }
+    }
+
+    SplittableRandom threadRandom = new 
SplittableRandom(Long.getLong("threadLocalRandomSeed", 
ThreadLocalRandom.current().nextLong()));
+    if (value.getLength() > -1) {
+      return RandomStringUtils.random(nextInt(value.getLength(), 
value.getLength(), threadRandom), 0, 0, true, false, null, 
ThreadLocalRandom.current());
+    } else {
+      return RandomStringUtils.random(nextInt(1, value.getMaxLength(), 
threadRandom), 0, 0, true, false, null, ThreadLocalRandom.current());
+    }
+  }
+
+  public enum Content {
+    UNICODE, ALPHEBETIC, INTEGER, UNIQUE_INT
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+    DocMakerRamGen that = (DocMakerRamGen) o;
+    return fields.equals(that.fields);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(fields);
+  }
+
+  public static int nextInt(final int startInclusive, final int endExclusive, 
SplittableRandom random) {
+    Validate.isTrue(endExclusive >= startInclusive,
+        "Start value must be smaller or equal to end value.");
+    Validate.isTrue(startInclusive >= 0, "Both range values must be 
non-negative.");
+
+    if (startInclusive == endExclusive) {
+      return startInclusive;
+    }
+
+    return startInclusive + random.nextInt(endExclusive - startInclusive);
+  }
+
+  public static long nextLong(final long startInclusive, final long 
endExclusive, SplittableRandom random) {
+    Validate.isTrue(endExclusive >= startInclusive,
+        "Start value must be smaller or equal to end value.");
+    Validate.isTrue(startInclusive >= 0, "Both range values must be 
non-negative.");
+
+    if (startInclusive == endExclusive) {
+      return startInclusive;
+    }
+
+    return startInclusive + random.nextLong(endExclusive - startInclusive);
+  }
+
+  public static void main(String[] args) {

Review comment:
       Still draft form. This should end up as a unit test for the jmh stuff, 
but have not set that ability up in gradle quite yet.

##########
File path: solr/test-framework/src/jmh/org/apache/solr/bench/FieldDef.java
##########
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.bench;
+
+import java.util.Objects;
+import java.util.concurrent.ThreadLocalRandom;
+
+public class FieldDef {

Review comment:
       Everything still needs javadocs and package level overview file. Don't 
want to keep updating them though, so will come when I feel the rest won't get 
change pushback.

##########
File path: solr/test-framework/src/jmh/org/apache/solr/bench/FieldDef.java
##########
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.bench;
+
+import java.util.Objects;
+import java.util.concurrent.ThreadLocalRandom;
+
+public class FieldDef {
+  private DocMakerRamGen.Content content;

Review comment:
       It probably should be. Was not sure I might do something a little more 
solid than hashing for preventing regen per iteration on a run.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscr...@solr.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscr...@solr.apache.org
For additional commands, e-mail: issues-h...@solr.apache.org

Reply via email to