我有一个客户列表说(A,B,C,D)有自己的时间段/窗口。我根据下一个窗口到期时间在内部设置了一个计时器......来自(A,B,C,D)的窗口大小..
例如:
Client Window Size
A 10
B 15
C 20
D 50
所以计时器到期时间为:10,15,20,30,40,45,50 ......
最好的方法是什么?选择C作为我们的语言来实现。客户端周期存储在静态分配的数组中(我们知道大小)
答案 0 :(得分:1)
最佳方法是优先级(分钟)堆,优先级基于到期时间。
每次窗口到期时,在O(1)时间内从堆中删除min项,并在过期时间加上O(log(N))时间内的窗口大小重新插入。所需空间为O(N)。
要表示当前时间,至少有两个选项。
1)使用宽值(比如64位)来处理太阳发火的时间
2)使用模运算;这需要仔细比较运算符
对于模数方法,时间值必须至少与最大窗口大小一样大,加上计时器到期延迟的小余量。使用无符号算术。堆中的值应该是插入条目的时间。每个条目的剩余时间是
window - (now - inserted)
请注意,(now - inserted)
总是正数,因为它是条目在堆中的长度的度量 - 如果差异“包裹”为零,则无符号结果将是正确的; window
也是积极的。如果我们有两个条目x
和y
,我们想看看是否
(x.window - (now - x.inserted)) > (y.window - (now - y.inserted))
我们可以使用
进行无符号算术(x.window + (now - y.inserted)) > (y.window + (now - x.inserted))
这是我们用来比较堆条目的比较运算符。
答案 1 :(得分:0)
取决于您添加客户端的频率以及窗口大小的大小,我会考虑使用此方法:
将m定义为最大窗口大小:m = max(Window Size)
。
然后你可以分配布尔数组:bool Alarms[m]
。
对于每个客户端集:Alamrs[k*windowsize]=true
其中k
的范围为<1, m/windowsize>
警报的每个刻度线检查Alarms[tick % m]
的值。当你读到真正的警报应该响起。阅读状态为O(1)。
当Window Sizes类似且你不经常添加窗口大小更高的客户端时,这种方法很好。
添加窗口大小&gt;的客户端时你必须重新分配整个阵列,这可能很昂贵。
当客户端窗口之间有大的空格时 - 例如A = 1且B = 30000,您需要29998个空单元格。