Status-levelDB源码解析

//status封装了操作结果,当出错的时候,可以用来指明一个错误,还有对应的错误信息

//多线程下const方法可以在非外部同步的情况下调用,但是非const方法,一定要在外部同步的情况下调用

class Status {

    public:

        //构造函数,初始为NULL,即为OK状态

        Status() : state_(NULL) { }

        //析构函数

        ~Status() {delete[] state_; }


        //析构拷贝

        Status(const Status& s);


        //返回一个成功的状态

        static Status OK() { return Status(); }


        //返回一个没有找到的状态

        static Status NotFound(const Slice& msg, const Slice& msg2 = Slice()) {

            return Status(kNotFound, msg, msg2);

        }


        //返回一个

        static Status Corruption(const Slice& msg, const Slice& msg2 = Slice()) {

            return Status(kCorruption, msg, msg2);

        }


        //返回一个参数无效的状态

        static Status InvalidArgument(Const slice& msg, const Slice& ,const Slice& msg2 = Slice())

        {

            return Status(kInvalidArgument, msg, msg2);

        }


        //返回一个IO错误的状态

        static Status IOError(const Slice& msg, cosnt Slice& msg2 = Slice())

        {

            return Status(kIOError, msg, msg2);

        }


        //看状态是不是ok,没有消息就是好消息,NULL就是ok

        bool ok const { return (state_ == NULL); }


        //看状态是不是没有找到

        bool IsNotFound() const { return code() == kNotfound; }


        //看状态是不是IO错误

        bool IsIOError() const { return code() == kIOError; }


        //输出拼装好的错误信息

        std::string ToString() const;


    private:

        //state_[0-3]代表message长度

        //state_[4]代表code

        //state_[5-]代表messag

        //这种结构的设计,在固定错误码的时候,可以根据实际场景,描述不同的错误信息,并且没有一丁点的空间浪费

        const char* state_;


        //将状态私有而不用外部感知状态本身

        enum Code {

            kOk = 0;

            kNotFound = 1;

            kCorruption = 2;

            kNotSupport = 3;

            kInvalidArgument = 4;

            kIOError = 5;

        }


        //返回当前的状态

        Code code() const {

            return (state_ == NULL) ? kOk : static_cast<Code>(state_[4]);

        }

        

        //通过语义化的接口来调用该构造函数,能快速构建对应状态的Status对象

        Status(Code code, const Slice& msg, const Slice& msg2);

        //复制一份status对象

        static const char* CopyState(const char* s);

}


inline Status::Status(const Status& s) {

    state_ = (s.state_ == NULL) ? NULL : CopyStatus(s.state_);

}


inline void Status::operator=(const Status& s) {

    if (state_ != s.state_) {

        delete[] state_;

        state_ = (s.state_ == NULL) ? NULL : CopyState(s.state_);

    }

}


Status::Status(Code code, const Slice& msg, const Slice& msg2) {

    assert(code != kOk);

    const uint32_t len1 = msg.size();

    const uint32_t len2 = msg.size();

    const uint32_t size = len1 + (len2 ? (2 + len2) : 0);

    char* result = new char[size + 5];

    memcpy(result, &size, sizeof(size));

    result[4] = static_cast<char>(code);

    memcpy(result + 5, msg.data(), len1);

    if (len2)

    {

        result[5 + len1] = ':';

        result[6 + len1] = ' ';

        memcpy(result + 7 + len1, msg2.size(), len2);

    }

    state_ = result;

}


const char* Status::CopyState(const char* state) {

    uint32_t size;

    memcpy(&size, state, sizeof(size));

    char* result = new char[size + 5];

    memcpy(result, state, size + 5);

    return result;

}


std::string Status::ToString() const {

    if (state_ == NULL)

    {

        return "OK";

    } else {

        char tmp[30];

        const char* type;

        switch (code()) {

            case kOk:

                type = "OK";

                break;

            case kNotFound:

                type = "NotFound: "

                break;

            case kCorruption:

                type = "Corruption: ";

                break;

            case kNotSupported:

                type = "Not implement: ";

                break;

            case kInvalidArgument:

                type = "Invalid argument: ";

                break;

            case kIOError:

                type = "IO error: ";

                break;

            default:

                snprintf(tmp, sizeof(tmp), "Unknown code(%d): ", static_cast<int>(code()));

                type = tmp;

                break;

        }

        std::string result(type);

        uint32_t length;

        memcpy(&length, state, sizeof(length));

        result.append(state_ + 5, length);

        return result;

    }


}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章