关键词搜索

源码搜索 ×
×

tars源码分析之4

发布2022-07-03浏览423次

详情内容

基础buffer的实现,也很简单,大致看看:

  1. #include "util/tc_buffer.h"
  2. #include <iostream>
  3. #include <algorithm>
  4. #include <limits>
  5. #include <cassert>
  6. inline static std::size_t RoundUp2Power(std::size_t size)
  7. {
  8. if (size == 0)
  9. return 0;
  10. std::size_t roundUp = 1;
  11. while (roundUp < size)
  12. roundUp *= 2;
  13. return roundUp;
  14. }
  15. namespace tars
  16. {
  17. const std::size_t TC_Buffer::kMaxBufferSize = std::numeric_limits<std::size_t>::max() / 2;
  18. const std::size_t TC_Buffer::kDefaultSize = 128;
  19. std::size_t TC_Buffer::PushData(const void* data, std::size_t size)
  20. {
  21. if (!data || size == 0)
  22. return 0;
  23. if (ReadableSize() + size >= kMaxBufferSize)
  24. return 0; // overflow
  25. AssureSpace(size);
  26. ::memcpy(&_buffer[_writePos], data, size);
  27. Produce(size);
  28. return size;
  29. }
  30. std::size_t TC_Buffer::PopData(void* buf, std::size_t size)
  31. {
  32. const std::size_t dataSize = ReadableSize();
  33. if (!buf ||
  34. size == 0 ||
  35. dataSize == 0)
  36. return 0;
  37. if (size > dataSize)
  38. size = dataSize; // truncate
  39. ::memcpy(buf, &_buffer[_readPos], size);
  40. Consume(size);
  41. return size;
  42. }
  43. void TC_Buffer::PeekData(void*& buf, std::size_t& size)
  44. {
  45. buf = ReadAddr();
  46. size = ReadableSize();
  47. }
  48. void TC_Buffer::Consume(std::size_t bytes)
  49. {
  50. assert (_readPos + bytes <= _writePos);
  51. _readPos += bytes;
  52. if (IsEmpty())
  53. Clear();
  54. }
  55. void TC_Buffer::AssureSpace(std::size_t needsize)
  56. {
  57. if (WritableSize() >= needsize)
  58. return;
  59. const size_t dataSize = ReadableSize();
  60. const size_t oldCap = _capacity;
  61. while (WritableSize() + _readPos < needsize)
  62. {
  63. if (_capacity < kDefaultSize)
  64. {
  65. _capacity = kDefaultSize;
  66. }
  67. else if (_capacity <= kMaxBufferSize)
  68. {
  69. const size_t newCapcity = RoundUp2Power(_capacity);
  70. if (_capacity < newCapcity)
  71. _capacity = newCapcity;
  72. else
  73. _capacity = 2 * newCapcity;
  74. }
  75. else
  76. {
  77. assert(false);
  78. }
  79. }
  80. if (oldCap < _capacity)
  81. {
  82. char* tmp(new char[_capacity]);
  83. if (dataSize != 0)
  84. memcpy(&tmp[0], &_buffer[_readPos], dataSize);
  85. ResetBuffer(tmp);
  86. }
  87. else
  88. {
  89. assert (_readPos > 0);
  90. ::memmove(&_buffer[0], &_buffer[_readPos], dataSize);
  91. }
  92. _readPos = 0;
  93. _writePos = dataSize;
  94. assert (needsize <= WritableSize());
  95. }
  96. void TC_Buffer::Shrink()
  97. {
  98. if (IsEmpty())
  99. {
  100. Clear();
  101. _capacity = 0;
  102. ResetBuffer();
  103. return;
  104. }
  105. if (_capacity <= kDefaultSize)
  106. return;
  107. std::size_t oldCap = _capacity;
  108. std::size_t dataSize = ReadableSize();
  109. if (dataSize * 100 > oldCap * _highWaterPercent)
  110. return;
  111. std::size_t newCap = RoundUp2Power(dataSize);
  112. char* tmp(new char[newCap]);
  113. memcpy(&tmp[0], &_buffer[_readPos], dataSize);
  114. ResetBuffer(tmp);
  115. _capacity = newCap;
  116. _readPos = 0;
  117. _writePos = dataSize;
  118. }
  119. void TC_Buffer::Clear()
  120. {
  121. _readPos = _writePos = 0;
  122. }
  123. void TC_Buffer::Swap(TC_Buffer& buf)
  124. {
  125. std::swap(_readPos, buf._readPos);
  126. std::swap(_writePos, buf._writePos);
  127. std::swap(_capacity, buf._capacity);
  128. std::swap(_buffer, buf._buffer);
  129. }
  130. void TC_Buffer::ResetBuffer(void* ptr)
  131. {
  132. delete[] _buffer;
  133. _buffer = reinterpret_cast<char*>(ptr);
  134. }
  135. void TC_Buffer::SetHighWaterPercent(size_t percents)
  136. {
  137. if (percents < 10 || percents >= 100)
  138. return;
  139. _highWaterPercent = percents;
  140. }
  141. } // end namespace tars

相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载