Skip to content

Commit

Permalink
Assignment evaluation refactoring in progress.
Browse files Browse the repository at this point in the history
  • Loading branch information
semancik committed Jul 30, 2014
1 parent 1c579c7 commit 762b0bb
Show file tree
Hide file tree
Showing 6 changed files with 425 additions and 67 deletions.
@@ -0,0 +1,308 @@
/*
* Copyright (c) 2010-2014 Evolveum
*
* 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 com.evolveum.midpoint.prism.delta;

import com.evolveum.midpoint.prism.SimpleVisitable;
import com.evolveum.midpoint.prism.SimpleVisitor;
import com.evolveum.midpoint.prism.Visitable;
import com.evolveum.midpoint.prism.Visitor;
import com.evolveum.midpoint.util.Cloner;
import com.evolveum.midpoint.util.DebugDumpable;
import com.evolveum.midpoint.util.DebugUtil;
import com.evolveum.midpoint.util.MiscUtil;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

/**
*
* @author Radovan Semancik
*/
public class DeltaMapTriple<K,V> implements DebugDumpable, Serializable, SimpleVisitable<Map.Entry<K, V>> {

/**
* Collection of values that were not changed.
*/
protected Map<K,V> zeroMap;

/**
* Collection of values that were added.
*/
protected Map<K,V> plusMap;

/**
* Collection of values that were deleted.
*/
protected Map<K,V> minusMap;

public DeltaMapTriple() {
zeroMap = createMap();
plusMap = createMap();
minusMap = createMap();
}

public DeltaMapTriple(Map<K,V> zeroMap, Map<K,V> plusMap, Map<K,V> minusMap) {
this.zeroMap = zeroMap;
this.plusMap = plusMap;
this.minusMap = minusMap;
}

protected Map<K,V> createMap() {
return new HashMap<>();
}

public Map<K,V> getZeroMap() {
return zeroMap;
}

public Map<K,V> getPlusMap() {
return plusMap;
}

public Map<K,V> getMinusMap() {
return minusMap;
}

public Map<K,V> getMap(PlusMinusZero plusMinusZero) {
if (plusMinusZero == null) {
return null;
}
switch (plusMinusZero) {
case PLUS: return plusMap;
case MINUS: return minusMap;
case ZERO: return zeroMap;
}
// notreached
throw new IllegalStateException();
}

public boolean hasPlusMap() {
return (plusMap != null && !plusMap.isEmpty());
}

public boolean hasZeroMap() {
return (zeroMap != null && !zeroMap.isEmpty());
}

public boolean hasMinusMap() {
return (minusMap != null && !minusMap.isEmpty());
}

public boolean isZeroOnly() {
return hasZeroMap() && !hasPlusMap() && !hasMinusMap();
}

public void addToPlusMap(K key, V value) {
addToMap(plusMap, key, value);
}

public void addToMinusMap(K key, V value) {
addToMap(minusMap, key, value);
}

public void addToZeroMap(K key, V value) {
addToMap(zeroMap, key, value);
}

public void addAllToPlusMap(Map<K,V> map) {
addAllToMap(plusMap, map);
}

public void addAllToMinusMap(Map<K,V> map) {
addAllToMap(minusMap, map);
}

public void addAllToZeroMap(Map<K,V> map) {
addAllToMap(zeroMap, map);

}

public void addAllToMap(PlusMinusZero destination, Map<K,V> map) {
if (destination == null) {
return;
} else if (destination == PlusMinusZero.PLUS) {
addAllToMap(plusMap, map);
} else if (destination == PlusMinusZero.MINUS) {
addAllToMap(minusMap, map);
} else if (destination == PlusMinusZero.ZERO) {
addAllToMap(zeroMap, map);
}
}

private void addAllToMap(Map<K,V> set, Map<K,V> items) {
if (items == null) {
return;
}
for (Entry<K, V> item: items.entrySet()) {
addToMap(set, item.getKey(), item.getValue());
}
}

private void addToMap(Map<K,V> set, K key, V value) {
if (set == null) {
set = createMap();
}
set.put(key, value);
}

public void clearPlusMap() {
clearMap(plusMap);
}

public void clearMinusMap() {
clearMap(minusMap);
}

public void clearZeroMap() {
clearMap(zeroMap);
}

private void clearMap(Map<K,V> set) {
if (set != null) {
set.clear();
}
}

public int size() {
return sizeMap(zeroMap) + sizeMap(plusMap) + sizeMap(minusMap);
}

private int sizeMap(Map<K,V> set) {
if (set == null) {
return 0;
}
return set.size();
}

public void merge(DeltaMapTriple<K,V> triple) {
addAllToZeroMap(triple.zeroMap);
addAllToPlusMap(triple.plusMap);
addAllToMinusMap(triple.minusMap);
}

/**
* Returns all values, regardless of the internal sets.
*/
public Collection<K> unionKeySets() {
return MiscUtil.union(zeroMap.keySet(), plusMap.keySet(), minusMap.keySet());
}

public DeltaMapTriple<K,V> clone(Cloner<Entry<K, V>> cloner) {
DeltaMapTriple<K,V> clone = new DeltaMapTriple<K,V>();
copyValues(clone, cloner);
return clone;
}

protected void copyValues(DeltaMapTriple<K,V> clone, Cloner<Entry<K, V>> cloner) {
clone.zeroMap = cloneSet(this.zeroMap, cloner);
clone.plusMap = cloneSet(this.plusMap, cloner);
clone.minusMap = cloneSet(this.minusMap, cloner);
}

private Map<K,V> cloneSet(Map<K,V> origSet, Cloner<Entry<K, V>> cloner) {
if (origSet == null) {
return null;
}
Map<K,V> clonedSet = createMap();
for (Entry<K, V> origVal: origSet.entrySet()) {
Entry<K, V> clonedVal = cloner.clone(origVal);
clonedSet.put(clonedVal.getKey(), clonedVal.getValue());
}
return clonedSet;
}

public boolean isEmpty() {
return isEmpty(minusMap) && isEmpty(plusMap) && isEmpty(zeroMap);
}

private boolean isEmpty(Map<K,V> set) {
if (set == null) {
return true;
}
return set.isEmpty();
}

@Override
public void accept(SimpleVisitor<Entry<K, V>> visitor) {
acceptMap(visitor, zeroMap);
acceptMap(visitor, plusMap);
acceptMap(visitor, minusMap);
}

private void acceptMap(SimpleVisitor<Entry<K, V>> visitor, Map<K,V> set) {
if (set == null) {
return;
}
for (Entry<K, V> element: set.entrySet()) {
visitor.visit(element);
}
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(debugName()).append("(");
dumpMap(sb, "zero", zeroMap);
dumpMap(sb, "plus", plusMap);
dumpMap(sb, "minus", minusMap);
sb.append(")");
return sb.toString();
}

protected String debugName() {
return "DeltaMapTriple";
}

private void dumpMap(StringBuilder sb, String label, Map<K,V> set) {
sb.append(label).append(": ").append(set).append("; ");
}

/* (non-Javadoc)
* @see com.evolveum.midpoint.util.DebugDumpable#debugDump()
*/
@Override
public String debugDump() {
return debugDump(0);
}

/* (non-Javadoc)
* @see com.evolveum.midpoint.util.DebugDumpable#debugDump(int)
*/
@Override
public String debugDump(int indent) {
StringBuilder sb = new StringBuilder();
DebugUtil.indentDebugDump(sb, indent);
sb.append("DeltaSetTriple:\n");
debugDumpMap(sb, "zero", zeroMap, indent + 1);
sb.append("\n");
debugDumpMap(sb, "plus", plusMap, indent + 1);
sb.append("\n");
debugDumpMap(sb, "minus", minusMap, indent + 1);
return sb.toString();
}

private void debugDumpMap(StringBuilder sb, String label, Map<K,V> set, int indent) {
DebugUtil.debugDumpLabel(sb, label, indent);
sb.append("\n");
DebugUtil.debugDumpMapMultiLine(sb, set, indent + 1);
}

}
Expand Up @@ -26,4 +26,28 @@ public enum PlusMinusZero {

PLUS, MINUS, ZERO;

public static PlusMinusZero compute(PlusMinusZero mode1, PlusMinusZero mode2) {
if (mode1 == null || mode2 == null) {
return null;
}
switch (mode1) {
case PLUS: switch (mode2) {
case PLUS: return PlusMinusZero.PLUS;
case ZERO: return PlusMinusZero.PLUS;
case MINUS: return null;
}
case ZERO: switch (mode2) {
case PLUS: return PlusMinusZero.PLUS;
case ZERO: return PlusMinusZero.ZERO;
case MINUS: return PlusMinusZero.MINUS;
}
case MINUS: switch (mode2) {
case PLUS: return null;
case ZERO: return PlusMinusZero.MINUS;
case MINUS: return PlusMinusZero.MINUS;
}
}
// notreached
throw new IllegalStateException();
}
}
Expand Up @@ -290,7 +290,7 @@ private void prepareConstructionEvaluation(EvaluatedAssignment<F> evaluatedAssig

// Do not evaluate the construction here. We will do it in the second pass. Just prepare everything to be evaluated.

evaluatedAssignment.addConstruction(construction);
evaluatedAssignment.addConstructionZero(construction);
}

private void evaluateFocusMappings(EvaluatedAssignment<F> evaluatedAssignment, AssignmentPathSegment assignmentPathSegment,
Expand Down

0 comments on commit 762b0bb

Please sign in to comment.