View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.rng.examples.stress;
18  
19  import org.apache.commons.rng.core.source32.RandomIntSource;
20  import org.apache.commons.rng.core.source64.RandomLongSource;
21  import org.apache.commons.rng.simple.RandomSource;
22  import org.apache.commons.rng.simple.internal.ProviderBuilder.RandomSourceInternal;
23  
24  import java.util.ArrayList;
25  import java.util.EnumMap;
26  import java.util.Iterator;
27  import java.util.List;
28  
29  /**
30   * Default list of generators defined by the {@link RandomSource}. Any source that
31   * requires arguments will have a default set of arguments.
32   */
33  class StressTestDataList implements Iterable<StressTestData> {
34      /**
35       * The example arguments for RandomSource values that require them.
36       */
37      private static final EnumMap<RandomSource, Object[]> EXAMPLE_ARGUMENTS =
38              new EnumMap<>(RandomSource.class);
39  
40      static {
41          // Currently we cannot detect if the source requires arguments,
42          // e.g. RandomSource.TWO_CMRES_SELECT. So example arguments must
43          // be manually added here.
44          EXAMPLE_ARGUMENTS.put(RandomSource.TWO_CMRES_SELECT, new Object[] {1, 2});
45      }
46  
47      /** List of generators. */
48      private final List<StressTestData> list = new ArrayList<>();
49  
50      /**
51       * Creates an empty list.
52       */
53      private StressTestDataList() {
54          // Do nothing
55      }
56  
57      /**
58       * Creates the list. The number of trials will be set if the source does not require arguments.
59       *
60       * @param idPrefix The id prefix prepended to each ID.
61       * @param numberOfTrials The number of trials (ignored if {@code <= 0}).
62       */
63      StressTestDataList(String idPrefix,
64                         int numberOfTrials) {
65          // Auto-generate using the order of the RandomSource enum
66          for (final RandomSource source : RandomSource.values()) {
67              final Object[] args = EXAMPLE_ARGUMENTS.get(source);
68              StressTestData data = new StressTestData(source, args).withIDPrefix(idPrefix);
69              if (args == null && numberOfTrials > 0) {
70                  data = data.withTrials(numberOfTrials);
71              }
72              list.add(data);
73          }
74      }
75  
76      /** {@inheritDoc} */
77      @Override
78      public Iterator<StressTestData> iterator() {
79          return list.iterator();
80      }
81  
82      /**
83       * Create a subset of the list containing only instances of {@link RandomIntSource}.
84       *
85       * @return the stress test data list
86       */
87      public StressTestDataList subsetIntSource() {
88          return subsetOf(RandomIntSource.class);
89      }
90  
91      /**
92       * Create a subset of the list containing only instances of {@link RandomLongSource}.
93       *
94       * @return the stress test data list
95       */
96      public StressTestDataList subsetLongSource() {
97          return subsetOf(RandomLongSource.class);
98      }
99  
100     /**
101      * Create a subset of the list containing only instances of the specified type.
102      *
103      * @param type The instance type.
104      * @return the stress test data list
105      */
106     private StressTestDataList subsetOf(Class<?> type) {
107         final StressTestDataList subset = new StressTestDataList();
108         for (final StressTestData data : list) {
109             // This makes a big assumption that the two enums have the same name
110             RandomSourceInternal source;
111             try {
112                 source = RandomSourceInternal.valueOf(data.getRandomSource().name());
113             } catch (IllegalArgumentException ex) {
114                 throw new ApplicationException("Unknown internal source: " + data.getRandomSource(), ex);
115             }
116             if (type.isAssignableFrom(source.getRng())) {
117                 subset.list.add(data);
118             }
119         }
120         return subset;
121     }
122 
123     /**
124      * Create a subset of the list containing only instances of RandomSource within the
125      * specified range of the enum. The first value in the enum corresponds to entry 1.
126      *
127      * @param min Minimum entry (inclusive)
128      * @param max Maximum entry (inclusive)
129      * @return the stress test data list
130      */
131     public StressTestDataList subsetRandomSource(int min, int max) {
132         final StressTestDataList subset = new StressTestDataList();
133         for (final StressTestData data : list) {
134             final int entry = data.getRandomSource().ordinal() + 1;
135             if (min <= entry && entry <= max) {
136                 subset.list.add(data);
137             }
138         }
139         return subset;
140     }
141 }