/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.engine.view.listener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.threeten.bp.Instant;
import com.google.common.base.Function;
import com.opengamma.engine.view.ViewComputationResultModel;
import com.opengamma.engine.view.ViewDeltaResultModel;
import com.opengamma.engine.view.impl.InMemoryViewComputationResultModel;
import com.opengamma.engine.view.impl.InMemoryViewDeltaResultModel;
/**
* Base class for cycle results.
*/
public abstract class AbstractCompletedResultsCall implements Function<ViewResultListener, Object> {
private static final Logger s_logger = LoggerFactory.getLogger(AbstractCompletedResultsCall.class);
private ViewComputationResultModel _full;
private InMemoryViewComputationResultModel _fullCopy;
private ViewDeltaResultModel _delta;
private InMemoryViewDeltaResultModel _deltaCopy;
public AbstractCompletedResultsCall(ViewComputationResultModel full, ViewDeltaResultModel delta) {
update(full, delta);
}
// NOTE: The calculation time is machine time, not valuation time so we know which was computed first, unless the cycle times are
// smaller than the resolution of the Instant clock.
protected InMemoryViewComputationResultModel getViewComputationResultModelCopy() {
if (_fullCopy == null) {
_fullCopy = new InMemoryViewComputationResultModel(_full);
_full = _fullCopy;
}
return _fullCopy;
}
protected void setViewComputationResultModel(final ViewComputationResultModel full) {
_full = full;
_fullCopy = null;
}
protected void setViewComputationResultModelCopy(final InMemoryViewComputationResultModel full) {
_fullCopy = full;
_full = full;
}
protected abstract void newResult(ViewComputationResultModel full);
protected abstract void ambiguousResult(ViewComputationResultModel full);
protected abstract void oldResult(ViewComputationResultModel full);
public void update(ViewComputationResultModel full, ViewDeltaResultModel delta) {
if (full != null) {
if (_full != null) {
final Instant previous = _full.getCalculationTime();
final Instant current = full.getCalculationTime();
if (previous.isBefore(current)) {
newResult(full);
} else if (previous.equals(current)) {
ambiguousResult(full);
} else {
oldResult(full);
}
} else {
s_logger.debug("Got initial full result");
_full = full;
}
}
if (delta != null) {
if (_delta != null) {
final Instant previous = _delta.getCalculationTime();
final Instant current = delta.getCalculationTime();
if (previous.isAfter(current)) {
// This result predates the current value, so swap and merge to get ordering right
s_logger.debug("Applying old delta from {} to new baseline delta from {}", previous, current);
_deltaCopy = new InMemoryViewDeltaResultModel(delta);
_deltaCopy.update(_delta);
_delta = _deltaCopy;
} else {
// Merge the new result into the running delta
if (s_logger.isDebugEnabled()) {
if (previous.equals(current)) {
// Two results calculated so close together they appear "at the same time". The merge order might be wrong.
s_logger.debug("Merging two deltas both calculated at {}", current);
} else {
s_logger.debug("Applying new delta from {} to previous delta from {}", current, previous);
}
}
if (_deltaCopy == null) {
_deltaCopy = new InMemoryViewDeltaResultModel(_delta);
_delta = _deltaCopy;
}
_deltaCopy.update(delta);
}
} else {
s_logger.debug("Got initial delta result");
_delta = delta;
}
}
}
public ViewComputationResultModel getViewComputationResultModel() {
return _full;
}
public ViewDeltaResultModel getViewDeltaResultModel() {
return _delta;
}
}