1. ByteArray 类封装测试
1. 对定长和压缩变长数据进行读写操作
每一个写入、读出函数都是固定的步骤:
- 生成一个随机数组,创建
Bytearray
对象(开辟一块动态内存空间) - 依次将数组内容写入内存空间
- 手动将内存指针置为开头
ba->setPosition(0)
,开始读取。 - 显示一下内存空间开辟的总容量,已经实际使用的空间大小,内存结点个数等信息
test_bytearray.cpp
: ```cpp static Logger::ptr g_logger = KIT_LOG_ROOT();
void test() {
define XX(type, len, write_func, read_func, base_len){\
std::vector<type> mv;\
for(int i = 0;i < len;++i)\
{\
mv.push_back(rand());\
}\
ByteArray::ptr ba(new ByteArray(base_len));\
for(auto &x : mv)\
{\
ba->write_func(x);\
}\
ba->setPosition(0);\
for(size_t i = 0; i < mv.size();++i)\
{\
type v = ba->read_func();\
KIT_ASSERT(v == mv[i]);\
}\
KIT_ASSERT(ba->getReadSize() == 0);\
KIT_LOG_INFO(g_logger) << #write_func "/" #read_func "(" #type ")" << ",len=" << len\
<< ",base_len=" << base_len << ",size=" << ba->getSize() << ", node count=" << ba->getNodeSum();\
}
/*固定大小*/
XX(int8_t, 100, writeFint8, readFint8, 1);
XX(uint8_t, 100, writeFuint8, readFuint8, 1);
XX(int16_t, 100, writeFint16, readFint16, 1);
XX(uint16_t, 100, writeFuint16, readFuint16, 1);
XX(int32_t, 100, writeFint32, readFint32, 1);
XX(uint32_t, 100, writeFuint32, readFuint32, 1);
XX(int64_t, 100, writeFint64, readFint64, 1);
XX(uint64_t, 100, writeFuint64, readFuint64, 1);
/*变长大小*/
XX(int32_t, 100, writeInt32, readInt32, 1);
XX(uint32_t, 100, writeUint32, readUint32, 1);
XX(int64_t, 100, writeInt64, readInt64, 1);
XX(uint64_t, 100, writeUint64, readUint64, 1);
undef XX
}
int main() { KIT_LOG_INFO(g_logger) << “tesdt begin”;
test();
KIT_LOG_INFO(g_logger) << "test end";
return 0;
}
![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)
<a name="uXjz3"></a>
### BUG:跨节点存储时写入和读取不一致
现象:改变结点大小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)
- 将写入和读取的数据全部打印一下 `test_bytearray.cpp`:
```cpp
static Logger::ptr g_logger = KIT_LOG_ROOT();
void test()
{
#define XX(type, len, write_func, read_func, base_len){\
std::vector<type> mv;\
std::cout << "写入:";\
for(int i = 0;i < len;++i)\
{\
mv.push_back(rand());\
std::cout << mv[i] << " ";\
}\
std::cout << std::endl << std::endl;\
ByteArray::ptr ba(new ByteArray(base_len));\
for(size_t i = 0; i < mv.size();++i)\
{\
ba->write_func(mv[i]);\
}\
ba->setPosition(0);\
std::cout << "读取:";\
for(size_t i = 0; i < mv.size();++i)\
{\
type v = ba->read_func();\
std::cout << v << " ";\
KIT_ASSERT(v == mv[i]);\
}\
std::cout << std::endl;\
KIT_ASSERT(ba->getReadSize() == 0);\
KIT_LOG_INFO(g_logger) << #write_func "/" #read_func "(" #type ")" << ",len=" << len\
<< ",base_len=" << base_len << ",capacity=" << ba->getTotalCapacity() << ",used size=" << ba->getSize() << ", node count=" << ba->getNodeSum();\
std::cout << std::endl;\
}
/*固定大小*/
XX(int8_t, 100, writeFint8, readFint8, 10);
XX(uint8_t, 100, writeFuint8, readFuint8, 10);
XX(int16_t, 100, writeFint16, readFint16, 10);
XX(uint16_t, 100, writeFuint16, readFuint16, 10);
XX(int32_t, 100, writeFint32, readFint32, 10);
XX(uint32_t, 100, writeFuint32, readFuint32, 10);
XX(int64_t, 100, writeFint64, readFint64, 10);
XX(uint64_t, 100, writeFuint64, readFuint64, 10);
/*变长大小*/
XX(int32_t, 100, writeInt32, readInt32, 10);
XX(uint32_t, 100, writeUint32, readUint32, 10);
XX(int64_t, 100, writeInt64, readInt64, 10);
XX(uint64_t, 100, writeUint64, readUint64, 10);
#undef XX
}
int main()
{
KIT_LOG_INFO(g_logger) << "test begin";
test();
KIT_LOG_INFO(g_logger) << "test end";
return 0;
}
- 不一致数据如下: ```cpp 写入:
- 1635550270 = 0110 0001 0111 1100 1000 0100 0011 1110
- 2069110699 = 0111 1011 0101 0100 0001 1111 1010 1011
读取: 1.1635550270 2.712582607 = 0010 1010 0111 1001 0010 0101 1100 1111
![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)
<a name="wid0z"></a>
### 更正:能够正常跨节点写入和读取
可以看到实际总容量和已经使用的空间大小,有时候不一定是对等的,可能存在一部分的冗余。<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)
<a name="bZjgu"></a>
## 2. 单独测一下浮点型数据
- `test_bytrarray.cpp`:
```cpp
static Logger::ptr g_logger = KIT_LOG_ROOT();
void test()
{
#if 1
#define XX(type, len, write_func, read_func, base_len){\
std::vector<type> mv;\
std::cout << "写入:";\
for(int i = 0;i < len;++i)\
{\
mv.push_back((type)(1.2 + rand()));\
std::cout << mv[i] << " ";\
}\
std::cout << std::endl << std::endl;\
ByteArray::ptr ba(new ByteArray(base_len));\
for(size_t i = 0; i < mv.size();++i)\
{\
ba->write_func(mv[i]);\
}\
ba->setPosition(0);\
std::cout << "读取:";\
for(size_t i = 0; i < mv.size();++i)\
{\
type v = ba->read_func();\
std::cout << v << " ";\
KIT_ASSERT(v == mv[i]);\
}\
std::cout << std::endl;\
KIT_ASSERT(ba->getReadSize() == 0);\
KIT_LOG_INFO(g_logger) << #write_func "/" #read_func "(" #type ")" << ",len=" << len\
<< ",base_len=" << base_len << ",capacity=" << ba->getTotalCapacity() << ",used size=" << ba->getSize() << ", node count=" << ba->getNodeSum();\
std::cout << std::endl;\
}
XX(float, 100, writeFloat, readFloat, 10);
XX(double, 100, writeDouble, readDouble, 10);
#undef XX
}
int main()
{
KIT_LOG_INFO(g_logger) << "test begin";
test();
KIT_LOG_INFO(g_logger) << "test end";
return 0;
}
BUG:读写不一致问题
现象:写入、读取的float型数据不一致。writeFloat()/readFloat()
函数有问题。
本质上:float
就是使用32位型数据存储的,double
使用64位型存储。不管写入定长还是变长都应该读写一致。
更正:全部读写都是定长或变长
3. 对定长和变长字符串进行读写
写一个能够生成指定长度的随机字符串函数
static std::string rand_str(uint32_t len)
{
std::string s;
s.resize(len);
for(int i = 0; i < (int)len;++i)
{
switch (rand() % 3)
{
case 0: s[i] = 'a' + rand() % 26; break;
case 1: s[i] = 'A' + rand() % 26; break;
case 2: s[i] = '0' + rand() % 9; break;
}
}
return s;
}
test_bytearray.cpp
: ```cpp void test2() {
define XX(type_len, len, write_func, read_func, base_len){\
std::vector<std::string> mv;\
for(int i = 0; i < len;++i)\
{\
mv.push_back(rand_str(type_len));\
}\
ByteArray::ptr ba(new ByteArray(base_len));\
for(auto &x : mv)\
ba->write_func(x);\
ba->setPosition(0);\
for(int i = 0; i < len;++i)\
{\
std::string v = ba->read_func();\
KIT_ASSERT(v == mv[i]);\
}\
KIT_LOG_INFO(g_logger) << #write_func "/" #read_func << "(" << type_len * 8 << ")" << ",len=" << len\
<< ",base_len=" << base_len << ",capacity=" << ba->getTotalCapacity() << ",used size=" << ba->getSize() << ", node count=" << ba->getNodeSum();\
}
XX(2, 100, writeStringF16, readStringF16, 10);
XX(4, 100,writeStringF32, readStringF32, 10);
XX(8, 100, writeStringF64, readStringF64, 10);
uint64_t t = rand() % 1000; //随机长度为1000 以内的字符串
XX(t, 100, writeStringVint, readStringVint, 100);
undef XX
}
int main() { KIT_LOG_INFO(g_logger) << “test begin”;
test2();
KIT_LOG_INFO(g_logger) << "test end";
return 0;
}
![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)
<a name="ZOf4W"></a>
## 4. 将内存数据写入文件、从文件读取数据到内存
- `test_bytearray.cpp`:
读写文件时候加入断言,来判断从文件中读取的数据是否和写入前的数据完全一样
```cpp
void test3()
{
#define XX(type, len, write_func, read_func, base_len){\
std::vector<type> mv;\
for(int i = 0;i < len;++i)\
{\
mv.push_back(rand());\
}\
ByteArray::ptr ba(new ByteArray(base_len));\
for(size_t i = 0; i < mv.size();++i)\
{\
ba->write_func(mv[i]);\
}\
ba->setPosition(0);\
for(size_t i = 0; i < mv.size();++i)\
{\
type v = ba->read_func();\
KIT_ASSERT(v == mv[i]);\
}\
KIT_ASSERT(ba->getReadSize() == 0);\
KIT_LOG_INFO(g_logger) << #write_func "/" #read_func "(" #type ")" << ",len=" << len\
<< ",base_len=" << base_len << ",capacity=" << ba->getTotalCapacity() << ",used size=" << ba->getSize() << ", node count=" << ba->getNodeSum();\
ba->setPosition(0);\
KIT_ASSERT(ba->writeToFile("./tests/temp/" #type "_" #write_func "_" #len ".dat"));\
ByteArray::ptr ba2(new ByteArray(base_len * 2));\
KIT_ASSERT(ba2->readFromFile("./tests/temp/" #type "_" #write_func "_" #len ".dat"));\
ba2->setPosition(0);\
KIT_ASSERT(ba->toString() == ba2->toString());\
KIT_ASSERT(ba->getPosition() == 0);\
KIT_ASSERT(ba2->getPosition() == 0);\
}
/*固定大小*/
XX(int8_t, 100, writeFint8, readFint8, 10);
XX(uint8_t, 100, writeFuint8, readFuint8, 10);
XX(int16_t, 100, writeFint16, readFint16, 10);
XX(uint16_t, 100, writeFuint16, readFuint16, 10);
XX(int32_t, 100, writeFint32, readFint32, 10);
XX(uint32_t, 100, writeFuint32, readFuint32, 10);
XX(int64_t, 100, writeFint64, readFint64, 10);
XX(uint64_t, 100, writeFuint64, readFuint64, 10);
/*变长大小*/
XX(int32_t, 100, writeInt32, readInt32, 10);
XX(uint32_t, 100, writeUint32, readUint32, 10);
XX(int64_t, 100, writeInt64, readInt64, 10);
XX(uint64_t, 100, writeUint64, readUint64, 10);
#undef XX
}
int main()
{
KIT_LOG_INFO(g_logger) << "test begin";
test3();
KIT_LOG_INFO(g_logger) << "test end";
return 0;
}