2

QuickFIXJで2つの修正メッセージ(たとえば2つのExecutionReports)を比較する必要があります。

er1それらを呼び出してみましょうer2

さて、私がそれらを比較することによって意味するのは、フィールドの束が同一でなければならないということです。たとえば、タグ55、タグ207、タグ1が同じであることを気にします。しかし、他の人ではありません。

そうする唯一の方法は、次のように(パフォーマンス的に)高価なものを書くことだと私には思えます。

public static boolean compare(ExecutionReport er1,ExecutionReport er2) 
{
   StringField sf1 = new StringField(55);
   StringField sf2 = new StringField(55);

   er.getField(sf1);
   er.getField(sf2);

   if (sf1.getValue().equals(sf2.getValue())==false) return false;

   ... // continue with all of the other fields
   ... // in the same way

}

私は何かが足りないのですか?誰かがより良い/より速いアプローチを提案できますか?

4

2 に答える 2

2

APIには2つの修正メッセージを比較する機能がないようです。ただし、メッセージフィールド全体を比較するのではなく、必須のフィールドのみを比較するのが最善です。拡張機能は、これらのフィールドがFIXメッセージに存在することを確信している場合です。

別のオプションは、メッセージを送受信しているセッションのスレッドとは異なるスレッドで比較することです。実行レポートでダウンストリームで何が発生するか、または実行レポートが一致した場合のアクションを知らずに、メッセージを同じスレッドで比較する必要があるかどうかを判断するのは困難です。

于 2011-03-23T09:10:41.663 に答える
0

quickfix.Message.toXML()反復ロジックに基づく実装。比較の結果は、複合キー(フィールドがグループの一部である場合)と「前」と「後」の状態のペアのソートされたマップです。

import static java.lang.Math.min;
import static java.util.Collections.emptySet;
import static java.util.stream.Collectors.toList;
import static org.apache.commons.collections4.CollectionUtils.subtract;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;

import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;

import quickfix.Field;
import quickfix.FieldMap;
import quickfix.Group;
import quickfix.Message;

public class FixDiff {

    private static final CompositeKeyComparator COMPARATOR = new CompositeKeyComparator();

    private Set<Integer> ignored;

    public FixDiff() {
        this(emptySet());
    }

    public FixDiff(Set<Integer> ignored) {
        this.ignored = ignored;
    }

    public Map<List<Integer>, Pair<String, String>> compare(Message expected, Message actual) {
        Map<List<Integer>, String> expectedMap = toHierarchialMap(expected);
        Map<List<Integer>, String> actualMap = toHierarchialMap(actual);

        Collection<List<Integer>> missing = subtract(expectedMap.keySet(), actualMap.keySet());
        Collection<List<Integer>> extra = subtract(actualMap.keySet(), expectedMap.keySet());
        Collection<List<Integer>> diff = expectedMap.entrySet().stream()
                .filter(e -> !missing.contains(e.getKey()) && !extra.contains(e.getKey()))
                .filter(e -> !e.getValue().equals(actualMap.get(e.getKey())))
                .map(Entry::getKey)
                .collect(toList());

        TreeMap<List<Integer>, Pair<String, String>> discrepancies = new TreeMap<List<Integer>, Pair<String, String>>(COMPARATOR);
        missing.forEach(key -> discrepancies.put(key, new ImmutablePair<String, String>(expectedMap.get(key), null)));
        extra.forEach(key -> discrepancies.put(key, new ImmutablePair<String, String>(null, actualMap.get(key))));
        diff.forEach(key -> discrepancies.put(key, new ImmutablePair<String, String>(expectedMap.get(key), actualMap.get(key))));
        return discrepancies;
    }

    private Map<List<Integer>, String> toHierarchialMap(Message message) {
        Map<List<Integer>, String> result = new HashMap<List<Integer>, String>();
        toHierarchialMap(result, new ArrayList<Integer>(), message.getHeader());
        toHierarchialMap(result, new ArrayList<Integer>(), message);
        toHierarchialMap(result, new ArrayList<Integer>(), message.getTrailer());
        return result;
    }

    private void toHierarchialMap(Map<List<Integer>, String> map, ArrayList<Integer> segmentKey, FieldMap segment) {
        Iterator<Field<?>> iterator = segment.iterator();
        while (iterator.hasNext()) {
            Field<?> field = iterator.next();
            if (!ignored.contains(field.getTag()) && field.getObject() != null)
                map.put(compositeKey(segmentKey, field.getTag()), field.getObject().toString());
        }
        Iterator<Integer> groupKeyIterator = segment.groupKeyIterator();
        while (iterator.hasNext()) {
            Integer groupKey = groupKeyIterator.next();
            if (ignored.contains(groupKey))
                continue;
            for (Group group : segment.getGroups(groupKey))
                toHierarchialMap(map, compositeKey(segmentKey, groupKey), group);
        }
    }

    private ArrayList<Integer> compositeKey(ArrayList<Integer> parent, Integer tag) {
        ArrayList<Integer> copy = new ArrayList<>(parent);
        copy.add(tag);
        return copy;
    }

    private static class CompositeKeyComparator implements Comparator<List<Integer>> {
        @Override
        public int compare(List<Integer> o1, List<Integer> o2) {
            for (int i = 0; i < min(o1.size(), o2.size()); i++) {
                if (o1.get(i) != o2.get(i))
                    return o1.get(i) - o2.get(i);
            }
            return o1.size() - o2.size();
        }
    }
}
于 2021-03-25T14:58:50.003 に答える