python实现简单的匹配队列

367 阅读2分钟

问题

假设有两个数据流A、B,两者可以通过key关联上。如何简单地写一个python实现

解决方案

有序队列

可以使用python地OrderedDict实现简单的队列。这种字典按照元素的插入顺序排列,这样就可以把数据流A或者B保存到一个有序的队列中。当数据匹配上之后,返回这个匹配上的数据,然后从队列中删除这个数据。

数据结构

将不同流的数据保存到同一个字典中,key作为字典的key,使用字典保存不同的流。

type Cache = OrderedDict
type CacheItem = {
    key: 用于关联流的key,
    value: {
        A: 其中一个流,
        B: 另一个流,
        ...
    }
}

固定大小

给有序队列指定容量,当超过这个容量时,最先入队的数据丢弃掉。这个数据属于未匹配上的数据,需要额外处理。

如果流中存在匹配不上的数据,那么队列长度一定会变得越来越长,最终耗尽内存。因此我们给队列一个固定的容量,超过这个容量之后,丢弃最开始入队、且未匹配上的数据。这个数据被视为错误数据,需要额外处理。

简单的代码实现

from collections import OrderedDict
import random

# 1.从一个(或多个)流读取数据data = {key, ...}
# 2.匹配前后取到的数据,按照匹配函数匹配上f(d1.key, d2.key)
#  - 输出匹配上的数据(d1, d2)
#  - 从缓存中删除匹配上的数据d1,d2
# 3.如果没有匹配上,则插入队列最后
# 4.当队列当前缓存数据量大于设定的最大限度后,出队

cache = OrderedDict()

max_size = 3

# 数据流
for i in range(0, 100):
    # 当前从流中获取的数据
    to_insert = random.randint(0, 10)
    # 匹配函数
    is_odd = to_insert % 2 == 1
    gt_than_to_insert = cache.get(to_insert + 1)
    # 匹配:本身为奇数,比它大1的数存在
    # 删除匹配的两个数
    if is_odd and gt_than_to_insert != None:
        print(f"匹配: {to_insert} {gt_than_to_insert}")
        del cache[gt_than_to_insert]
    # 未匹配:本身为偶数,或比它大1的数不存在
    # 未匹配入队
    else:
        cache[to_insert] = to_insert
    # 超过容纳极限,则出队
    if len(cache) > max_size:
        unmatched = cache.popitem(last=False)
        print(f"未匹配: {unmatched}")

print(cache)