1. ByteArray 类封装测试

目的:测试写入、读出数据能否正常进行

1. 对定长和压缩变长数据进行读写操作

每一个写入、读出函数都是固定的步骤:

  1. 生成一个随机数组,创建Bytearray对象(开辟一块动态内存空间)
  2. 依次将数组内容写入内存空间
  3. 手动将内存指针置为开头ba->setPosition(0),开始读取。
  4. 显示一下内存空间开辟的总容量,已经实际使用的空间大小,内存结点个数等信息
  • test_bytearray.cpp: ```cpp static Logger::ptr g_logger = KIT_LOG_ROOT();

void test() {

define XX(type, len, write_func, read_func, base_len){\

  1. std::vector<type> mv;\
  2. for(int i = 0;i < len;++i)\
  3. {\
  4. mv.push_back(rand());\
  5. }\
  6. ByteArray::ptr ba(new ByteArray(base_len));\
  7. for(auto &x : mv)\
  8. {\
  9. ba->write_func(x);\
  10. }\
  11. ba->setPosition(0);\
  12. for(size_t i = 0; i < mv.size();++i)\
  13. {\
  14. type v = ba->read_func();\
  15. KIT_ASSERT(v == mv[i]);\
  16. }\
  17. KIT_ASSERT(ba->getReadSize() == 0);\
  18. KIT_LOG_INFO(g_logger) << #write_func "/" #read_func "(" #type ")" << ",len=" << len\
  19. << ",base_len=" << base_len << ",size=" << ba->getSize() << ", node count=" << ba->getNodeSum();\

}

  1. /*固定大小*/
  2. XX(int8_t, 100, writeFint8, readFint8, 1);
  3. XX(uint8_t, 100, writeFuint8, readFuint8, 1);
  4. XX(int16_t, 100, writeFint16, readFint16, 1);
  5. XX(uint16_t, 100, writeFuint16, readFuint16, 1);
  6. XX(int32_t, 100, writeFint32, readFint32, 1);
  7. XX(uint32_t, 100, writeFuint32, readFuint32, 1);
  8. XX(int64_t, 100, writeFint64, readFint64, 1);
  9. XX(uint64_t, 100, writeFuint64, readFuint64, 1);
  10. /*变长大小*/
  11. XX(int32_t, 100, writeInt32, readInt32, 1);
  12. XX(uint32_t, 100, writeUint32, readUint32, 1);
  13. XX(int64_t, 100, writeInt64, readInt64, 1);
  14. XX(uint64_t, 100, writeUint64, readUint64, 1);

undef XX

}

int main() { KIT_LOG_INFO(g_logger) << “tesdt begin”;

  1. test();
  2. KIT_LOG_INFO(g_logger) << "test end";
  3. return 0;

}

  1. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/25460685/1645342977243-b866303f-47ee-4dd8-882b-a3c1f419fbac.png#clientId=ucb08377b-08bb-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=258&id=ued83ca46&margin=%5Bobject%20Object%5D&name=image.png&originHeight=258&originWidth=1586&originalType=binary&ratio=1&rotation=0&showTitle=false&size=72549&status=done&style=none&taskId=u0b908856-8ab5-41ec-a7da-a3d13073889&title=&width=1586)
  2. <a name="uXjz3"></a>
  3. ### BUG:跨节点存储时写入和读取不一致
  4. 现象:改变结点大小base_len = 10,让其能跨节点存储,发生`KIT_ASSERT(v == mv[i]);`断言,说明写入和读取出来的数据不一致。该情况发生在`writeFint64()/readFint64()`两个函数间。<br />间接说明:跨节点写入和读取有问题。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/25460685/1645343069053-7db19c2b-d472-404a-b4a1-219a10ceda74.png#clientId=ucb08377b-08bb-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=320&id=u1419d846&margin=%5Bobject%20Object%5D&name=image.png&originHeight=320&originWidth=1503&originalType=binary&ratio=1&rotation=0&showTitle=false&size=64457&status=done&style=none&taskId=u45118e93-98a0-4fc0-8d24-047d8b65b84&title=&width=1503)
  5. - 将写入和读取的数据全部打印一下 `test_bytearray.cpp`:
  6. ```cpp
  7. static Logger::ptr g_logger = KIT_LOG_ROOT();
  8. void test()
  9. {
  10. #define XX(type, len, write_func, read_func, base_len){\
  11. std::vector<type> mv;\
  12. std::cout << "写入:";\
  13. for(int i = 0;i < len;++i)\
  14. {\
  15. mv.push_back(rand());\
  16. std::cout << mv[i] << " ";\
  17. }\
  18. std::cout << std::endl << std::endl;\
  19. ByteArray::ptr ba(new ByteArray(base_len));\
  20. for(size_t i = 0; i < mv.size();++i)\
  21. {\
  22. ba->write_func(mv[i]);\
  23. }\
  24. ba->setPosition(0);\
  25. std::cout << "读取:";\
  26. for(size_t i = 0; i < mv.size();++i)\
  27. {\
  28. type v = ba->read_func();\
  29. std::cout << v << " ";\
  30. KIT_ASSERT(v == mv[i]);\
  31. }\
  32. std::cout << std::endl;\
  33. KIT_ASSERT(ba->getReadSize() == 0);\
  34. KIT_LOG_INFO(g_logger) << #write_func "/" #read_func "(" #type ")" << ",len=" << len\
  35. << ",base_len=" << base_len << ",capacity=" << ba->getTotalCapacity() << ",used size=" << ba->getSize() << ", node count=" << ba->getNodeSum();\
  36. std::cout << std::endl;\
  37. }
  38. /*固定大小*/
  39. XX(int8_t, 100, writeFint8, readFint8, 10);
  40. XX(uint8_t, 100, writeFuint8, readFuint8, 10);
  41. XX(int16_t, 100, writeFint16, readFint16, 10);
  42. XX(uint16_t, 100, writeFuint16, readFuint16, 10);
  43. XX(int32_t, 100, writeFint32, readFint32, 10);
  44. XX(uint32_t, 100, writeFuint32, readFuint32, 10);
  45. XX(int64_t, 100, writeFint64, readFint64, 10);
  46. XX(uint64_t, 100, writeFuint64, readFuint64, 10);
  47. /*变长大小*/
  48. XX(int32_t, 100, writeInt32, readInt32, 10);
  49. XX(uint32_t, 100, writeUint32, readUint32, 10);
  50. XX(int64_t, 100, writeInt64, readInt64, 10);
  51. XX(uint64_t, 100, writeUint64, readUint64, 10);
  52. #undef XX
  53. }
  54. int main()
  55. {
  56. KIT_LOG_INFO(g_logger) << "test begin";
  57. test();
  58. KIT_LOG_INFO(g_logger) << "test end";
  59. return 0;
  60. }
  • 不一致数据如下: ```cpp 写入:
  1. 1635550270 = 0110 0001 0111 1100 1000 0100 0011 1110
  2. 2069110699 = 0111 1011 0101 0100 0001 1111 1010 1011

读取: 1.1635550270 2.712582607 = 0010 1010 0111 1001 0010 0101 1100 1111

  1. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/25460685/1645343451468-182b8d7f-57c9-4c73-9d2e-648c25553f11.png#clientId=ucb08377b-08bb-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=307&id=u2655550d&margin=%5Bobject%20Object%5D&name=image.png&originHeight=307&originWidth=821&originalType=binary&ratio=1&rotation=0&showTitle=false&size=33517&status=done&style=none&taskId=u79d82d23-609e-4d09-a786-8d65f1fab7b&title=&width=821)
  2. <a name="wid0z"></a>
  3. ### 更正:能够正常跨节点写入和读取
  4. 可以看到实际总容量和已经使用的空间大小,有时候不一定是对等的,可能存在一部分的冗余。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/25460685/1645343753293-a8a5d2af-257f-4c51-a061-fa953fe61620.png#clientId=ucb08377b-08bb-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=328&id=u2ebab72f&margin=%5Bobject%20Object%5D&name=image.png&originHeight=328&originWidth=877&originalType=binary&ratio=1&rotation=0&showTitle=false&size=26986&status=done&style=none&taskId=u2c2013cb-32c7-44d1-b85d-ae4674a99a1&title=&width=877)<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/25460685/1645343735922-e143072d-3989-43eb-a065-46c6c93dd60f.png#clientId=ucb08377b-08bb-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=267&id=ucf501fd0&margin=%5Bobject%20Object%5D&name=image.png&originHeight=267&originWidth=1539&originalType=binary&ratio=1&rotation=0&showTitle=false&size=75257&status=done&style=none&taskId=ufb47a5b1-ab20-4ff2-860d-ac0818d7c14&title=&width=1539)
  5. <a name="bZjgu"></a>
  6. ## 2. 单独测一下浮点型数据
  7. - `test_bytrarray.cpp`:
  8. ```cpp
  9. static Logger::ptr g_logger = KIT_LOG_ROOT();
  10. void test()
  11. {
  12. #if 1
  13. #define XX(type, len, write_func, read_func, base_len){\
  14. std::vector<type> mv;\
  15. std::cout << "写入:";\
  16. for(int i = 0;i < len;++i)\
  17. {\
  18. mv.push_back((type)(1.2 + rand()));\
  19. std::cout << mv[i] << " ";\
  20. }\
  21. std::cout << std::endl << std::endl;\
  22. ByteArray::ptr ba(new ByteArray(base_len));\
  23. for(size_t i = 0; i < mv.size();++i)\
  24. {\
  25. ba->write_func(mv[i]);\
  26. }\
  27. ba->setPosition(0);\
  28. std::cout << "读取:";\
  29. for(size_t i = 0; i < mv.size();++i)\
  30. {\
  31. type v = ba->read_func();\
  32. std::cout << v << " ";\
  33. KIT_ASSERT(v == mv[i]);\
  34. }\
  35. std::cout << std::endl;\
  36. KIT_ASSERT(ba->getReadSize() == 0);\
  37. KIT_LOG_INFO(g_logger) << #write_func "/" #read_func "(" #type ")" << ",len=" << len\
  38. << ",base_len=" << base_len << ",capacity=" << ba->getTotalCapacity() << ",used size=" << ba->getSize() << ", node count=" << ba->getNodeSum();\
  39. std::cout << std::endl;\
  40. }
  41. XX(float, 100, writeFloat, readFloat, 10);
  42. XX(double, 100, writeDouble, readDouble, 10);
  43. #undef XX
  44. }
  45. int main()
  46. {
  47. KIT_LOG_INFO(g_logger) << "test begin";
  48. test();
  49. KIT_LOG_INFO(g_logger) << "test end";
  50. return 0;
  51. }

image.png

BUG:读写不一致问题

现象:写入、读取的float型数据不一致。writeFloat()/readFloat()函数有问题。
image.png
image.png
本质上:float就是使用32位型数据存储的,double使用64位型存储。不管写入定长还是变长都应该读写一致。

更正:全部读写都是定长或变长

image.png
image.png
image.png
image.png
image.png

3. 对定长和变长字符串进行读写

  • 写一个能够生成指定长度的随机字符串函数

    1. static std::string rand_str(uint32_t len)
    2. {
    3. std::string s;
    4. s.resize(len);
    5. for(int i = 0; i < (int)len;++i)
    6. {
    7. switch (rand() % 3)
    8. {
    9. case 0: s[i] = 'a' + rand() % 26; break;
    10. case 1: s[i] = 'A' + rand() % 26; break;
    11. case 2: s[i] = '0' + rand() % 9; break;
    12. }
    13. }
    14. return s;
    15. }
  • test_bytearray.cpp: ```cpp void test2() {

define XX(type_len, len, write_func, read_func, base_len){\

  1. std::vector<std::string> mv;\
  2. for(int i = 0; i < len;++i)\
  3. {\
  4. mv.push_back(rand_str(type_len));\
  5. }\
  6. ByteArray::ptr ba(new ByteArray(base_len));\
  7. for(auto &x : mv)\
  8. ba->write_func(x);\
  9. ba->setPosition(0);\
  10. for(int i = 0; i < len;++i)\
  11. {\
  12. std::string v = ba->read_func();\
  13. KIT_ASSERT(v == mv[i]);\
  14. }\
  15. KIT_LOG_INFO(g_logger) << #write_func "/" #read_func << "(" << type_len * 8 << ")" << ",len=" << len\
  16. << ",base_len=" << base_len << ",capacity=" << ba->getTotalCapacity() << ",used size=" << ba->getSize() << ", node count=" << ba->getNodeSum();\

}

  1. XX(2, 100, writeStringF16, readStringF16, 10);
  2. XX(4, 100,writeStringF32, readStringF32, 10);
  3. XX(8, 100, writeStringF64, readStringF64, 10);
  4. uint64_t t = rand() % 1000; //随机长度为1000 以内的字符串
  5. XX(t, 100, writeStringVint, readStringVint, 100);

undef XX

}

int main() { KIT_LOG_INFO(g_logger) << “test begin”;

  1. test2();
  2. KIT_LOG_INFO(g_logger) << "test end";
  3. return 0;

}

  1. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/25460685/1645355590577-81920abd-9072-43c3-99f9-1f87e11ee1b1.png#clientId=ucb08377b-08bb-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=128&id=u97d13fff&margin=%5Bobject%20Object%5D&name=image.png&originHeight=128&originWidth=1471&originalType=binary&ratio=1&rotation=0&showTitle=false&size=35530&status=done&style=none&taskId=u73b3667d-cb5a-450f-b078-1618eebd9d9&title=&width=1471)
  2. <a name="ZOf4W"></a>
  3. ## 4. 将内存数据写入文件、从文件读取数据到内存
  4. - `test_bytearray.cpp`:
  5. 读写文件时候加入断言,来判断从文件中读取的数据是否和写入前的数据完全一样
  6. ```cpp
  7. void test3()
  8. {
  9. #define XX(type, len, write_func, read_func, base_len){\
  10. std::vector<type> mv;\
  11. for(int i = 0;i < len;++i)\
  12. {\
  13. mv.push_back(rand());\
  14. }\
  15. ByteArray::ptr ba(new ByteArray(base_len));\
  16. for(size_t i = 0; i < mv.size();++i)\
  17. {\
  18. ba->write_func(mv[i]);\
  19. }\
  20. ba->setPosition(0);\
  21. for(size_t i = 0; i < mv.size();++i)\
  22. {\
  23. type v = ba->read_func();\
  24. KIT_ASSERT(v == mv[i]);\
  25. }\
  26. KIT_ASSERT(ba->getReadSize() == 0);\
  27. KIT_LOG_INFO(g_logger) << #write_func "/" #read_func "(" #type ")" << ",len=" << len\
  28. << ",base_len=" << base_len << ",capacity=" << ba->getTotalCapacity() << ",used size=" << ba->getSize() << ", node count=" << ba->getNodeSum();\
  29. ba->setPosition(0);\
  30. KIT_ASSERT(ba->writeToFile("./tests/temp/" #type "_" #write_func "_" #len ".dat"));\
  31. ByteArray::ptr ba2(new ByteArray(base_len * 2));\
  32. KIT_ASSERT(ba2->readFromFile("./tests/temp/" #type "_" #write_func "_" #len ".dat"));\
  33. ba2->setPosition(0);\
  34. KIT_ASSERT(ba->toString() == ba2->toString());\
  35. KIT_ASSERT(ba->getPosition() == 0);\
  36. KIT_ASSERT(ba2->getPosition() == 0);\
  37. }
  38. /*固定大小*/
  39. XX(int8_t, 100, writeFint8, readFint8, 10);
  40. XX(uint8_t, 100, writeFuint8, readFuint8, 10);
  41. XX(int16_t, 100, writeFint16, readFint16, 10);
  42. XX(uint16_t, 100, writeFuint16, readFuint16, 10);
  43. XX(int32_t, 100, writeFint32, readFint32, 10);
  44. XX(uint32_t, 100, writeFuint32, readFuint32, 10);
  45. XX(int64_t, 100, writeFint64, readFint64, 10);
  46. XX(uint64_t, 100, writeFuint64, readFuint64, 10);
  47. /*变长大小*/
  48. XX(int32_t, 100, writeInt32, readInt32, 10);
  49. XX(uint32_t, 100, writeUint32, readUint32, 10);
  50. XX(int64_t, 100, writeInt64, readInt64, 10);
  51. XX(uint64_t, 100, writeUint64, readUint64, 10);
  52. #undef XX
  53. }
  54. int main()
  55. {
  56. KIT_LOG_INFO(g_logger) << "test begin";
  57. test3();
  58. KIT_LOG_INFO(g_logger) << "test end";
  59. return 0;
  60. }

image.png
image.png