test_class.file: outland-feature-java/src/test/java/outland/feature/OptionSelectorWeightedTest.java
test_class.identifier: OptionSelectorWeightedTest
test_case.body: @Test
    public void testFairStrings() {
  
      /*
      maxweight is 10_000; thus in a 10K iteration we'd expect the option with weight "4000" to be
      selected about 40% of the time.
       */
      final ArrayList<FeatureOption> itemList = Lists.newArrayList(
          FeatureOption.newBuilder().setKey("10%").setWeight(1_000).build(),
          FeatureOption.newBuilder().setKey("20%").setWeight(2_000).build(),
          FeatureOption.newBuilder().setKey("30%").setWeight(3_000).build(),
          FeatureOption.newBuilder().setKey("40%").setWeight(4_000).build()
      );
  
      final OptionSelectorWeighted or = new OptionSelectorWeighted(itemList);
      final int[] resultFrequencies = new int[4];
      final int nearestRoundTo = 1_000;
  
      /*
       iterate as many times as the max weight; this means a 10% weight should be be hit about
       1000 times, which makes some of the arithmetic below easier
        */
      final int runs = 10_000;
      IntStream.range(0, runs).forEach(i -> {
        /*
         maps our 4 possible results (1000 to 4000) into array slots 0 to 3
          */
        final int fitIntoArray = (or.select().getWeight() / nearestRoundTo) - 1;
        resultFrequencies[fitIntoArray]++;
      });
  
      final Set<Integer> nearestFrequencies = Sets.newHashSet();
      final int nearestRoundUp = nearestRoundTo / 2; // avoid rounding down to 0 for a number < 1000
      for (int resultFrequency : resultFrequencies) {
        /*
        take the actual frequency and map it to the closest thousandth
         */
        final int nearestFrequency =
            (int) (nearestRoundTo * Math.floor((resultFrequency + nearestRoundUp) / nearestRoundTo));
  
        nearestFrequencies.add(nearestFrequency);
      }
  
      /*
      check we have our four expected frequencies
       */
      assertTrue(nearestFrequencies.contains(1_000));
      assertTrue(nearestFrequencies.contains(2_000));
      assertTrue(nearestFrequencies.contains(3_000));
      assertTrue(nearestFrequencies.contains(4_000));
    }
test_case.class_method_signature: OptionSelectorWeightedTest.testFairStrings()
test_case.full_signature: @Test public void testFairStrings()
test_case.identifier: testFairStrings
test_case.invocations: newArrayList build setWeight setKey newBuilder build setWeight setKey newBuilder build setWeight setKey newBuilder build setWeight setKey newBuilder forEach range getWeight select newHashSet floor add assertTrue contains assertTrue contains assertTrue contains assertTrue contains
test_case.modifiers: @Test public
test_case.parameters: ()
test_case.return: void
test_case.signature: void testFairStrings()
focal_class.declarator: wheel
focal_class.modifier: private final
focal_class.original_string: private final double[] wheel;
focal_class.type: double[]
focal_class.var_name: wheel
focal_class.declarator: values
focal_class.modifier: private final
focal_class.original_string: private final FeatureOption[] values;
focal_class.type: FeatureOption[]
focal_class.var_name: values
focal_class.file: outland-feature-java/src/main/java/outland/feature/OptionSelectorWeighted.java
focal_class.identifier: OptionSelectorWeighted
focal_class.class_method_signature: OptionSelectorWeighted.OptionSelectorWeighted(List<FeatureOption> options)
focal_class.full_signature:   OptionSelectorWeighted(List<FeatureOption> options)
focal_class.identifier: OptionSelectorWeighted
focal_class.parameters: (List<FeatureOption> options)
focal_class.signature:  OptionSelectorWeighted(List<FeatureOption> options)
focal_class.class_method_signature: OptionSelectorWeighted.select()
focal_class.full_signature:  FeatureOption select()
focal_class.identifier: select
focal_class.parameters: ()
focal_class.return: FeatureOption
focal_class.signature: FeatureOption select()
focal_class.class_method_signature: OptionSelectorWeighted.buildValues(List<FeatureOption> options)
focal_class.full_signature: private FeatureOption[] buildValues(List<FeatureOption> options)
focal_class.identifier: buildValues
focal_class.modifiers: private
focal_class.parameters: (List<FeatureOption> options)
focal_class.return: FeatureOption[]
focal_class.signature: FeatureOption[] buildValues(List<FeatureOption> options)
focal_class.class_method_signature: OptionSelectorWeighted.buildWheel(List<FeatureOption> options)
focal_class.full_signature: private double[] buildWheel(List<FeatureOption> options)
focal_class.identifier: buildWheel
focal_class.modifiers: private
focal_class.parameters: (List<FeatureOption> options)
focal_class.return: double[]
focal_class.signature: double[] buildWheel(List<FeatureOption> options)
focal_class.class_method_signature: OptionSelectorWeighted.normalize(int weight)
focal_class.full_signature: private double normalize(int weight)
focal_class.identifier: normalize
focal_class.modifiers: private
focal_class.parameters: (int weight)
focal_class.return: double
focal_class.signature: double normalize(int weight)
focal_method.body: FeatureOption select() {
      final double randomValue = Math.random();
      int idx = Arrays.binarySearch(wheel, randomValue);
      if (idx < 0) {
        idx = -idx - 1;
      }
      return values[idx];
    }
focal_method.class_method_signature: OptionSelectorWeighted.select()
focal_method.full_signature:  FeatureOption select()
focal_method.identifier: select
focal_method.invocations: random binarySearch
focal_method.parameters: ()
focal_method.return: FeatureOption
focal_method.signature: FeatureOption select()