当前位置:网站首页>Tar source code analysis Part 3
Tar source code analysis Part 3
2022-07-04 06:37:00 【Tao song remains the same】
buffer pool The implementation of the , It's also very classic :
#include "util/tc_buffer_pool.h"
#include <cassert>
#include <sstream>
#include <iomanip>
inline static std::size_t RoundUp2Power(std::size_t size)
{
if (size == 0)
return 0;
size_t roundUp = 1;
while (roundUp < size)
roundUp *= 2;
return roundUp;
}
namespace tars
{
TC_Slice::TC_Slice(void* d, size_t dl, size_t l) :
data(d),
dataLen(dl),
len(l)
{
}
TC_BufferPool::TC_BufferPool(size_t minBlock, size_t maxBlock) :
_minBlock(RoundUp2Power(minBlock)),
_maxBlock(RoundUp2Power(maxBlock)),
_maxBytes(1024 * 1024), // pool The allocated memory cannot exceed it , Otherwise directly new and delete, Avoid using too much memory
_totalBytes(0) // pool Memory in
{
/*
* minBlock It means that we should pool Responsible for the minimum memory allocation , Rounding up , such as 20 byte , Rounding off 32
* maxBlock It means that we should pool The maximum memory allocation for which you are responsible , Rounding up , such as 1000 byte , Rounding off 1024
* listCount It's calculation buffer Number of linked lists , such as minBlock yes 32,maxBlock yes 64, Then only two linked lists are needed
*/
size_t listCount = 0;
size_t testVal = _minBlock;
while (testVal <= _maxBlock)
{
testVal *= 2;
++ listCount;
}
assert (listCount > 0);
_buffers.resize(listCount);
}
TC_BufferPool::~TC_BufferPool()
{
std::vector<BufferList>::iterator it(_buffers.begin());
for (; it != _buffers.end(); ++ it)
{
BufferList& blist = *it;
BufferList::iterator bit(blist.begin());
for ( ; bit != blist.end(); ++ bit)
{
//delete[] (*bit);
delete[] reinterpret_cast<char*>(*bit);
}
}
}
TC_Slice TC_BufferPool::Allocate(size_t size)
{
TC_Slice s;
size = RoundUp2Power(size);
if (size == 0)
return s;
if (size < _minBlock || size > _maxBlock)
{
// Not to return pool management , direct new
s.data = new char[size];
s.len = size;
}
else
{
// Positioning to specific buffer Linked list
BufferList& blist = _GetBufferList(size);
s = _Allocate(size, blist);
}
return s;
}
void TC_BufferPool::Deallocate(TC_Slice s)
{
if (s.len < _minBlock || s.len > _maxBlock)
{
// Not to return pool management , direct delete
delete[] reinterpret_cast<char*>(s.data);
}
else if (_totalBytes >= _maxBytes)
{
// Too much memory , Don't give it back pool
delete[] reinterpret_cast<char*>(s.data);
}
else
{
// give back pool
BufferList& blist = _GetBufferList(s.len);
blist.push_back(s.data);
_totalBytes += s.len;
}
}
void TC_BufferPool::SetMaxBytes(size_t bytes)
{
_maxBytes = bytes;
}
size_t TC_BufferPool::GetMaxBytes() const
{
return _maxBytes;
}
std::string TC_BufferPool::DebugPrint() const
{
std::ostringstream oss;
oss << "\n===============================================================\n";
oss << "============ BucketCount " << std::setiosflags(std::ios::left) << std::setw(4) << _buffers.size() << " ================================" << std::endl;
oss << "============ PoolBytes " << std::setw(10) << _totalBytes << " ============================" << std::endl;
int bucket = 0;
size_t size = _minBlock;
std::vector<BufferList>::const_iterator it(_buffers.begin());
for (; it != _buffers.end(); ++ it)
{
const BufferList& blist = *it;
oss << "== Bucket " << std::setw(3) << bucket
<< ": BlockSize " << std::setw(8) << size
<< " Remain blocks " << std::setw(6) << blist.size()
<< " ======== \n";
++ bucket;
size *= 2;
}
return oss.str();
}
TC_Slice TC_BufferPool::_Allocate(size_t size, BufferList& blist)
{
assert ((size & (size - 1)) == 0);
TC_Slice s;
s.len = size;
if (blist.empty())
{
s.data = new char[size];
}
else
{
// Take it directly from the linked list buffer
s.data = *blist.begin();
blist.pop_front();
_totalBytes -= s.len;
}
return s;
}
TC_BufferPool::BufferList& TC_BufferPool::_GetBufferList(size_t s)
{
const BufferList& blist = const_cast<const TC_BufferPool& >(*this)._GetBufferList(s);
return const_cast<BufferList& >(blist);
}
const TC_BufferPool::BufferList& TC_BufferPool::_GetBufferList(size_t s) const
{
assert ((s & (s - 1)) == 0);
assert (s >= _minBlock && s <= _maxBlock);
size_t index = _buffers.size();
size_t testVal = s;
while (testVal <= _maxBlock)
{
testVal *= 2;
index --;
}
return _buffers[index];
}
} // end namespace tars
边栏推荐
- tars源码分析之2
- Wechat applet scroll view component scrollable view area
- tcp socket 的 recv 如何接收指定长度消息?
- uniapp 自定義環境變量
- Uniapp custom environment variables
- C语言中的排序,实现从小到大的数字排序法
- uniapp 自定义环境变量
- 金盾视频播放器拦截的软件关键词和进程信息
- Cloud native - SSH article that must be read on the cloud (commonly used for remote login to ECS)
- How to implement cross domain requests
猜你喜欢
InputStream/OutputStream(文件的输入输出)
《ClickHouse原理解析与应用实践》读书笔记(4)
C實現貪吃蛇小遊戲
How does apscheduler set tasks not to be concurrent (that is, execute the next task after the first one)?
17-18. Dependency scope and life cycle plug-ins
分布式CAP理论
C language - Blue Bridge Cup - Snake filling
MySQL learning notes 3 - JDBC
27-31. Dependency transitivity, principle
24 magicaccessorimpl can access the debugging of all methods
随机推荐
Dimension and format of data
Mysql 45讲学习笔记(七)行锁
Arcpy uses the updatelayer function to change the symbol system of the layer
【MySQL】数据库视图的介绍、作用、创建、查看、删除和修改(附练习题)
2022 wechat enterprise mailbox login entry introduction, how to open and register enterprise wechat enterprise mailbox?
tars源码分析之3
微信小程序使用rich-text中图片宽度超出问题
uniapp 自定義環境變量
Internet of things protocol ZigBee ZigBee module uses the concept of protocol stack
C language exercises (recursion)
tars源码分析之6
regular expression
24 magicaccessorimpl can access the debugging of all methods
How to realize multi account login of video platform members
4G wireless all network solar hydrological equipment power monitoring system bms110
Understanding of cross domain and how to solve cross domain problems
SQL injection SQL lab 11~22
Tsinghua University product: penalty gradient norm improves generalization of deep learning model
2022.7.2-----leetcode. eight hundred and seventy-one
Matlab remainder