LinkedListStarTreeTable implements StarTreeTable { @Override public Iterator<StarTreeTableRow> getUniqueCombinations(final List<Integer> excludedDimensions) { final List<Integer> includedDimensions = new ArrayList<>(); for (int i = 0; i < dimensionTypes.size(); i++) { if (excludedDimensions == null || !excludedDimensions.contains(i)) { includedDimensions.add(i); } } final Comparator<StarTreeTableRow> includedComparator = new Comparator<StarTreeTableRow>() { @Override public int compare(StarTreeTableRow o1, StarTreeTableRow o2) { for (Integer dimension : includedDimensions) { Integer v1 = o1.getDimensions().get(dimension); Integer v2 = o2.getDimensions().get(dimension); if (!v1.equals(v2)) { return v1 - v2; } } return 0; } }; final List<ByteBuffer> listCopy = new LinkedList<>(list); Collections.sort(listCopy, new Comparator<ByteBuffer>() { @Override public int compare(ByteBuffer o1, ByteBuffer o2) { for (Integer dimension : includedDimensions) { o1.position(dimension * Integer.SIZE / 8); o2.position(dimension * Integer.SIZE / 8); Integer v1 = o1.getInt(); Integer v2 = o2.getInt(); if (!v1.equals(v2)) { return v1 - v2; } } return 0; } }); final Iterator<ByteBuffer> itr = listCopy.iterator(); return new Iterator<StarTreeTableRow>() { private StarTreeTableRow nextToReturn = new StarTreeTableRow(dimensionTypes.size(), metricTypes.size()); private StarTreeTableRow nextFromItr = new StarTreeTableRow(dimensionTypes.size(), metricTypes.size()); private boolean shouldReset = true; private boolean hasReturnedCurrent = true; private boolean hasStarted = false; private int numReturned = 0; @Override public boolean hasNext() { if (itr.hasNext() && hasReturnedCurrent) { if (shouldReset) { if (!hasStarted) { ByteBuffer buffer = itr.next(); fromByteBuffer(buffer, nextFromItr); hasStarted = true; } copyStarTreeTableRow(nextFromItr, nextToReturn, excludedDimensions); shouldReset = false; } while (itr.hasNext()) { ByteBuffer buffer = itr.next(); fromByteBuffer(buffer, nextFromItr); if (includedComparator.compare(nextFromItr, nextToReturn) == 0) { aggregateStarTreeTableRow(nextFromItr, nextToReturn); } else { shouldReset = true; break; } } hasReturnedCurrent = false; } if (!itr.hasNext() && hasReturnedCurrent && shouldReset) { copyStarTreeTableRow(nextFromItr, nextToReturn, excludedDimensions); shouldReset = false; hasReturnedCurrent = false; } return itr.hasNext() || !hasReturnedCurrent; } @Override public StarTreeTableRow next() { if (!hasNext()) { throw new NoSuchElementException(); } hasReturnedCurrent = true; numReturned++; return nextToReturn; } @Override public void remove() { throw new UnsupportedOperationException(); } }; } LinkedListStarTreeTable(List<FieldSpec.DataType> dimensionTypes, List<FieldSpec.DataType> metricTypes); private  LinkedListStarTreeTable(List<ByteBuffer> list,
                                  List<FieldSpec.DataType> dimensionTypes,
                                  List<FieldSpec.DataType> metricTypes); @Override void append(StarTreeTableRow row); @Override int size(); @Override Iterator<StarTreeTableRow> getUniqueCombinations(final List<Integer> excludedDimensions); @Override Iterator<StarTreeTableRow> getAllCombinations(); @Override void sort(final List<Integer> sortDimensions); @Override StarTreeTableGroupByStats groupBy(Integer dimension); @Override StarTreeTable view(Integer startDocumentId, Integer documentCount); @Override void printTable(PrintStream printStream); @Override void close();  }
@Test(dataProvider = "uniqueCombinationExcludesDataProvider") public void testGetUniqueCombinations(StarTreeTable table, List<Integer> excludedDimensions) { Set<List<Integer>> uniqueCombinations = new HashSet<List<Integer>>(); for (List<Integer> combination : generateCombinations()) { table.append(new StarTreeTableRow(combination, metrics)); List<Integer> withExclusions = new ArrayList<Integer>(combination); for (int i = 0; i < withExclusions.size(); i++) { if (excludedDimensions != null && excludedDimensions.contains(i)) { withExclusions.set(i, StarTreeIndexNode.all()); } } uniqueCombinations.add(withExclusions); } Iterator<StarTreeTableRow> itr = table.getUniqueCombinations(excludedDimensions); int actualCombinations = 0; while (itr.hasNext()) { StarTreeTableRow next = itr.next(); actualCombinations++; } Assert.assertEquals(actualCombinations, uniqueCombinations.size()); }