Кольцевой буфер

Как работает кольцевой буфер

Кольцевой буфер есть массив который используется как очередь. Кольцевой буфер читает с позиции и пишет в позицию которая отмечена следующей позицией для чтения из и записи в кольцевой буфер. Когда позиция записи подошла к концу массива то пишущая позиция установливается снова в 0. Тоже самое касается читающей позиции.

Установка позиции четения и записи назад в 0 когда она подходит к концу массива иногда называют "обтеканием". Это поведение которое превращает массив в кольцевой буфер. Когда позиция чтения и записи подходят к концу массива она продолжается с начала массива таким образом если бы массив был кольцом. Отсюда и название кольцевой буфер.

Этот учебник объяснит работу кольцевого буфера и покажет две его реализации.

Кольцевой буфер использующий счётчик заполнения

Один из способов чтобы следить за позицией записи, позиции чтения и количества элементов в кольцевом буфере является использование позиции записи и счётчик заполнения. Позиция записи отмечает следующую позицию в кольцевом буфере, для записи элемента. Счётчик заполнения показывает, сколько элементов в настоящее время сохранено в буфере.


				public class RingBufferFillCount {
    public Object[] elements = null;

    private int capacity  = 0;
    private int writePos  = 0;
    private int available = 0;

    public QueueFillCount(int capacity) {
        this.capacity = capacity;
        this.elements = new Object[capacity];
    }

    public void reset() {
        this.writePos = 0;
        this.available = 0;
    }

    public int capacity() { return this.capacity; }
    public int available(){ return this.available; }

    public int remainingCapacity() {
        return this.capacity - this.available;
    }

    public boolean put(Object element){

        if(available < capacity){
            if(writePos >= capacity){
                writePos = 0;
            }
            elements[writePos] = element;
            writePos++;
            available++;
            return true;
        }

        return false;
    }

    public Object take() {
        if(available == 0){
            return null;
        }
        int nextSlot = writePos - available;
        if(nextSlot < 0){
            nextSlot += capacity;
        }
        Object nextObj = elements[nextSlot];
        available--;
        return nextObj;
    }
}
				

Переведен отрывок с сайта jenkov.com