StarTreeJobUtils { public static int[] findBestMatch(DimensionKey dimensionKey, List<String> dimensionNames, List<int[]> dimensionCombinations, Map<String, Map<String, Integer>> forwardIndex) { int[] target = new int[dimensionKey.getDimensionValues().length]; for (int i = 0; i < dimensionNames.size(); i++) { String dimensionName = dimensionNames.get(i); String dimensionValue = dimensionKey.getDimensionValues()[i]; Integer intValue = forwardIndex.get(dimensionName).get(dimensionValue); if (intValue == null) { intValue = -1; } target[i] = intValue; } int[] closestCombination = null; Integer closestScore = null; for (int[] combination : dimensionCombinations) { int score = 0; for (int i = 0; i < target.length; i++) { if (target[i] != combination[i]) { if (combination[i] == StarTreeConstants.OTHER_VALUE) { score += 1; } else if (combination[i] == StarTreeConstants.STAR_VALUE) { score += 0; } else if(target[i] == StarTreeConstants.STAR_VALUE) { score += 0; } else { score = -1; break; } } } if (score >= 0 && (closestScore == null || score < closestScore)) { closestScore = score; closestCombination = combination; } } if (closestCombination == null) { StringBuilder sb = new StringBuilder(); for(int[] combination:dimensionCombinations){ sb.append(Arrays.toString(combination)); sb.append("\n"); } throw new IllegalArgumentException("Could not find matching combination for " + dimensionKey + " in \n" + sb.toString() +"\n"+ " forwardIndex:"+ forwardIndex); } return closestCombination; }  static String getTreeId(FileSystem fileSystem, Path treePath); static int pushConfig(InputStream configData, String thirdEyeUri, String collection); static int pushTree(InputStream treeData,
                             String thirdEyeUri,
                             String collection,
                             String treeId,
                             DateTime minTime,
                             DateTime maxTime,
                             String schedule); static int pushData(InputStream leafData,
                             String thirdEyeUri,
                             String collection,
                             DateTime minTime,
                             DateTime maxTime,
                             String schedule); static void collectRecords(StarTreeConfig config, StarTreeNode node, StarTreeRecord record, Map<UUID, StarTreeRecord> collector); static int[] findBestMatch(DimensionKey dimensionKey,
                                    List<String> dimensionNames,
                                    List<int[]> dimensionCombinations,
                                    Map<String, Map<String, Integer>> forwardIndex);  }
@Test public void testFindBestMatch() throws Exception { List<String> dimensions = Arrays.asList("A", "B", "C"); Map<String, Map<String, Integer>> forwardIndex = new HashMap<String, Map<String, Integer>>(); for (String dimension : dimensions) { forwardIndex.put(dimension, new HashMap<String, Integer>()); forwardIndex.get(dimension).put(StarTreeConstants.STAR, StarTreeConstants.STAR_VALUE); forwardIndex.get(dimension).put(StarTreeConstants.OTHER, StarTreeConstants.OTHER_VALUE); forwardIndex.get(dimension).put(dimension + "X", StarTreeConstants.FIRST_VALUE); for (int i = 0; i < 3; i++) { forwardIndex.get(dimension).put(dimension + i, StarTreeConstants.FIRST_VALUE + 1 + i); } } List<int[]> combinations = new ArrayList<int[]>(); combinations.add(getCombination(forwardIndex, dimensions, Arrays.asList("A0", "B0", "C0"))); combinations.add(getCombination(forwardIndex, dimensions, Arrays.asList("A1", "B1", "C1"))); combinations.add(getCombination(forwardIndex, dimensions, Arrays.asList("A0", "B2", "C0"))); combinations.add(getCombination(forwardIndex, dimensions, Arrays.asList("?", "B0", "?"))); combinations.add(getCombination(forwardIndex, dimensions, Arrays.asList("?", "B2", "C0"))); combinations.add(getCombination(forwardIndex, dimensions, Arrays.asList("?", "?", "?"))); int[] allOther = new int[] { StarTreeConstants.OTHER_VALUE, StarTreeConstants.OTHER_VALUE, StarTreeConstants.OTHER_VALUE }; int[] oneOther = new int[] { StarTreeConstants.OTHER_VALUE, forwardIndex.get("B").get("B2"), forwardIndex.get("C").get("C0") }; int[] twoOther = new int[] { StarTreeConstants.OTHER_VALUE, forwardIndex.get("B").get("B0"), StarTreeConstants.OTHER_VALUE }; int[] res = StarTreeJobUtils.findBestMatch( new DimensionKey(new String[] { "AX", "BX", "CX" }), dimensions, combinations, forwardIndex); Assert.assertEquals(res, allOther); res = StarTreeJobUtils.findBestMatch( new DimensionKey(new String[] { "AX", "B2", "C0" }), dimensions, combinations, forwardIndex); Assert.assertEquals(res, oneOther); res = StarTreeJobUtils.findBestMatch( new DimensionKey(new String[] { "AX", "B0", "C1" }), dimensions, combinations, forwardIndex); Assert.assertEquals(res, twoOther); }