一:RingBuffer主要的成员变量
typename RingStorage::Ptr _storage;
typename RingDelegate<T>::Ptr _delegate;
onReaderChanged _on_reader_changed;
unordered_map<EventPoller::Ptr, typename RingReaderDispatcher::Ptr, HashOfPtr> _dispatcher_map;
1.1 _storage
是一个_RingStorage类,存储的容器为list,容器存储的是一帧数据,作用是存储一组GOP数据,遇到I帧则从新缓存
定义如下:
List<pair<bool, T> > _data_cache;
1.2 _delegate
是一个 RingDelegate类,通过setDelegate赋值,代理定义如下,显然RingDelegate是通过onWrite将数据转发出去
template<typename T>
class RingDelegate {
public:
typedef std::shared_ptr<RingDelegate> Ptr;
RingDelegate() {}
virtual ~RingDelegate() {}
virtual void onWrite(T in, bool is_key = true) = 0;
};
1.3 _dispatcher_map
_dispatcher_map 的申明
unordered_map<EventPoller::Ptr, typename RingReaderDispatcher::Ptr, HashOfPtr> _dispatcher_map;
typedef _RingReaderDispatcher<T> RingReaderDispatcher;
_dispatcher_map 数据的增加
通过attach为_dispatcher_map(RingReaderDispatcher)增加读取类RingReader
std::shared_ptr<RingReader> attach(const EventPoller::Ptr &poller, bool use_cache) {
if (!poller->isCurrentThread()) {
throw std::runtime_error("必须在绑定的poller线程中执行attach操作");
}
weak_ptr<_RingReaderDispatcher> weakSelf = this->shared_from_this();
auto on_dealloc = [weakSelf, poller](RingReader *ptr) {
poller->async([weakSelf, ptr]() {
auto strongSelf = weakSelf.lock();
if (strongSelf && strongSelf->_reader_map.erase(ptr)) {
--strongSelf->_reader_size;
strongSelf->onSizeChanged(false);
}
delete ptr;
});
};
std::shared_ptr<RingReader> reader(new RingReader(_storage, use_cache), on_dealloc);
_reader_map[reader.get()] = std::move(reader);
++_reader_size;
onSizeChanged(true);
return reader;
}
_dispatcher_map 数据的读取(分发)
_RingReaderDispatcher里包含了一个键值对_reader_map,分发对象都会存储在这里,定义如下
unordered_map<void *, std::weak_ptr<RingReader>> _reader_map;
数据读取是通过RingReader去处理
typedef _RingReader<T> RingReader;
_RingReader定义如下,通过onRead调用了_read_cb将数据回调出去,而_read_cb通过setReadCB设置
/**
* 环形缓存读取器
* 该对象的事件触发都会在绑定的poller线程中执行
* 所以把锁去掉了
* 对该对象的一切操作都应该在poller线程中执行
* @tparam T
*/
template<typename T>
class _RingReader {
public:
void setReadCB(const function<void(const T &)> &cb) {
if (!cb) {
_read_cb = [](const T &) {};
} else {
_read_cb = cb;
flushGop();
}
}
......
private:
void onRead(const T &data, bool is_key) {
_read_cb(data);
}
......
void flushGop() {
if (!_use_cache) {
return;
}
_storage->getCache().for_each([&](const pair<bool, T> &pr) {
onRead(pr.second, pr.first);
});
}
......
};
二:数据写入
很显然数据通过遍历_dispatcher_map去处理,最终都是_RingReader去处理,而_RingReader最终数据都会通过_read_cb回调出去
void write(T in, bool is_key = true) {
if (_delegate) {
_delegate->onWrite(std::move(in), is_key);
return;
}
LOCK_GUARD(_mtx_map);
for (auto &pr : _dispatcher_map) {
auto &second = pr.second;
//切换线程后触发onRead事件
pr.first->async([second, in, is_key]() {
second->write(std::move(const_cast<T &>(in)), is_key);
}, false);
}
_storage->write(std::move(in), is_key);
}
总结:
使用RingBuffer时数据通过write写入(这里是异步写入),通过write接口写入数据
通过attach将读取器(_RingReader)添加进RingBuffer的分发map,此时attach接口返回一个RingReader,通过返回的RingReader调用setReadCB设置回调函数将数据拿到
template<typename T>
class RingBuffer : public enable_shared_from_this<RingBuffer<T> > {
public:
typedef std::shared_ptr<RingBuffer> Ptr;
typedef _RingReader<T> RingReader;
typedef _RingStorage<T> RingStorage;
typedef _RingReaderDispatcher<T> RingReaderDispatcher;
typedef function<void(int size)> onReaderChanged;
RingBuffer(int max_size = 1024, const onReaderChanged &cb = nullptr) {
_on_reader_changed = cb;
_storage = std::make_shared<RingStorage>(max_size);
}
~RingBuffer() {}
void write(T in, bool is_key = true);
std::shared_ptr<RingReader> attach(const EventPoller::Ptr &poller, bool use_cache = true);
};