我想存储在一个队列中,数据结构无关紧要,只有我插入的元素说的是从当前时间开始的最后5分钟。任何旧的都应该被删除 - 这样每当我得到队列的大小时,它将给出在最后5分钟插入的对象的数量。
基本上,我必须知道的是,在下一次通话之前,我的应用程序在过去5分钟内对服务器进行了多少次http呼叫。
如果有人知道可能有此实现的现有库,请分享。
答案 0 :(得分: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();
}
}
答案 1 :(得分:4)
用什么语言?队列是持久的还是内存的?
如果您在Java中需要此行为,则可以使用DelayedQueue,并在紧密循环中连续调用queue.take()
以排出过期项目。然后,queue.size()
将为您提供队列中剩余未到期项目的大小。这要求您在DelayedQueue中放置的项目实现Delayed接口,并将值返回到.getDelay()
方法的5分钟。
答案 2 :(得分:0)
我已经实现了FadingLinkedList
之类的
public class FadingLinkedList<E> {
private transient Entry<E> header = new Entry<E>(null, null);
/**
* ms
*/
private long livingTime;
/**
* Constructs FadingLinkedList with elements of living time livingTime in
* milliseconds
*/
public FadingLinkedList(long livingTime) {
this.livingTime = livingTime;
}
/**
* remove all faded elements,
*
* @return the count of not faded
*/
public synchronized int removeFaded() {
long now = System.nanoTime();
int count = 0;
Entry<E> prev = header;// the last living Entry in the loop
for (Entry<E> e = header.next; e != null; e = e.next) {
if (TimeUnit.NANOSECONDS.toMillis(now - e.birthTime) >= livingTime) {
// cut off this list here.
prev.next = null;
break;
}
count++;
prev = e;
}
return count;
}
/**
* Returns the number of elements that not faded.
*/
public int size() {
return removeFaded();
}
public synchronized void push(E e) {
Entry<E> newEntry = new Entry<E>(e, header.next);
header.next = newEntry;
}
private static class Entry<E> {
E element;
Entry<E> next;
long birthTime;
Entry(E element, Entry<E> next) {
this.element = element;
this.next = next;
this.birthTime = System.nanoTime();
}
}
public synchronized void clear() {
header.next = null;
}
public synchronized int getAndClear() {
int size = size();
clear();
return size;
}
}