public DispatchRouteInformation[] addHashDispatcher(final LocalVertex srcPV, final List<LocalEdge> edges,
                                                        final HashCoder coder) {
        Collections.sort(edges, new PartitionOrderComparetor());
        final ThreadUnit srcThreadUnit = srcPV.getThreadUnit();
        final int srcQueueThreadLocalId = edges.get(0).getSrcQueueThreadLocalId();

        DispatchAccepter[] accepters = new DispatchAccepter[edges.size()];
        int[] destQueueThreadLocalId = new int[edges.size()];
        int[] destQueueLogicalId = new int[edges.size()];
        double[] partitioningRate = new double[edges.size()];

        int index = 0;
        for (LocalEdge edge : edges) {
            final LocalVertex destPV = edge.getDestVertex();
            if (srcPV.getThreadUnit() == destPV.getThreadUnit()) {
                accepters[index] = (DispatchAccepter<?>) destPV.getContext();
            } else {
                accepters[index] = (DispatchAccepter<?>) destPV.getThreadUnit();
            }

            if (destPV instanceof LocalPhysicalVertex) {
                destQueueLogicalId[index] = edge.getDestQueueLogicalId();
                destQueueThreadLocalId[index] = edge.getDestQueueThreadLocalId();
            } else {
                destQueueLogicalId[index] = edge.getDestQueueId();
                destQueueThreadLocalId[index] = edge.getDestQueueThreadLocalId();
            }
            index++;
        }

        return unitController.addHashDispatcher(srcThreadUnit, srcQueueThreadLocalId, accepters,
                                                destQueueThreadLocalId, destQueueLogicalId, false, coder,
                                                partitioningRate);
    }