/*
* Redberry: symbolic tensor computations.
*
* Copyright (c) 2010-2015:
* Stanislav Poslavsky
* Bolotin Dmitriy
*
* This file is part of Redberry.
*
* Redberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Redberry is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Redberry. If not, see .
*/
package cc.redberry.core.indexgenerator;
import cc.redberry.core.indices.IndexType;
import gnu.trove.map.hash.TByteObjectHashMap;
import java.util.Arrays;
import static cc.redberry.core.indices.IndicesUtils.*;
/**
* Returns distinct indices only from the allowed set of indices and produces exception if no more allowed indices exist.
*
* @author Dmitry Bolotin
* @author Stanislav Poslavsky
*/
public final class IndexGeneratorFromData implements IndexGenerator {
private final TByteObjectHashMap generators = new TByteObjectHashMap<>();
public IndexGeneratorFromData(int[] allowedIndices) {
if (allowedIndices.length > 0) {
Arrays.sort(allowedIndices);
byte type = getType(allowedIndices[0]);
allowedIndices[0] = getNameWithoutType(allowedIndices[0]);
int prevIndex = 0;
for (int i = 1; i < allowedIndices.length; ++i) {
if (getType(allowedIndices[i]) != type) {
generators.put(type, new IntProvider(Arrays.copyOfRange(allowedIndices, prevIndex, i)));
prevIndex = i;
type = getType(allowedIndices[i]);
}
allowedIndices[i] = getNameWithoutType(allowedIndices[i]);
}
generators.put(type, new IntProvider(Arrays.copyOfRange(allowedIndices, prevIndex, allowedIndices.length)));
}
}
/**
* {@inheritDoc}
*
* @throws IndexOutOfBoundsException if no more allowed indices exist
*/
@Override
public int generate(byte type) {
IntProvider ig = generators.get(type);
if (ig == null)
throw new IndexOutOfBoundsException("No allowed indices with specified type: " + IndexType.getType(type));
return setType(type, ig.getNext());
}
private static final class IntProvider {
final int[] data;
int pointer;
private IntProvider(int[] data) {
this.data = data;
this.pointer = 0;
}
int getNext() {
return data[pointer++];
}
}
}
Ads help maintain this website.