/* * ARX: Powerful Data Anonymization * Copyright 2012 - 2017 Fabian Prasser, Florian Kohlmayer and contributors * * Licensed 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.deidentifier.arx.framework.check; import org.deidentifier.arx.ARXConfiguration.ARXConfigurationInternal; import org.deidentifier.arx.framework.check.StateMachine.TransitionType; import org.deidentifier.arx.framework.check.distribution.IntArrayDictionary; import org.deidentifier.arx.framework.check.groupify.HashGroupifyEntry; import org.deidentifier.arx.framework.check.groupify.HashGroupify; import org.deidentifier.arx.framework.check.transformer.AbstractTransformer; import org.deidentifier.arx.framework.check.transformer.Transformer01; import org.deidentifier.arx.framework.check.transformer.Transformer02; import org.deidentifier.arx.framework.check.transformer.Transformer03; import org.deidentifier.arx.framework.check.transformer.Transformer04; import org.deidentifier.arx.framework.check.transformer.Transformer05; import org.deidentifier.arx.framework.check.transformer.Transformer06; import org.deidentifier.arx.framework.check.transformer.Transformer07; import org.deidentifier.arx.framework.check.transformer.Transformer08; import org.deidentifier.arx.framework.check.transformer.Transformer09; import org.deidentifier.arx.framework.check.transformer.Transformer10; import org.deidentifier.arx.framework.check.transformer.Transformer11; import org.deidentifier.arx.framework.check.transformer.Transformer12; import org.deidentifier.arx.framework.check.transformer.Transformer13; import org.deidentifier.arx.framework.check.transformer.Transformer14; import org.deidentifier.arx.framework.check.transformer.Transformer15; import org.deidentifier.arx.framework.check.transformer.TransformerAll; import org.deidentifier.arx.framework.data.GeneralizationHierarchy; /** * The class Transformer. * * @author Fabian Prasser * @author Florian Kohlmayer */ public class Transformer { /** The config. */ protected final ARXConfigurationInternal config; /** The dictionary for the snapshot compression *. */ protected IntArrayDictionary dictionarySensFreq; /** The dictionary for the snapshot compression *. */ protected IntArrayDictionary dictionarySensValue; /** The dimensions. */ protected final int dimensions; /** The hierarchies. */ protected final GeneralizationHierarchy[] hierarchies; /** Other attribute values. */ protected int[][] inputAnalyzed; /** The data. */ protected final int[][] inputGeneralized; /** The instances. */ protected final AbstractTransformer[] instances; /** The buffer. */ protected int[][] outputGeneralized; /** * Instantiates a new transformer. * * @param inputGeneralized * @param inputAnalyzed * @param hierarchies * @param config * @param dictionarySensValue * @param dictionarySensFreq */ public Transformer(final int[][] inputGeneralized, final int[][] inputAnalyzed, final GeneralizationHierarchy[] hierarchies, final ARXConfigurationInternal config, final IntArrayDictionary dictionarySensValue, final IntArrayDictionary dictionarySensFreq) { this.config = config; this.inputGeneralized = inputGeneralized; this.hierarchies = hierarchies; this.instances = new AbstractTransformer[16]; this.outputGeneralized = new int[inputGeneralized.length][]; for (int i = 0; i < inputGeneralized.length; i++) { outputGeneralized[i] = new int[inputGeneralized[0].length]; } this.dimensions = inputGeneralized[0].length; this.dictionarySensValue = dictionarySensValue; this.dictionarySensFreq = dictionarySensFreq; this.inputAnalyzed = inputAnalyzed; buildApplicators(); } /** * Apply. * * @param projection * the projection * @param transformation * the transformation * @param target * the target * @return the hash groupify */ public HashGroupify apply(final long projection, final int[] transformation, final HashGroupify target) { return applyInternal(projection, transformation, null, target, null, TransitionType.UNOPTIMIZED); } /** * Apply rollup. * * @param projection * the projection * @param state * the state * @param source * the source * @param target * the target * @return the hash groupify */ public HashGroupify applyRollup(final long projection, final int[] state, final HashGroupify source, final HashGroupify target) { return applyInternal(projection, state, source, target, null, TransitionType.ROLLUP); } /** * Apply snapshot. * * @param projection * the projection * @param state * the state * @param target * the target * @param snapshot * the snapshot * @return the hash groupify */ public HashGroupify applySnapshot(final long projection, final int[] state, final HashGroupify target, final int[] snapshot) { return applyInternal(projection, state, null, target, snapshot, TransitionType.SNAPSHOT); } /** * Gets the buffer. * * @return the buffer */ public int[][] getBuffer() { return outputGeneralized; } /** * Builds the applicators. */ private void buildApplicators() { instances[15] = new Transformer15(inputGeneralized, hierarchies, inputAnalyzed, dictionarySensValue, dictionarySensFreq, config); instances[14] = new Transformer14(inputGeneralized, hierarchies, inputAnalyzed, dictionarySensValue, dictionarySensFreq, config); instances[13] = new Transformer13(inputGeneralized, hierarchies, inputAnalyzed, dictionarySensValue, dictionarySensFreq, config); instances[12] = new Transformer12(inputGeneralized, hierarchies, inputAnalyzed, dictionarySensValue, dictionarySensFreq, config); instances[11] = new Transformer11(inputGeneralized, hierarchies, inputAnalyzed, dictionarySensValue, dictionarySensFreq, config); instances[10] = new Transformer10(inputGeneralized, hierarchies, inputAnalyzed, dictionarySensValue, dictionarySensFreq, config); instances[9] = new Transformer09(inputGeneralized, hierarchies, inputAnalyzed, dictionarySensValue, dictionarySensFreq, config); instances[8] = new Transformer08(inputGeneralized, hierarchies, inputAnalyzed, dictionarySensValue, dictionarySensFreq, config); instances[7] = new Transformer07(inputGeneralized, hierarchies, inputAnalyzed, dictionarySensValue, dictionarySensFreq, config); instances[6] = new Transformer06(inputGeneralized, hierarchies, inputAnalyzed, dictionarySensValue, dictionarySensFreq, config); instances[5] = new Transformer05(inputGeneralized, hierarchies, inputAnalyzed, dictionarySensValue, dictionarySensFreq, config); instances[4] = new Transformer04(inputGeneralized, hierarchies, inputAnalyzed, dictionarySensValue, dictionarySensFreq, config); instances[3] = new Transformer03(inputGeneralized, hierarchies, inputAnalyzed, dictionarySensValue, dictionarySensFreq, config); instances[2] = new Transformer02(inputGeneralized, hierarchies, inputAnalyzed, dictionarySensValue, dictionarySensFreq, config); instances[1] = new Transformer01(inputGeneralized, hierarchies, inputAnalyzed, dictionarySensValue, dictionarySensFreq, config); instances[0] = new TransformerAll(inputGeneralized, hierarchies, inputAnalyzed, dictionarySensValue, dictionarySensFreq, config); } /** * Apply internal. * * @param projection * the projection * @param state * the state * @param source * the source * @param target * the target * @param snapshot * the snapshot * @param transition * the transition * @return the hash groupify */ protected HashGroupify applyInternal(final long projection, final int[] state, final HashGroupify source, final HashGroupify target, final int[] snapshot, final TransitionType transition) { int startIndex = 0; int stopIndex = 0; int bucket = 0; HashGroupifyEntry element = null; switch (transition) { case UNOPTIMIZED: startIndex = 0; stopIndex = inputGeneralized.length; break; case ROLLUP: startIndex = 0; stopIndex = source.getNumberOfEquivalenceClasses(); bucket = 0; element = source.getFirstEquivalenceClass(); break; case SNAPSHOT: startIndex = 0; stopIndex = snapshot.length / config.getSnapshotLength(); break; } AbstractTransformer app = null; app = getApplicator(projection); app.init(projection, state, target, source, snapshot, transition, startIndex, stopIndex, bucket, element, outputGeneralized); return app.call(); } /** * Gets the applicator. * * @param projection the projection * @return the applicator */ protected AbstractTransformer getApplicator(final long projection) { final int index = dimensions - Long.bitCount(projection); if (index > (instances.length - 1)) { return instances[0]; } else { return instances[index]; } } }