当前位置:网站首页>tars源码分析之3
tars源码分析之3
2022-07-04 06:33:00 【涛歌依旧】
buffer pool的实现,也非常经典:
#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所分配的内存不能超过它,否则直接new和delete,避免占用过高内存
_totalBytes(0) // pool中的内存
{
/*
* minBlock表示该pool所负责的最小内存分配,向上取整,比如20字节,取整为32
* maxBlock表示该pool所负责的最大内存分配,向上取整,比如1000字节,取整为1024
* listCount是计算buffer链表的数量,比如minBlock是32,maxBlock是64,那么只需要两个链表
*/
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)
{
// 不归pool管理,直接new
s.data = new char[size];
s.len = size;
}
else
{
// 定位到具体的buffer链表
BufferList& blist = _GetBufferList(size);
s = _Allocate(size, blist);
}
return s;
}
void TC_BufferPool::Deallocate(TC_Slice s)
{
if (s.len < _minBlock || s.len > _maxBlock)
{
// 不归pool管理,直接delete
delete[] reinterpret_cast<char*>(s.data);
}
else if (_totalBytes >= _maxBytes)
{
// 占用内存过多,就不还给pool
delete[] reinterpret_cast<char*>(s.data);
}
else
{
// 还给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
{
// 直接从链表中取出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
边栏推荐
- 实用的小工具指令
- Fundamentals of SQL database operation
- C realize Snake games
- 1、 Relevant theories and tools of network security penetration testing
- CORS is not intended to protect API endpoints - nikofischer
- QT QTableWidget 表格列置顶需求的思路和代码
- Tf/pytorch/cafe-cv/nlp/ audio - practical demonstration of full ecosystem CPU deployment - Intel openvino tool suite course summary (Part 2)
- STC8H开发(十二): I2C驱动AT24C08,AT24C32系列EEPROM存储
- Arcpy uses the updatelayer function to change the symbol system of the layer
- 24 magicaccessorimpl can access the debugging of all methods
猜你喜欢

P26-P34 third_ template

740. Delete and get points
![[Android reverse] function interception (CPU cache mechanism | CPU cache mechanism causes function interception failure)](/img/7e/02bb01480257cd56537914a7247733.jpg)
[Android reverse] function interception (CPU cache mechanism | CPU cache mechanism causes function interception failure)

C language - Blue Bridge Cup - Snake filling

R统计绘图-随机森林分类分析及物种丰度差异检验组合图

Bicolor case

Json Web token - jwt vs. Traditional session login Authentication

regular expression

List of top ten professional skills required for data science work

Notes and notes
随机推荐
740. Delete and get points
R statistical mapping - random forest classification analysis and species abundance difference test combination diagram
Functions in C language (detailed explanation)
Displaying currency in Indian numbering format
Background and current situation of domestic CDN acceleration
C實現貪吃蛇小遊戲
ORICO ORICO outdoor power experience, lightweight and portable, the most convenient office charging station
如何避免 JVM 内存泄漏?
颈椎、脚气
Invalid revision: 3.18.1-g262b901-dirty
C语言中的排序,实现从小到大的数字排序法
ES6 modularization
Variables d'environnement personnalisées uniapp
JSON web token -- comparison between JWT and traditional session login authentication
Arcpy uses the updatelayer function to change the symbol system of the layer
7. Agency mode
uniapp 自定義環境變量
《ClickHouse原理解析与应用实践》读书笔记(4)
【无标题】
Another company raised the price of SAIC Roewe new energy products from March 1