当前位置:网站首页>tars源码分析之4
tars源码分析之4
2022-07-04 06:33:00 【涛歌依旧】
基础buffer的实现,也很简单,大致看看:
#include "util/tc_buffer.h"
#include <iostream>
#include <algorithm>
#include <limits>
#include <cassert>
inline static std::size_t RoundUp2Power(std::size_t size)
{
if (size == 0)
return 0;
std::size_t roundUp = 1;
while (roundUp < size)
roundUp *= 2;
return roundUp;
}
namespace tars
{
const std::size_t TC_Buffer::kMaxBufferSize = std::numeric_limits<std::size_t>::max() / 2;
const std::size_t TC_Buffer::kDefaultSize = 128;
std::size_t TC_Buffer::PushData(const void* data, std::size_t size)
{
if (!data || size == 0)
return 0;
if (ReadableSize() + size >= kMaxBufferSize)
return 0; // overflow
AssureSpace(size);
::memcpy(&_buffer[_writePos], data, size);
Produce(size);
return size;
}
std::size_t TC_Buffer::PopData(void* buf, std::size_t size)
{
const std::size_t dataSize = ReadableSize();
if (!buf ||
size == 0 ||
dataSize == 0)
return 0;
if (size > dataSize)
size = dataSize; // truncate
::memcpy(buf, &_buffer[_readPos], size);
Consume(size);
return size;
}
void TC_Buffer::PeekData(void*& buf, std::size_t& size)
{
buf = ReadAddr();
size = ReadableSize();
}
void TC_Buffer::Consume(std::size_t bytes)
{
assert (_readPos + bytes <= _writePos);
_readPos += bytes;
if (IsEmpty())
Clear();
}
void TC_Buffer::AssureSpace(std::size_t needsize)
{
if (WritableSize() >= needsize)
return;
const size_t dataSize = ReadableSize();
const size_t oldCap = _capacity;
while (WritableSize() + _readPos < needsize)
{
if (_capacity < kDefaultSize)
{
_capacity = kDefaultSize;
}
else if (_capacity <= kMaxBufferSize)
{
const size_t newCapcity = RoundUp2Power(_capacity);
if (_capacity < newCapcity)
_capacity = newCapcity;
else
_capacity = 2 * newCapcity;
}
else
{
assert(false);
}
}
if (oldCap < _capacity)
{
char* tmp(new char[_capacity]);
if (dataSize != 0)
memcpy(&tmp[0], &_buffer[_readPos], dataSize);
ResetBuffer(tmp);
}
else
{
assert (_readPos > 0);
::memmove(&_buffer[0], &_buffer[_readPos], dataSize);
}
_readPos = 0;
_writePos = dataSize;
assert (needsize <= WritableSize());
}
void TC_Buffer::Shrink()
{
if (IsEmpty())
{
Clear();
_capacity = 0;
ResetBuffer();
return;
}
if (_capacity <= kDefaultSize)
return;
std::size_t oldCap = _capacity;
std::size_t dataSize = ReadableSize();
if (dataSize * 100 > oldCap * _highWaterPercent)
return;
std::size_t newCap = RoundUp2Power(dataSize);
char* tmp(new char[newCap]);
memcpy(&tmp[0], &_buffer[_readPos], dataSize);
ResetBuffer(tmp);
_capacity = newCap;
_readPos = 0;
_writePos = dataSize;
}
void TC_Buffer::Clear()
{
_readPos = _writePos = 0;
}
void TC_Buffer::Swap(TC_Buffer& buf)
{
std::swap(_readPos, buf._readPos);
std::swap(_writePos, buf._writePos);
std::swap(_capacity, buf._capacity);
std::swap(_buffer, buf._buffer);
}
void TC_Buffer::ResetBuffer(void* ptr)
{
delete[] _buffer;
_buffer = reinterpret_cast<char*>(ptr);
}
void TC_Buffer::SetHighWaterPercent(size_t percents)
{
if (percents < 10 || percents >= 100)
return;
_highWaterPercent = percents;
}
} // end namespace tars
边栏推荐
- Mysql 45讲学习笔记(十四)count(*)
- 2022.7.2-----leetcode.871
- How does apscheduler set tasks not to be concurrent (that is, execute the next task after the first one)?
- How to choose the middle-aged crisis of the testing post? Stick to it or find another way out? See below
- Uniapp custom environment variables
- Another company raised the price of SAIC Roewe new energy products from March 1
- The solution of win11 taskbar right click without Task Manager - add win11 taskbar right click function
- [March 3, 2019] MAC starts redis
- 实用的小工具指令
- QT releases multilingual International Translation
猜你喜欢
Detectron: train your own data set -- convert your own data format to coco format
Appium基础 — APPium安装(二)
Inputstream/outputstream (input and output of file)
SQL injection SQL lab 11~22
Yiwen unlocks Huawei's new cloud skills - the whole process of aiot development [device access - ESP end-to-side data collection [mqtt]- real time data analysis] (step-by-step screenshot is more detai
Download kicad on Alibaba cloud image station
测试岗的中年危机该如何选择?是坚守还是另寻出路?且看下文
雲原生——上雲必讀之SSH篇(常用於遠程登錄雲服務器)
QT qtablewidget table column top requirements ideas and codes
Practical gadget instructions
随机推荐
2022.7.3-----leetcode.556
金盾视频播放器拦截的软件关键词和进程信息
【MySQL】数据库视图的介绍、作用、创建、查看、删除和修改(附练习题)
Detailed explanation of common APIs for component and container containers: frame, panel, scrollpane
Mysql 45讲学习笔记(七)行锁
Distributed cap theory
Mysql 45讲学习笔记(十一)字符串字段怎么加索引
GoogleChromePortable 谷歌chrome浏览器便携版官网下载方式
The sorting in C language realizes the number sorting method from small to large
【无标题】
Appium foundation - appium installation (II)
STC8H开发(十二): I2C驱动AT24C08,AT24C32系列EEPROM存储
Webrtc quickly set up video call and video conference
what the fuck! If you can't grab it, write it yourself. Use code to realize a Bing Dwen Dwen. It's so beautiful ~!
Common usage of time library
Average two numbers
What is the sheji principle?
MySQL installation and configuration
Software keywords and process information intercepted by Golden Shield video player
内卷怎么破?