小编典典

您将如何用Java或C#编写高效的循环缓冲区?

c#

我想要一个实现固定大小的 循环缓冲区
的简单类。它应该是高效的,易于使用的,通用的类型。

目前,它不必具有MT功能。我以后总是可以添加一个锁,无论如何它都不是高并发的。

方法应该是:.Add()我猜应该在.List()哪里检索所有条目。再次考虑,我认为应该通过索引器进行检索。在任何时候,我都希望能够通过
index 检索缓冲区中的任何元素。但是请记住,从一刻到下一个Element [n]可能会有所不同,因为 圆形缓冲区会 填满并翻转。这不是 堆栈
,而是循环缓冲区。

关于“ 溢出 ”:我希望内部会有一个数组来保存这些项,并且随着时间的流逝,缓冲区的
将围绕该固定数组旋转。但这对用户来说应该是不可见的。不应存在​​外部可检测到的“溢出”事件或行为。

这不是学校的作业,而是最常用于MRU缓存或固定大小的事务或事件日志的作业。


阅读 277

收藏
2020-05-19

共1个答案

小编典典

我将使用T数组,首尾指针以及add和get方法。

像:(错误查找留给用户)

// Hijack these for simplicity
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;

public class CircularBuffer<T> {

  private T[] buffer;

  private int tail;

  private int head;

  @SuppressWarnings("unchecked")
  public CircularBuffer(int n) {
    buffer = (T[]) new Object[n];
    tail = 0;
    head = 0;
  }

  public void add(T toAdd) {
    if (head != (tail - 1)) {
        buffer[head++] = toAdd;
    } else {
        throw new BufferOverflowException();
    }
    head = head % buffer.length;
  }

  public T get() {
    T t = null;
    int adjTail = tail > head ? tail - buffer.length : tail;
    if (adjTail < head) {
        t = (T) buffer[tail++];
        tail = tail % buffer.length;
    } else {
        throw new BufferUnderflowException();
    }
    return t;
  }

  public String toString() {
    return "CircularBuffer(size=" + buffer.length + ", head=" + head + ", tail=" + tail + ")";
  }

  public static void main(String[] args) {
    CircularBuffer<String> b = new CircularBuffer<String>(3);
    for (int i = 0; i < 10; i++) {
        System.out.println("Start: " + b);
        b.add("One");
        System.out.println("One: " + b);
        b.add("Two");
        System.out.println("Two: " + b);
        System.out.println("Got '" + b.get() + "', now " + b);

        b.add("Three");
        System.out.println("Three: " + b);
        // Test Overflow
        // b.add("Four");
        // System.out.println("Four: " + b);

        System.out.println("Got '" + b.get() + "', now " + b);
        System.out.println("Got '" + b.get() + "', now " + b);
        // Test Underflow
        // System.out.println("Got '" + b.get() + "', now " + b);

        // Back to start, let's shift on one
        b.add("Foo");
        b.get();
    }
  }
}
2020-05-19