在一段时间内排队带有时间戳的元素

use*_*326 8 java queue data-structures

我想存储在一个队列中,数据结构无关紧要,只有我插入的元素说的是从当前时间开始的最后5分钟.任何较旧的东西都应该被删除 - 这样每当我得到队列的大小时,它将给出在最后5分钟插入的对象的数量.

基本上我要知道的是,在下一次通话之前,我的应用程序在最后5分钟内对服务器进行了多少次http呼叫.

如果有人知道可能有这个实现的现有库请分享.

eSn*_*iff 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 在这种情况下,优先级队列真的有必要吗,因为项目是按时间戳插入的,并且是按顺序排列的。使用queue.peek() 仅仅一个队列接口就足够了吗? (2认同)

Moe*_*tar 5

用什么语言?队列是持久的还是内存中的?

如果您在 Java 中需要这种行为,您可以使用DelayedQueue,并让一个单独的线程queue.take()在紧密循环中连续调用以排出过期的项目。queue.size()然后将为您提供队列中剩余未过期项目的大小。这要求您放入 DelayedQueue 中的项目实现Delayed接口并将值 5 分钟返回给该.getDelay()方法。