prm4j.indexing.model.JoinArgs.java Source code

Java tutorial

Introduction

Here is the source code for prm4j.indexing.model.JoinArgs.java

Source

/*
 * Copyright (c) 2012, 2013 Mateusz Parzonka
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * Mateusz Parzonka - initial API and implementation
 */
package prm4j.indexing.model;

import static prm4j.indexing.IndexingUtils.toParameterMask;
import static prm4j.indexing.IndexingUtils.toParameterMasks;
import static prm4j.indexing.IndexingUtils.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

import prm4j.Util.Tuple;
import prm4j.api.BaseEvent;
import prm4j.api.Parameter;
import prm4j.indexing.monitor.DeadMonitor;

import com.google.common.base.Predicate;
import com.google.common.collect.Sets;
import com.google.common.collect.Table;

/**
 * Represents all instances which are compatible with the event instance.
 * <p>
 * Used by {@link EventContext}
 */
public class JoinArgs {

    // identifies the node, which represents the compatible part of the instance, we want to join with
    public final int[] nodeMask;
    // identifies the monitor set, which contains the monitors carrying the bindings we will join with (they are
    // strictly more informative than the node, selected by the nodeMask)
    public final int monitorSetId;
    // prepares the event bindings for the join
    public final int[] extensionPattern;
    // identifies the bindings which will be used for the join, picking out only "new" parameters
    // { joiningBinding[i1], joinableBinding[j1], joiningBinding[i2], joinableBinding[j2], ... }
    public final int[] copyPattern;

    /**
     * ParameterMasks to be used with uncompressed bindings. Each parameterMask selects a instance to check if it has a
     * monitor. If it has a monitor, do not create a monitor (and node, if possible) in this join. The checked instances
     * are usually configured with the {@link DeadMonitor}, to define that they are disabled.
     * 
     * @return array of parameter masks
     */
    public int[][] disableMasks;

    public JoinArgs(int[] nodeMask, int monitorSetId, int[] extensionPattern, int[] copyPattern,
            int[][] disableMasks) {
        super();
        this.nodeMask = nodeMask;
        this.monitorSetId = monitorSetId;
        this.extensionPattern = extensionPattern;
        this.copyPattern = copyPattern;
        this.disableMasks = disableMasks;
    }

    @Override
    public String toString() {
        StringBuilder disableMasksString = new StringBuilder("[");
        for (int[] disableMask : disableMasks) {
            disableMasksString.append(Arrays.toString(disableMask));
            disableMasksString.append(" ");
        }
        disableMasksString.append("]");
        return "JoinArgs [nodeMask=" + Arrays.toString(nodeMask) + ", monitorSetId=" + monitorSetId
                + ", extensionPattern=" + Arrays.toString(extensionPattern) + ", copyPattern="
                + Arrays.toString(copyPattern) + ", disableMasks=" + disableMasksString.toString() + "]";
    }

    public static JoinArgs[] createArgsArray(ParametricPropertyModel ppm, BaseEvent baseEvent) {
        final JoinArgs[] result = new JoinArgs[ppm.getJoinTuples().get(baseEvent).size()];
        final Table<Set<Parameter<?>>, Set<Parameter<?>>, Integer> monitorSetIds = ppm.getMonitorSetIds();
        int i = 0;
        for (Tuple<Set<Parameter<?>>, Set<Parameter<?>>> tuple : ppm.getJoinTuples().get(baseEvent)) {
            final Set<Parameter<?>> compatibleSubset = tuple._1();
            final Set<Parameter<?>> enableSet = tuple._2();
            final int[] nodeMask = toParameterMask(compatibleSubset);
            final int monitorSetId = monitorSetIds.get(compatibleSubset, enableSet);
            final int[] extensionPattern = getExtensionPattern(baseEvent.getParameters(), enableSet);
            final int[] copyPattern = getCopyPattern(baseEvent.getParameters(), enableSet);
            final int[][] disableMasks = toParameterMasks(getDisableSets(ppm, baseEvent, enableSet),
                    Sets.union(baseEvent.getParameters(), enableSet));
            result[i++] = new JoinArgs(nodeMask, monitorSetId, extensionPattern, copyPattern, disableMasks);
        }
        return result;
    }

    protected static List<Set<Parameter<?>>> getDisableSets(ParametricPropertyModel ppm, BaseEvent baseEvent,
            final Set<Parameter<?>> enableSet) {
        final Set<Parameter<?>> combination = Sets.union(baseEvent.getParameters(), enableSet);
        return toListOfParameterSetsAscending(
                Sets.filter(toParameterSets(ppm.getParametricProperty().getSpec().getBaseEvents()),
                        new Predicate<Set<Parameter<?>>>() {
                            @Override
                            public boolean apply(Set<Parameter<?>> baseEventParameterSet) {
                                return combination.containsAll(baseEventParameterSet)
                                        && !enableSet.containsAll(baseEventParameterSet);
                            }
                        }));
    }

    /**
     * Creates a int pattern needed for the join operation.
     * 
     * @param baseSet
     *            all parameters of this set will be kept
     * @param joiningSet
     *            new parameters from this set will join
     * @return
     */
    protected static int[] getExtensionPattern(Set<Parameter<?>> baseSet, Set<Parameter<?>> joiningSet) {
        final List<Integer> result = new ArrayList<Integer>();
        final Set<Integer> baseParameterIndexSet = toParameterIndexSet(baseSet);
        final int[] joinedArray = toParameterMask(Sets.union(baseSet, joiningSet));
        for (int parameterIndex : joinedArray) {
            if (baseParameterIndexSet.contains(parameterIndex)) {
                result.add(parameterIndex);
            } else {
                result.add(-1);
            }
        }
        return toPrimitiveIntegerArray(result);
    }

    /**
     * Returns a pattern { s1, t1, ..., sN, tN } which represents a instruction to copy a binding from sourceBinding[s1]
     * to targetBinding[t1] to perform a join.
     * 
     * @param ps1
     *            parameter set which masks the target binding
     * @param ps2
     *            parameter set which masks the source binding
     * @return the pattern
     */
    protected static int[] getCopyPattern(Set<Parameter<?>> ps1, Set<Parameter<?>> ps2) {
        List<Integer> result = new ArrayList<Integer>();
        int i = 0;
        int j = 0;
        int k = 0;
        while (i < ps1.size() || j < ps2.size()) {
            if (i < ps1.size() && j < ps2.size() && toParameterMask(ps1)[i] == toParameterMask(ps2)[j]) {
                i++;
                j++;
            } else if (i < ps1.size() && (j >= ps2.size() || toParameterMask(ps1)[i] < toParameterMask(ps2)[j])) {
                i++;
            } else {
                result.add(j++);
                result.add(i + k++);
            }
        }
        return toPrimitiveIntegerArray(result);
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + Arrays.hashCode(copyPattern);
        result = prime * result + Arrays.hashCode(disableMasks);
        result = prime * result + Arrays.hashCode(extensionPattern);
        result = prime * result + monitorSetId;
        result = prime * result + Arrays.hashCode(nodeMask);
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        JoinArgs other = (JoinArgs) obj;
        if (!Arrays.equals(copyPattern, other.copyPattern)) {
            return false;
        }
        if (!Arrays.deepEquals(disableMasks, other.disableMasks)) {
            return false;
        }
        if (!Arrays.equals(extensionPattern, other.extensionPattern)) {
            return false;
        }
        if (monitorSetId != other.monitorSetId) {
            return false;
        }
        if (!Arrays.equals(nodeMask, other.nodeMask)) {
            return false;
        }
        return true;
    }

}