BuffersStorage.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*
  2. * This is the source code of tgnet library v. 1.1
  3. * It is licensed under GNU GPL v. 2 or later.
  4. * You should have received a copy of the license in this archive (see LICENSE).
  5. *
  6. * Copyright Nikolai Kudashov, 2015-2018.
  7. */
  8. #include "BuffersStorage.h"
  9. #include "FileLog.h"
  10. #include "NativeByteBuffer.h"
  11. BuffersStorage &BuffersStorage::getInstance() {
  12. static BuffersStorage instance(true);
  13. return instance;
  14. }
  15. BuffersStorage::BuffersStorage(bool threadSafe) {
  16. isThreadSafe = threadSafe;
  17. if (isThreadSafe) {
  18. pthread_mutex_init(&mutex, NULL);
  19. }
  20. for (uint32_t a = 0; a < 4; a++) {
  21. freeBuffers8.push_back(new NativeByteBuffer((uint32_t) 8));
  22. }
  23. for (uint32_t a = 0; a < 5; a++) {
  24. freeBuffers128.push_back(new NativeByteBuffer((uint32_t) 128));
  25. }
  26. }
  27. NativeByteBuffer *BuffersStorage::getFreeBuffer(uint32_t size) {
  28. uint32_t byteCount = 0;
  29. std::vector<NativeByteBuffer *> *arrayToGetFrom = nullptr;
  30. NativeByteBuffer *buffer = nullptr;
  31. if (size <= 8) {
  32. arrayToGetFrom = &freeBuffers8;
  33. byteCount = 8;
  34. } else if (size <= 128) {
  35. arrayToGetFrom = &freeBuffers128;
  36. byteCount = 128;
  37. } else if (size <= 1024 + 200) {
  38. arrayToGetFrom = &freeBuffers1024;
  39. byteCount = 1024 + 200;
  40. } else if (size <= 4096 + 200) {
  41. arrayToGetFrom = &freeBuffers4096;
  42. byteCount = 4096 + 200;
  43. } else if (size <= 16384 + 200) {
  44. arrayToGetFrom = &freeBuffers16384;
  45. byteCount = 16384 + 200;
  46. } else if (size <= 40000) {
  47. arrayToGetFrom = &freeBuffers32768;
  48. byteCount = 40000;
  49. } else if (size <= 160000) {
  50. arrayToGetFrom = &freeBuffersBig;
  51. byteCount = 160000;
  52. } else {
  53. buffer = new NativeByteBuffer(size);
  54. }
  55. if (arrayToGetFrom != nullptr) {
  56. if (isThreadSafe) {
  57. pthread_mutex_lock(&mutex);
  58. }
  59. if (arrayToGetFrom->size() > 0) {
  60. buffer = (*arrayToGetFrom)[0];
  61. arrayToGetFrom->erase(arrayToGetFrom->begin());
  62. }
  63. if (isThreadSafe) {
  64. pthread_mutex_unlock(&mutex);
  65. }
  66. if (buffer == nullptr) {
  67. buffer = new NativeByteBuffer(byteCount);
  68. if (LOGS_ENABLED) DEBUG_D("create new %u buffer", byteCount);
  69. }
  70. }
  71. if (buffer != nullptr) {
  72. buffer->limit(size);
  73. buffer->rewind();
  74. }
  75. return buffer;
  76. }
  77. void BuffersStorage::reuseFreeBuffer(NativeByteBuffer *buffer) {
  78. if (buffer == nullptr) {
  79. return;
  80. }
  81. std::vector<NativeByteBuffer *> *arrayToReuse = nullptr;
  82. uint32_t capacity = buffer->capacity();
  83. uint32_t maxCount = 10;
  84. if (capacity == 8) {
  85. arrayToReuse = &freeBuffers8;
  86. maxCount = 80;
  87. } else if (capacity == 128) {
  88. arrayToReuse = &freeBuffers128;
  89. maxCount = 80;
  90. } else if (capacity == 1024 + 200) {
  91. arrayToReuse = &freeBuffers1024;
  92. } else if (capacity == 4096 + 200) {
  93. arrayToReuse = &freeBuffers4096;
  94. } else if (capacity == 16384 + 200) {
  95. arrayToReuse = &freeBuffers16384;
  96. } else if (capacity == 40000) {
  97. arrayToReuse = &freeBuffers32768;
  98. } else if (capacity == 160000) {
  99. arrayToReuse = &freeBuffersBig;
  100. }
  101. if (arrayToReuse != nullptr) {
  102. if (isThreadSafe) {
  103. pthread_mutex_lock(&mutex);
  104. }
  105. if (arrayToReuse->size() < maxCount) {
  106. arrayToReuse->push_back(buffer);
  107. } else {
  108. if (LOGS_ENABLED) DEBUG_D("too much %d buffers", capacity);
  109. delete buffer;
  110. }
  111. if (isThreadSafe) {
  112. pthread_mutex_unlock(&mutex);
  113. }
  114. } else {
  115. delete buffer;
  116. }
  117. }