概述
本小节实现了leveld的Status类,Status看起来是个简单的类,但是其中也包含了leveldb对极致的性能实现的巧妙设计
Status的内存管理
Status 只有一个成员变量 const char* state_;
state[0…3] 表示长度,state[4] 1个字节 表示状态的枚举, state[5…] 表示状态的含义
// OK status has a null state_. Otherwise, state_ is a new[] array
// of the following form:
// state_[0..3] == length of message
// state_[4] == code
// state_[5..] == message
const char* state_;
通义灵码的解释是
简化设计:通过一个指针管理所有状态信息,减少了类的复杂性。state_ 为 nullptr 表示成功状态(OK),否则指向一个动态分配的数组。
紧凑存储:将长度信息、状态码和消息合并存储在一个连续的内存块中,避免了多个独立成员变量带来的额外开销和内存碎片。
高效复制和移动:在复制或移动构造函数中,只需要处理一个指针,确保资源正确转移或复制,提高了性
从CopyState可以看到,先取state_的长度,再进行拷贝,+5是因为 4字节存长度,1字节存状态
。
const char *Status::CopyState(const char * state)
{
if(state == nullptr) {
return nullptr;
}
uint32_t size;
std::memcpy(&size, state, sizeof(size));
char * result = new char[size + 5];
std::memcpy(result, state, size + 5);
return result;
}
使用Swap实现移动构造函数
我可能看的代码太少了,这种swap方式实现移动语义的奇技淫巧我是大为震惊, 不需要判断rhs是不是自己。
inline Status& Status::operator=(Status&& rhs) noexcept {
std::swap(state_, rhs.state_);
return *this;
}
单元测试
本节没有新加单元测试,跑通原来的测试即可
./leveldb_tests --gtest_filter="*Status*"
代码地址
https://github.com/9DemonFox/myleveldb/commit/0b184a279e4d92bb3e5ae35b2921c8b10c29848f