结合多个事件流

时间:2012-11-16 11:34:45

标签: java algorithm events

假设我有 N 数据事件流,我想将它们合并为一个,使用一些用于排序(例如 timestamp )。假设EventStream被定义为:

class EventStream{

    Event peek();

    Event next();
}

现在我想接受 N 事件流,将它们包装在一个流中,这将强制执行排序。但是,我不想简单地遍历所有流并将它们添加到priorityQueue中 - 我不希望内存中的所有事件,因为我将很快耗尽堆空间。我想要一种动态方法,其中每个next()之后的组合流可以确定下一个事件应该是什么。我每次都可以扫描 N 流并找出下一个值是什么,但是有更好的方法吗?

3 个答案:

答案 0 :(得分:2)

你可以避免缓存所有内容,只通过偷看他们对流进行过多的查找,并且只在需要时才这样做。我建议你写一个类似于这个的MergedEventStream

public class MergedEventStream implements EventStream {

    private ArrayList<EventStream> merged = new ArrayList<EventStream>();
    private int nextIndex = -1;

    public MergedEventStream(Collection<EventStream> toMerge) {
        merged.addAll(toMerge);
        findNext();
    }

    public Event peek() {
        if (nextIndex == -1 && findNext() == false) {
           throw new NoSuchElementException();
        } else {
           Event e = merged.get(nextIndex).peek();
           return e;
        }
    }

    public Event peek() {
        if (nextIndex == -1 && findNext() == false) {
           throw new NoSuchElementException();
        } else {
           Event e = merged.get(nextIndex).next();
           findNext();
           return e;
        }
    }

    /**
     * iterates over merged, and for each stream with an available event,
     * adds it to a sorted TreeMap<Event, Integer> (sorting by any event field; integer
     * is stream index in arrayList)
     * if set is not empty, returns 'true', and sets nextIndex to the stream index
     * otherwise, returns 'false', and sets nextIndex to -1
     */
    private boolean findNext() {
        // ...
    }
}

您可以通过将TreeMap保留为实例属性并仅刷新从中提取的流来提高效率。

答案 1 :(得分:2)

使用MinHeap存储每个事件流中的一个事件。

next()上弹出堆顶部事件(具有最早时间的值)。

然后从检索事件的同一EventStream中输入一个事件。

因此,MinHeap中每个EventStream只有一个Event形式。

您将在MinHeap中使用Event存储对EventStream的引用。

这个next()实现将使用O(log n),其中'n'是EventStream的数量。

注意:预计EventStream已经对事件进行了排序。 Next()始终返回最早的事件。

答案 2 :(得分:1)

你的方法很好。除非N很大,否则应该没问题。

如果N非常大,您可以将每个流的第一个事件存储在已排序的集合中,与其来源相关联,每次从此已排序的集合中删除项目时,您都可以添加下一个来自它的流。