当前位置:网站首页>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
边栏推荐
- what the fuck! If you can't grab it, write it yourself. Use code to realize a Bing Dwen Dwen. It's so beautiful ~!
- Notes and notes
- Variables d'environnement personnalisées uniapp
- 24 magicaccessorimpl can access the debugging of all methods
- C réaliser des jeux de serpents gourmands
- 【问题记录】03 连接MySQL数据库提示:1040 Too many connections
- What is the sheji principle?
- Arcpy uses the updatelayer function to change the symbol system of the layer
- ABAP:OOALV实现增删改查功能
- [backpack DP] backpack problem
猜你喜欢
随机推荐
R statistical mapping - random forest classification analysis and species abundance difference test combination diagram
List of top ten professional skills required for data science work
QT releases multilingual International Translation
Inputstream/outputstream (input and output of file)
Another company raised the price of SAIC Roewe new energy products from March 1
Common JS tool Libraries
如何实现视频平台会员多账号登录
Explain in one sentence what social proof is
Redis面试题集
Distributed cap theory
4G wireless all network solar hydrological equipment power monitoring system bms110
ES6 modularization
Which water in the environment needs water quality monitoring
2022.7.3-----leetcode.556
Tsinghua University product: penalty gradient norm improves generalization of deep learning model
C réaliser des jeux de serpents gourmands
MySQL installation and configuration
740. Delete and get points
leetcode 310. Minimum Height Trees
雲原生——上雲必讀之SSH篇(常用於遠程登錄雲服務器)






![[March 3, 2019] MAC starts redis](/img/ff/88638fcdc8d24dc268781c224e8195.jpg)

