/* * 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.ignite.testframework.configvariations; import java.util.Arrays; import java.util.Iterator; /** * Variations iterator. */ public class VariationsIterator implements Iterator<int[]> { /** */ private final Object[][] params; /** */ private final int[] vector; /** */ private int position; /** */ private final int expCntOfVectors; /** */ private int cntOfVectors; /** * @param params Paramethers. */ public VariationsIterator(Object[][] params) { assert params != null; assert params.length > 0; for (int i = 0; i < params.length; i++) { assert params[i] != null : i; assert params[i].length > 0 : i; } this.params = params; vector = new int[params.length]; for (int i = 0; i < vector.length; i++) vector[i] = 0; position = -1; int cntOfVectors0 = 1; for (int i = 0; i < params.length; i++) cntOfVectors0 *= params[i].length; expCntOfVectors = cntOfVectors0; cntOfVectors = 0; } /** {@inheritDoc} */ @Override public boolean hasNext() { return cntOfVectors < expCntOfVectors; } /** {@inheritDoc} */ @Override public int[] next() { // Only first call. if (position == -1) { position = 0; cntOfVectors++; return arraycopy(vector); } if (!updateVector(vector, position)) { if (position + 1 == params.length) throw new IllegalStateException("[position=" + position + ", vector=" + Arrays.toString(vector) + ", params=" + Arrays.deepToString(params)); position++; // Skip params with length 1. We cannot set 1 at this position. while (position < params.length && params[position].length < 2) position++; if (position == params.length) throw new IllegalStateException("[position=" + position + ", vector=" + Arrays.toString(vector) + ", params=" + Arrays.deepToString(params)); vector[position] = 1; cntOfVectors++; return arraycopy(vector); } cntOfVectors++; return arraycopy(vector); } /** * Updates vector starting from position. * * @param vector Vector. * @param position Position. * @return {@code True} if vector has been updated. When {@code false} is returned it means that all positions * before has been set to {@code 0}. */ private boolean updateVector(int[] vector, int position) { if (position == 0) { int val = vector[0]; if (val + 1 < params[0].length) { vector[0] = val + 1; return true; } else { vector[0] = 0; return false; } } if (updateVector(vector, position - 1)) return true; int val = vector[position]; if (val + 1 < params[position].length) { vector[position] = val + 1; return true; } else { vector[position] = 0; return false; } } /** * @param arr Array. * @return Array copy. */ private static int[] arraycopy(int[] arr) { int[] dest = new int[arr.length]; System.arraycopy(arr, 0, dest, 0, arr.length); return dest; } /** {@inheritDoc} */ @Override public void remove() { throw new UnsupportedOperationException(); } }