ringbuf

读写安全的环状buffer。

源码链接:https://github.com/SaberMqd/naive/blob/master/include/naive/ring_buffer.h

#ifndef _NAIVE_RINGBUF_H_
#define _NAIVE_RINGBUF_H_

#include <cstring>
#include <cstdint>

#include "safe_delete.h"
#include "base_constructor.h"

namespace naive {

template <typename T>
class RingBuf {

public:

	explicit RingBuf(uint32_t len):
		_len(len+1),_beg(0),_end(0) {
		_buf = new T[_len]{ 0 };
	}

	void Reset() {
		_beg = 0;
		_end = 0;
		memset(_buf, 0, _len * sizeof(T));
	}

	bool Push(const T* in_buf, uint32_t len) {
		if (len > GetSpareLen()) {
			return false;
		}
		if (_beg > _end) {
			if (_beg - _end ==1){
				return false;
			}
			_end += len;
			memcpy(_buf + _end, in_buf, len * sizeof(T));
		} else {//_beg <= _end
			uint32_t afterLen = _len - _end;
			if (afterLen > len) {//
				memcpy(_buf + _end, in_buf, len * sizeof(T));
				_end += len;
			} else {
				memcpy(_buf + _end, in_buf, afterLen * sizeof(T));
				uint32_t frontLen = len - afterLen;
				_end = frontLen ;//
				memcpy(_buf, in_buf + afterLen, frontLen * sizeof(T));
			}
		}
		return true;
	}

	T* Pop(uint32_t len) {
		if ((_len -1 - GetSpareLen()) < len) {//
			return nullptr;
		}
		T* tempBuf = new T[len];
		if (_beg > _end) {
			uint32_t afterLen = _len - _beg - 1;
			if (afterLen > len) {//
				memcpy(tempBuf, _buf + _beg, len * sizeof(T));
				_beg += len;
				return tempBuf;
			}
			memcpy(tempBuf, _buf + _beg, afterLen * sizeof(T));
			uint32_t frontLen = len - afterLen;
			memcpy(tempBuf + afterLen, _buf, frontLen * sizeof(T));
			_beg = frontLen;
		} else {
			memcpy(tempBuf, _buf + _beg, len * sizeof(T));
			_beg += len;
		}
		return tempBuf;
	}

	bool Pop(T* in_buf, uint32_t len) {		
		if ((_len - 1 - GetSpareLen()) < len) {//
			return false;
		}
		if (_beg > _end) {
			uint32_t afterLen = _len - _beg;
			if (afterLen > len) {//
				memcpy(in_buf, _buf + _beg, len * sizeof(T));
				_beg += len;
				return true;
			}
			memcpy(in_buf, _buf + _beg, afterLen * sizeof(T));
			uint32_t frontLen = len - afterLen;
			memcpy(in_buf + afterLen, _buf, frontLen * sizeof(T));
			_beg = frontLen;
		}
		else {
			memcpy(in_buf, _buf + _beg, len * sizeof(T));
			_beg += len;
		}
		return true;
	}

	uint32_t TryPop(T* in_buf, uint32_t len) {
		const uint32_t contentLen = (_len - 1 - GetSpareLen());//
		if (contentLen < len) {
			Pop(in_buf, contentLen);
			return contentLen;		
		}
		Pop(in_buf, len);
		return len;
	}

	uint32_t Size() {
		return _len - 1 - GetSpareLen();
	}

	bool PushBack(const T* in_buf, uint32_t len) {
		if (len > GetSpareLen()) {
			return false;
		}
		if (_beg > _end) {
			_beg -= len;
			memcpy(_buf + _beg, in_buf, len * sizeof(T));
		}else {//_beg<=_end
			if (_beg >= len) {
				_beg -= len;
				memcpy(_buf + _beg, in_buf, len * sizeof(T));
			}else {
				uint32_t frontLen = len - _beg;
				memcpy(_buf + (_len - frontLen), in_buf, frontLen * sizeof(T));
				memcpy(_buf, in_buf + _beg, _beg * sizeof(T));//
				_beg = _len - frontLen;
			}
		}
		return true;
	}

	bool PopBack(T* in_buf, uint32_t len) {
		if ((_len - 1 - GetSpareLen()) < len) {//
			return false;
		}
		if (_beg > _end) {
			if (len <= _end) {
				memcpy(in_buf, _buf + (_end - len), len * sizeof(T));
				_end -= len;
				return true;
			}
			uint32_t frontLen = len - _end;
			memcpy(in_buf, _buf + (_len - frontLen), frontLen * sizeof(T));
			memcpy(in_buf + frontLen, _buf, _end * sizeof(T));
			_end = (_len - frontLen);
		}else {
			if (_beg == _end) {
				return false;
			}
			memcpy(in_buf, _buf + (_end - len), len * sizeof(T));//
			_end -= len;
		}
		return true;
	}

	uint32_t TryPopBack(T* in_buf, uint32_t len) {
		const uint32_t contentLen = (_len - 1 - GetSpareLen());//
		if (contentLen < len) {
			PopBack(in_buf, contentLen);
			return contentLen;
		}
		PopBack(in_buf, len);
		return len;
	}

	~RingBuf() {
		SafeDeleteArray(_buf);
	}

private:

	uint32_t _beg;
	uint32_t _end;
	uint32_t _len;
	T*      _buf;

	uint32_t GetSpareLen() const {
		if (_beg < _end){
			return (_len - (_end - _beg) - 1);
		} else if (_beg > _end) {
			return (_beg - _end - 1);
		} else {
			return _len - 1;//
		}
	}
	DISALLOW_COPY_AND_ASSIGN(RingBuf)
};

}

#endif

 

好的,下面是一个简单的环形缓冲区(Ring Buffer)的示例代码: ```c #include <stdio.h> #include <stdlib.h> typedef struct { int* buffer; int size; int front; int rear; } RingBuffer; RingBuffer* createRingBuffer(int size) { RingBuffer* rb = (RingBuffer*)malloc(sizeof(RingBuffer)); rb->buffer = (int*)malloc(size * sizeof(int)); rb->size = size; rb->front = 0; rb->rear = 0; return rb; } void destroyRingBuffer(RingBuffer* rb) { free(rb->buffer); free(rb); } void enqueue(RingBuffer* rb, int data) { if ((rb->rear + 1) % rb->size == rb->front) { printf("Ring Buffer is full. Unable to enqueue.\n"); return; } rb->buffer[rb->rear] = data; rb->rear = (rb->rear + 1) % rb->size; } int dequeue(RingBuffer* rb) { if (rb->front == rb->rear) { printf("Ring Buffer is empty. Unable to dequeue.\n"); return -1; // or any other value to indicate error } int data = rb->buffer[rb->front]; rb->front = (rb->front + 1) % rb->size; return data; } int main() { RingBuffer* rb = createRingBuffer(5); enqueue(rb, 10); enqueue(rb, 20); enqueue(rb, 30); enqueue(rb, 40); enqueue(rb, 50); printf("Dequeued: %d\n", dequeue(rb)); printf("Dequeued: %d\n", dequeue(rb)); enqueue(rb, 60); enqueue(rb, 70); printf("Dequeued: %d\n", dequeue(rb)); printf("Dequeued: %d\n", dequeue(rb)); printf("Dequeued: %d\n", dequeue(rb)); printf("Dequeued: %d\n", dequeue(rb)); destroyRingBuffer(rb); return 0; } ``` 这个示例代码实现了一个固定大小的环形缓冲区(Ring Buffer),使用了数组来存储数据。其中,`createRingBuffer` 函数用于创建一个环形缓冲区,`destroyRingBuffer` 函数用于销毁缓冲区。`enqueue` 函数用于将数据入队到缓冲区,`dequeue` 函数用于将数据出队。在示例代码的 `main` 函数中,展示了如何使用环形缓冲区进行入队和出队操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值