当前位置:网站首页>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
边栏推荐
- Mysql 45讲学习笔记(十一)字符串字段怎么加索引
- C实现贪吃蛇小游戏
- 4G wireless all network solar hydrological equipment power monitoring system bms110
- QT QTableWidget 表格列置顶需求的思路和代码
- ORICO ORICO outdoor power experience, lightweight and portable, the most convenient office charging station
- 2022 wechat enterprise mailbox login entry introduction, how to open and register enterprise wechat enterprise mailbox?
- Redis面试题集
- ES6 modularization
- The width of the picture in rich text used by wechat applet exceeds the problem
- Matlab remainder
猜你喜欢
随机推荐
Fast power (template)
Notes and notes
云原生——上云必读之SSH篇(常用于远程登录云服务器)
How to help others effectively
JS execution mechanism
tars源码分析之10
InputStream/OutputStream(文件的输入输出)
分布式CAP理论
tars源码分析之3
Considerations for testing a website
Can the out of sequence message complete TCP three handshakes
Uniapp custom environment variables
C realize Snake games
tcp socket 的 recv 如何接收指定长度消息?
JSON Web Token----JWT和传统session登录认证对比
[MySQL] introduction, function, creation, view, deletion and modification of database view (with exercises)
实用的小工具指令
Background and current situation of domestic CDN acceleration
Which water in the environment needs water quality monitoring
24 magicaccessorimpl can access the debugging of all methods