/** * Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.financial.comparison; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import org.fudgemsg.FudgeContext; import com.google.common.collect.Maps; import com.opengamma.core.position.Position; import com.opengamma.util.ArgumentChecker; import com.opengamma.util.tuple.Pair; /** * Provides comparison operations between sets of {@link Position} objects. */ public class PositionSetComparator extends AbstractComparator { public PositionSetComparator(final FudgeContext fudgeContext) { super(fudgeContext); } private static Set<PositionInfo> createPositionInfoSet(final ComparisonContext context, final Iterable<Position> positions, final int sizeHint) { final Map<PositionInfo, PositionInfo> map = Maps.newHashMapWithExpectedSize(sizeHint); for (Position position : positions) { final PositionInfo info = new PositionInfo(context, position); final PositionInfo previous = map.get(info); if (previous != null) { previous.associateAdditionalUnderlying(position); } else { map.put(info, info); } } return new HashSet<PositionInfo>(map.keySet()); } /** * Produces a comparison of two sets of positions. * * @param first first set of positions, not null * @param second second set of positions, not null * @return the comparison result */ public PositionSetComparison compare(final Iterable<Position> first, final Iterable<Position> second) { ArgumentChecker.notNull(first, "first"); ArgumentChecker.notNull(second, "second"); final ComparisonContext context = createContext(); return compare(createPositionInfoSet(context, first, 32), createPositionInfoSet(context, second, 32)); } /** * Produces a comparison of two sets of positions. * * @param first first set of positions, not null * @param second second set of positions, not null * @return the comparison result */ public PositionSetComparison compare(final Collection<Position> first, final Collection<Position> second) { ArgumentChecker.notNull(first, "first"); ArgumentChecker.notNull(second, "second"); final ComparisonContext context = createContext(); return compare(createPositionInfoSet(context, first, first.size()), createPositionInfoSet(context, second, second.size())); } private static Collection<Position> getUnderlyingPositions(final Collection<PositionInfo> positions) { final Collection<Position> result = new ArrayList<Position>(positions.size()); for (PositionInfo position : positions) { position.addUnderlyingToCollection(result); } return result; } private PositionSetComparison compare(final Set<PositionInfo> first, final Set<PositionInfo> second) { final Iterator<PositionInfo> itrFirst = first.iterator(); final Collection<Position> intersection = new ArrayList<Position>(); // Remove the identical positions first to lower the size of the sets while (itrFirst.hasNext()) { final PositionInfo position = itrFirst.next(); if (second.remove(position)) { // Second portfolio contained an equivalent position position.addUnderlyingToCollection(intersection); itrFirst.remove(); } } final Collection<Pair<Position, Position>> diff = new ArrayList<Pair<Position, Position>>(); // TODO: identify changes // Anything left in either set is unique to that set return new PositionSetComparison(diff, getUnderlyingPositions(first), getUnderlyingPositions(second), intersection); } }