Skip to content

Instantly share code, notes, and snippets.

@shijinkui
Created November 13, 2013 14:56
Show Gist options
  • Save shijinkui/7450396 to your computer and use it in GitHub Desktop.
Save shijinkui/7450396 to your computer and use it in GitHub Desktop.
ringbuffer,entry中是ConcurrentLinkedQueue<LogEntry>, 用于缓存scribelog,满了就批量发出去
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