Created
November 13, 2013 14:56
-
-
Save shijinkui/7450396 to your computer and use it in GitHub Desktop.
ringbuffer,entry中是ConcurrentLinkedQueue<LogEntry>, 用于缓存scribelog,满了就批量发出去
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.twitter.common.logging; | |
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.concurrent.atomic.AtomicReferenceArray; | |
/** | |
* ringbuffer | |
* <pre> | |
* tail | |
* | | |
* v | |
* +---+ +---+ +---+ +---+ | |
* <---| |--->| |-H->| |--->| |---> | |
* --->| |<---| |<---| |<---| |<--- | |
* +---+ +---+ +---+ +---+ | |
* </pre> | |
* User: shijinkui | |
* Date: 13-9-16 | |
* Time: 下午1:59 | |
* To change this template use File | Settings | File Templates. | |
*/ | |
public class RingBuffer<E> { | |
private final int capacity; | |
private final AtomicReferenceArray<Entry<E>> data; | |
private Entry<E> head = null; | |
public RingBuffer(int fixedCapacity) { | |
this.capacity = fixedCapacity; | |
this.data = new AtomicReferenceArray<Entry<E>>(capacity); | |
initData(); | |
} | |
private synchronized void initData() { | |
for (int i = 0; i < capacity; i++) { | |
Entry<E> entry = new Entry<E>(i); | |
data.set(i, entry); | |
} | |
for (int i = 0; i < capacity; i++) { | |
Entry<E> entry = data.get(i); | |
if (i == capacity - 1) { | |
entry.setFront(data.get(0)); | |
} else { | |
Entry<E> front = data.get(i + 1); | |
entry.setFront(front); | |
} | |
} | |
this.head = data.get(0); | |
} | |
public void initList(E[] obj) { | |
for (int i = 0; i < data.length(); i++) { | |
data.get(i).setData(obj[i]); | |
} | |
} | |
public void add(E element) { | |
head.setData(element); | |
head = head.front; | |
} | |
public synchronized void moveIdx() { | |
head = head.front; | |
} | |
public int getIndex(E e) { | |
int len = data.length(); | |
for (int i = 0; i < len; i++) { | |
// value is equal or referance is the same obj | |
E tmp = data.get(i).getData(); | |
if (e.equals(tmp) || e == tmp) { | |
return i; | |
} | |
} | |
return -1; | |
} | |
public List<E> getList(int limit) { | |
final int from = head.getOffset(); | |
limit = limit > capacity ? capacity : limit; | |
limit = limit > 0 ? limit : data.length(); | |
ArrayList<E> list = new ArrayList<E>(limit); | |
int end = data.length() - from; | |
for (int i = from; i < end; i++) { | |
list.add(data.get(i).getData()); | |
} | |
System.out.println("get list: " + limit); | |
return list; | |
} | |
public E getHead() { | |
return head.getData(); | |
} | |
public int getOffset() { | |
return head.getOffset(); | |
} | |
private class Entry<E> { | |
//数组中的偏移量, 取列表的时候,直接根据这个offset定位 | |
private final int offset; | |
private Entry<E> front; | |
private E data = null; | |
Entry(int offset) { | |
this.offset = offset; | |
this.front = (Entry<E>) head; | |
} | |
E getData() { | |
return data; | |
} | |
void setData(E e) { | |
this.data = e; | |
} | |
private void setFront(Entry<E> front) { | |
this.front = front; | |
} | |
private int getOffset() { | |
return offset; | |
} | |
} | |
public static void main(String... args) { | |
RingBuffer<Integer> rf = new RingBuffer<Integer>(10); | |
long ct = System.currentTimeMillis(); | |
for (int i = 0; i < 1000; i++) { | |
rf.add(i); | |
System.out.println("header ===>>>> " + rf.getHead()); | |
} | |
ct = System.currentTimeMillis() - ct; | |
System.out.println("ct:" + ct); | |
List<Integer> list = rf.getList(-1); | |
for (int obj : list) { | |
System.out.println("---- " + obj); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment