2011-07-11 52 views
8

我想在队列中存储时间标记的元素,数据结构没有关系,只是我已经插入内的元素从说当前时间最后5分钟。任何旧的东西都应该被删除 - 这样,每当我得到队列的大小时,它就会计算最近5分钟内插入的对象的数量。排队的时间

基本上所有我知道的是我的应用程序有多少次让下一个电话之前做了一个HTTP调用到最后5分钟服务器。

如果有人可能在本实施,请分享一些现有的库都知道。

+0

你忘了提东西,如:所需的平台/语言/等... – DarkSquirrel42

+0

对不起它在Java。 – user759326

回答

4

在什么语言?队列是持久还是内存?

如果您在Java中需要此行为,您可以使用DelayedQueue,并有一个单独的线程连续调用queue.take()以避免过期的项目。 queue.size()将会为您提供队列中剩余未过期项目的大小。这就要求你把DelayedQueue项目实施Delayed接口,5分钟返回值到.getDelay()方法。

+0

谢谢,但这种方法唯一的问题是线程必须频繁运行才能使调用'queue.size()'的结果最好。 – user759326

+0

是的 - 它需要是一个紧密的循环(例如queue.take()!= null)。请注意,queue.take()将阻塞,直到队列中的元素到期为止。然后,迭代的频率由项目放置在队列中的频率(以及它们到期的频率)决定,而不是基于时间的垃圾收集(因此queue.size()将完全准确无误次)。 –

+0

谢谢,我没有意识到,queue.take()将阻塞,直到队列已过期元素被采取。了解他们如何实现DelayQueue将会很有趣 - 可能是他们在内部使用2个队列来保存过期的元素,而一个队列保留未过期的队列。不管怎么说,非常感谢 - 你们的人是如此的乐于助人 - 我想给你一个25美元的签证礼品卡给你 - 不知道如何发送 – user759326

6

您可以使用一个优先级队列带有时间戳作为你的钥匙。因此,当您调用Peek()时,您始终会将最旧的时间戳保留在队列中。然后,每次查询窗口大小内的项目数量时:清除窗口外的项目并返回优先级队列中的项目数。

例如:

public class CountInWindow { 

    /** 
    * Adding a main just for testing 
    * @param args 
    * @throws InterruptedException 
    */ 
    public static void main(String[] args) throws InterruptedException { 
     System.out.println("test started"); 
     CountInWindow test = new CountInWindow(5000); //5 seconds for testing 
     test.debug = true; 
     test.insertTimeStamp(System.currentTimeMillis()); 
     Thread.sleep(100);//sleep 
     test.insertTimeStamp(System.currentTimeMillis()); 
     Thread.sleep(100);//sleep 
     test.insertTimeStamp(System.currentTimeMillis()); 
     Thread.sleep(100);//sleep 
     test.insertTimeStamp(System.currentTimeMillis()); 
     Thread.sleep(5040);//sleep 5 secs 
     test.insertTimeStamp(System.currentTimeMillis()); 
     Thread.sleep(100);//sleep 
     test.insertTimeStamp(System.currentTimeMillis()); 
     System.out.println(test.getWindowCount()); //Should be 2 not 6. 
     System.out.println("test done"); 
    } 

    java.util.PriorityQueue<Long> window; 
    public static final long FIVE_MINS_IN_MS = 300000l; 
    public final long WINDOW_SIZE; 
    public boolean debug = false; 

    //Constructor which defaults to 5mins 
    public CountInWindow(){ 
     WINDOW_SIZE = FIVE_MINS_IN_MS; 
     window = new java.util.PriorityQueue<Long>(); 
    } 
    //Constructor for any size window 
    public CountInWindow(long windowSize){ 
     WINDOW_SIZE = windowSize; 
     window = new java.util.PriorityQueue<Long>(); 
    } 
    /** 
    * Add a new timestamp to the window's queue 
    * @param ts 
    */ 
    public void insertTimeStamp(long ts){ 
     window.add(ts); 
    } 
    /** 
    * Clean up items outside the window size and then return the count of times still in the window. 
    * @return A count of timestamps still inside the 5 mins window. 
    */ 
    public int getWindowCount(){ 
     long currTime = System.currentTimeMillis(); 
     //Clean out old Timestamps 
     while((currTime - window.peek().longValue()) > WINDOW_SIZE){ 
      long drop = window.remove().longValue(); 
      if(debug)System.out.println("dropping item:" + drop); 
     } 
     return window.size(); 
    } 
} 
+0

在场景中确实需要优先级队列,因为项目插入时间戳并且它将按顺序排列。 queue.peek()不仅仅是一个队列接口吗? – dmachop