leveldb Status 分析

leveldb Status 分析


版權(quán)聲明:本文為 cheng-zhi 原創(chuàng)文章熄守,可以隨意轉(zhuǎn)載幢码,但必須在明確位置注明出處但绕!

Status 簡(jiǎn)介

leveldb 中柑蛇,你可以使用 Status 這個(gè)類來(lái)得到你的函數(shù)的返回的狀態(tài)弊琴,它的基本用法如下:

leveldb::Status s = function();
if (!s.ok()) 
cerr << s.ToString() << endl;

你可在 leveldb/include/status.h 中找到 Status 的定義

Status 的狀態(tài)

leveldb 用下面的一個(gè) enum 類型來(lái)表示所有應(yīng)該出現(xiàn)的狀態(tài):

enum Code {
  kOk = 0,
  kNotFound = 1,
  kCorruption = 2,
  kNotSupported = 3,
  kInvalidArgument = 4,
  kIOError = 5
}

leveldb 使用下面的一組函數(shù)來(lái)分別返回這些狀態(tài):


// 返回索引為 4 的字節(jié)兆龙,代表消息的類型,后面會(huì)有解釋敲董。
Code code() const {
  return (state_ == NULL) ? kOk : static_cast<Code>(state_[4]);
}

// Returns true iff the status indicates success.
bool ok() const { return (state_ == NULL); }

// Returns true iff the status indicates a NotFound error.
bool IsNotFound() const { return code() == kNotFound; }

// Returns true iff the status indicates a Corruption error.
bool IsCorruption() const { return code() == kCorruption; }

// Returns true iff the status indicates an IOError.
bool IsIOError() const { return code() == kIOError; }

// Returns true iff the status indicates a NotSupportedError.
bool IsNotSupportedError() const { return code() == kNotSupported; }

// Returns true iff the status indicates an InvalidArgument.
bool IsInvalidArgument() const { return code() == kInvalidArgument; }

Status 的本質(zhì)

Status.h 源碼中有一段這樣的注釋:

private:
// 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_;

可以看出 Stauts 本身就是一個(gè)字符串紫皇,只不過(guò) Google 工程師給這個(gè)字符串的某些字節(jié)區(qū)域限定了含義:

  1. state_[0, 3] 字節(jié)代表消息的長(zhǎng)度,這個(gè)長(zhǎng)度是從 state_[5, ...] 開(kāi)始的腋寨,前面的 5 個(gè)字節(jié)不算聪铺。
  2. state_[4] 字節(jié)代表消息的類型,就是上面介紹的 enum Code 的 6 種類型萄窜。
  3. state_[5, ...] 代表實(shí)際的消息體铃剔。

一個(gè)關(guān)鍵的函數(shù)

下面的這一組函數(shù)用來(lái)組合指定的狀態(tài)信息:

// Return a success status.
static Status OK() { return Status(); }

// Return error status of an appropriate type.
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 NotSupported(const Slice& msg, const Slice& msg2 = Slice()) {
  return Status(kNotSupported, msg, msg2);
}

static Status InvalidArgument(const Slice& msg, const Slice& msg2 = Slice()) {
  return Status(kInvalidArgument, msg, msg2);
}

static Status IOError(const Slice& msg, const Slice& msg2 = Slice()) {
  return Status(kIOError, msg, msg2);
}

這里都調(diào)用了下面這個(gè)重要的函數(shù),用它來(lái)完成 msgmsg2 的拼接:

#include "leveldb/db/leveldbutil.cc"

Status::Status(Code code, const Slice& msg, const Slice& msg2) {
  assert(code != kOk);
  // 分別得到長(zhǎng)度
  const uint32_t len1 = msg.size();
  const uint32_t len2 = msg2.size();
  // 如果 len2 不為 0查刻,就在消息中加上 ": " 這兩個(gè)字節(jié)
  const uint32_t size = len1 + (len2 ? (2 + len2) : 0);
  // 實(shí)際的消息需要加上前面的 5 個(gè)字節(jié)键兜,所以要多分配 5 個(gè)
  char* result = new char[size + 5];
  // 先拷貝前面的 4 個(gè)字節(jié)作為長(zhǎng)度, uint32_t 為 4B 大小
  memcpy(result, &size, sizeof(size));
  // 索引為 4 的字節(jié)存儲(chǔ)消息的類型穗泵,就是那 6 種之一
  result[4] = static_cast<char>(code);
  // 拷貝實(shí)際的消息體普气,從索引為 5 的字節(jié)開(kāi)始
  memcpy(result + 5, msg.data(), len1);
  if (len2) {
    result[5 + len1] = ':';
    result[6 + len1] = ' ';
    // len2 不為 0,就拼接上 ": "
    memcpy(result + 7 + len1, msg2.data(), len2);
  }
  
  state_ = result;
}

附加的工具函數(shù)

Status 還提供了下面兩個(gè)函數(shù)作為工具佃延,作為學(xué)習(xí)還是不錯(cuò)的:

#include "leveldb/db/leveldbutil.cc"

// 拷貝狀態(tài)现诀,因?yàn)橛址峙淞诵碌膬?nèi)存夷磕,相當(dāng)于深拷貝
const char* Status::CopyState(const char* state) {
  uint32_t size;
  // 得到 state 的消息體的長(zhǎng)度,消息體長(zhǎng)度存儲(chǔ)在前面的 4 個(gè)字節(jié)中
  memcpy(&size, state, sizeof(size));
  char* result = new char[size + 5];
  // 拷貝消息體
  memcpy(result, state, size + 5);
  return result;
}

這個(gè)函數(shù)將 Code 的最新的狀態(tài)轉(zhuǎn)換為字符串仔沿,我們常用 Status s = ... 來(lái)接受函數(shù)的返回值坐桩,然后輸出 s.ToString()

#include "leveldb/db/leveldbutil.cc"

std::string Status::ToString() const {
  if (state_ == NULL) {
    return "OK";
  } else {
    char tmp[30];
    const char* type;
    // 判斷當(dāng)前的狀態(tài)
    switch (code()) {
      case kOk:
        type = "OK";
        break;
      case kNotFound:
        type = "NotFound: ";
        break;
      case kCorruption:
        type = "Corruption: ";
        break;
      case kNotSupported:
        type = "Not implemented: ";
        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;
    }
    // 拷貝到 result 中
    std::string result(type);
    uint32_t length;
    memcpy(&length, state_, sizeof(length));
    result.append(state_ + 5, length);
    return result;
  }
}

總結(jié)

Status 這個(gè)類既然是用來(lái)表示狀態(tài)的,所以我們?cè)谑褂玫氖褂梅怙保蟛糠智闆r都是得到一個(gè)函數(shù)的返回的狀態(tài)值绵跷,然后進(jìn)行相應(yīng)的判斷即可。

原文地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末烘浦,一起剝皮案震驚了整個(gè)濱河市抖坪,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌闷叉,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,744評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件脊阴,死亡現(xiàn)場(chǎng)離奇詭異握侧,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)嘿期,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門品擎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人备徐,你說(shuō)我怎么就攤上這事萄传。” “怎么了蜜猾?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,105評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵秀菱,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我蹭睡,道長(zhǎng)衍菱,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,242評(píng)論 1 292
  • 正文 為了忘掉前任肩豁,我火速辦了婚禮脊串,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘清钥。我一直安慰自己琼锋,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,269評(píng)論 6 389
  • 文/花漫 我一把揭開(kāi)白布祟昭。 她就那樣靜靜地躺著缕坎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪从橘。 梳的紋絲不亂的頭發(fā)上念赶,一...
    開(kāi)封第一講書(shū)人閱讀 51,215評(píng)論 1 299
  • 那天础钠,我揣著相機(jī)與錄音,去河邊找鬼叉谜。 笑死旗吁,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的停局。 我是一名探鬼主播很钓,決...
    沈念sama閱讀 40,096評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼董栽!你這毒婦竟也來(lái)了码倦?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,939評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤锭碳,失蹤者是張志新(化名)和其女友劉穎袁稽,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體擒抛,經(jīng)...
    沈念sama閱讀 45,354評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡推汽,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,573評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了歧沪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片歹撒。...
    茶點(diǎn)故事閱讀 39,745評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖诊胞,靈堂內(nèi)的尸體忽然破棺而出暖夭,到底是詐尸還是另有隱情,我是刑警寧澤撵孤,帶...
    沈念sama閱讀 35,448評(píng)論 5 344
  • 正文 年R本政府宣布迈着,位于F島的核電站,受9級(jí)特大地震影響早直,放射性物質(zhì)發(fā)生泄漏寥假。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,048評(píng)論 3 327
  • 文/蒙蒙 一霞扬、第九天 我趴在偏房一處隱蔽的房頂上張望糕韧。 院中可真熱鬧,春花似錦喻圃、人聲如沸萤彩。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,683評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)雀扶。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間愚墓,已是汗流浹背予权。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,838評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留浪册,地道東北人扫腺。 一個(gè)月前我還...
    沈念sama閱讀 47,776評(píng)論 2 369
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像村象,于是被迫代替她去往敵國(guó)和親笆环。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,652評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,082評(píng)論 25 707
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法厚者,類相關(guān)的語(yǔ)法躁劣,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法库菲,異常的語(yǔ)法账忘,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 31,624評(píng)論 18 399
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)熙宇,斷路器闪萄,智...
    卡卡羅2017閱讀 134,652評(píng)論 18 139
  • 浩瀚的宇宙里,以黑色為背景的虛空奇颠,其中夾雜著許些泛出淡白色光芒的群星,這一切放航,似乎是出至一位名貴的畫(huà)師之手烈拒,畫(huà)上去...
    忘阿溫閱讀 415評(píng)論 0 1
  • 需求 后臺(tái)生成周報(bào)月報(bào)季報(bào)年報(bào)Excel荆几,將文件下載鏈接推送給對(duì)應(yīng)客戶 開(kāi)發(fā)思路: 1.根據(jù)選定日期生成周報(bào),月報(bào)...
    Winter_Chen閱讀 2,659評(píng)論 0 3