你将如何code的高效循环缓冲在Java或C# [英] How would you code an efficient Circular Buffer in Java or C#

查看:119
本文介绍了你将如何code的高效循环缓冲在Java或C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要一个简单的类,它实现一个固定大小的循环缓冲区。它应该是有效的,容易对眼睛,一般类型。

I want a simple class that implements a fixed-size circular buffer. It should be efficient, easy on the eyes, generically typed.

编辑:它不需要MT-能力,现在是这样。我总是可以稍后再添加一个锁,它不会是高并发在任何情况下。

It need not be MT-capable, for now. I can always add a lock later, it won't be high-concurrency in any case.

方法应该是:。新增和我猜的.List,在那里我检索所有条目。关于第二个想法,我检索认为应该通过索引器来完成。在任何时候,我会希望能够按索引检索缓冲区中的任何元素。但请记住,从一个时刻到下一个元素[n]的可能是不同的,作为循环缓冲区填满,然后返回。

Methods should be: .Add and I guess .List, where I retrieve all the entries. On second thought, Retrieval I think should be done via an indexer. At any moment I will want to be able to retrieve any element in the buffer by index. But keep in mind that from one moment to the next Element[n] may be different, as the Circular buffer fills up and rolls over.

这不是堆叠,这是一个循环缓冲器。关于溢出:我预计国内将有数组持有的项目,随着时间的推移缓冲区的头部和尾部将围绕固定阵列旋转。但是,应该是从用户看不到的。应该没有外部探测溢出事件或行为。

This isn't a stack, it's a circular buffer. Regarding "overflow": I would expect internally there would be an array holding the items, and over time the head and tail of the buffer will rotate around that fixed array. But that should be invisible from the user. There should be no externally-detectable "overflow" event or behavior.

这不是一个作业 - 它是最常见的将要被用于MRU缓存或固定大小的事务或事件日志

This is not a school assignment - it is most commonly going to be used for a MRU cache or a fixed-size transaction or event log.

推荐答案

我会用T,头和尾指针数组,并添加和get方法。

I would use an array of T, a head and tail pointer, and add and get methods.

我爱:(错误狩猎留给用户)

Like: (Bug hunting is left to the user)

// 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();
    }
  }
}

这篇关于你将如何code的高效循环缓冲在Java或C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆