/*
* 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 cc.redberry.core.indices.Indices;
import gnu.trove.map.hash.TByteObjectHashMap;
import gnu.trove.procedure.TByteObjectProcedure;
import java.util.Arrays;
import static cc.redberry.core.indices.IndicesUtils.*;
/**
* Generates distinct indices of particular types, which does not contain in
* specified sets of indices (engaged data).
*
* @author Dmitry Bolotin
* @author Stanislav Poslavsky
* @since 1.0
*/
public final class IndexGeneratorImpl implements IndexGenerator {
protected TByteObjectHashMap generators = new TByteObjectHashMap<>();
/**
* Creates with generator without engaged data.
*/
public IndexGeneratorImpl() {
}
/**
* Creates with generator with specified engaged data.
*
* @param indices forbidden indices
*/
public IndexGeneratorImpl(Indices indices) {
this(indices.getAllIndices().copy());
}
protected IndexGeneratorImpl(TByteObjectHashMap generators) {
this.generators = generators;
}
/**
* Creates with generator with specified engaged data.
*
* @param indices forbidden indices
*/
public IndexGeneratorImpl(final int[] indices) {
if (indices.length == 0)
return;
for (int i = 0; i < indices.length; ++i)
indices[i] = getNameWithType(indices[i]);
Arrays.sort(indices);
byte type = getType(indices[0]);
indices[0] = getNameWithoutType(indices[0]);
int prevIndex = 0;
for (int i = 1; i < indices.length; ++i) {
if (getType(indices[i]) != type) {
generators.put(type, new IntGenerator(Arrays.copyOfRange(indices, prevIndex, i)));
prevIndex = i;
type = getType(indices[i]);
}
indices[i] = getNameWithoutType(indices[i]);
}
generators.put(type, new IntGenerator(Arrays.copyOfRange(indices, prevIndex, indices.length)));
}
/**
* Returns true if index contains in engaged data or already was generated.
*
* @param index index
* @return true if index contains in engaged data or already was generated
*/
public boolean contains(int index) {
byte type = getType(index);
IntGenerator intGen;
if ((intGen = generators.get(type)) == null)
return false;
return intGen.contains(getNameWithoutType(index));
}
/**
* Merges from specified generator.
*
* @param other index generator
*/
public void mergeFrom(IndexGeneratorImpl other) {
other.generators.forEachEntry(
new TByteObjectProcedure() {
@Override
public boolean execute(byte a, IntGenerator b) {
IntGenerator thisGenerator = generators.get(a);
if (thisGenerator == null)
generators.put(a, b.clone());
else
thisGenerator.mergeFrom(b);
return true;
}
}
);
/*for (Map.Entry entry : other.generators.entrySet()) {
IntGenerator thisGenerator = generators.get(entry.getKey());
if (thisGenerator == null)
generators.put(entry.getKey(), entry.getValue().clone());
else
thisGenerator.mergeFrom(entry.getValue());
}*/
}
/*public void add(int index) {
byte type = getType(index);
IntGenerator intGen;
if ((intGen = generators.get(type)) == null) {
generators.put(type, new IntGenerator(new int[]{getNameWithoutType(index)}));
return;
}
intGen.add(getNameWithoutType(index));
}*/
/**
* Generates new index of a particular type.
*
* @param type index type
* @return new index of a particular type
*/
public int generate(IndexType type) {
return generate(type.getType());
}
/**
* Generates new index of a particular type.
*
* @param type index type
* @return new index of a particular type
*/
@Override
public int generate(byte type) {
IntGenerator ig = generators.get(type);
if (ig == null)
generators.put(type, ig = new IntGenerator());
return setType(type, ig.getNext());
}
@Override
public IndexGeneratorImpl clone() {
final TByteObjectHashMap newMap = new TByteObjectHashMap<>(generators.size());
generators.forEachEntry(
new TByteObjectProcedure() {
@Override
public boolean execute(byte a, IntGenerator b) {
newMap.put(a, b.clone());
return true;
}
}
);
/*for (Map.Entry entry : generators.entrySet())
newMap.put(entry.getKey(), entry.getValue().clone()); */
return new IndexGeneratorImpl(newMap);
}
}
Ads help maintain this website.