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;

    }


}


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