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



##########
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) {

Review comment:
       I think it would be clearer to declare a variable here named docSink of 
type Queue<SolrInputDocument> initialized to either the docs field or the value 
field (if value isn't null).  Then you wouldn't be repeating the loop logic so 
many times.

##########
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:
       Why this change?  Decoupling this random from tests.random seed seems 
bad to me.

##########
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:
       Class level javadoc please

##########
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 {

Review comment:
       Always one javadoc comment for a class, please

##########
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:
       I'd prefer to see each of these two settings below with their own system 
property based choise.  This would be more consistent with all the many things 
that are already configurable via a system property.

##########
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:
       It's not clear to me why you are changing this file

##########
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<>();

Review comment:
       Minor: please use 'final' more consistently for the fields, and organize 
all statics together up top.

##########
File path: solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
##########
@@ -548,10 +548,10 @@ public static void resetFactory() throws Exception {
     }
   }
 
-  private static SSLTestConfig buildSSLConfig() {
+  public static SSLTestConfig buildSSLConfig() {
 
     SSLRandomizer sslRandomizer =
-      
SSLRandomizer.getSSLRandomizerForClass(RandomizedContext.current().getTargetClass());
+      SSLRandomizer.getSSLRandomizerForClass(SolrTestCaseJ4.class);

Review comment:
       It's not clear what point there is in changing this.  Before or after 
seem fine.

##########
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:
       this field isn't part of class identity (not in equals/hashCode); maybe 
comment here to state this

##########
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 loop exists twice in this method; it's worth refactoring out IMO

##########
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:
       This method should perhaps not be kept?

##########
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);

Review comment:
       move to constructor?

##########
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:
       This method could be nicer via Java stream and Collectors.joining, or 
perhaps some Groovy equivalent




-- 
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