亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

Chinaunix

標(biāo)題: Tokyo Cabinet中變量壓縮存取的問題 [打印本頁]

作者: hm2462964492    時間: 2015-01-14 15:02
標(biāo)題: Tokyo Cabinet中變量壓縮存取的問題
在TC中,很多地方為了節(jié)約存儲空間,在保存變量時不會直接存放變量類型長度的值(比如4字節(jié)或8字節(jié)的值)到文件中,它會探測變量用來表示值的有效字節(jié)數(shù),然后把這些有意義的字節(jié)保存起來,在后面讀取該變量時,TC會把該變量的所有有效字節(jié)都讀出來,從而計算出該變量所表示的值。
為了實(shí)現(xiàn)這個功能,TC的做法是:把變量的每個字節(jié)當(dāng)成一個有符號數(shù),最高位僅做為符號位使用,前面7位才用來表示真正的值,這樣一來,文件中的4個字節(jié)的數(shù)僅有28位用來保存長度信息,如果我們要保存0xFFFFFFFF這個值,就需要在文件中占用5個字節(jié),然而,這種情況的值畢竟是少數(shù)(4字節(jié)整型數(shù)只有超過2^28時才會在文件中占用5字節(jié),其它情況都會少于或等于4字節(jié)),我們一般存放的值都很小,就只需要少于4個字節(jié)的存儲長度,比如存放小于2^7的所有值只需要1個字節(jié)空間,存放2^7到2^14之間的值僅需要2字節(jié)等等,通過這中方式節(jié)省的空間會遠(yuǎn)遠(yuǎn)少于我們浪費(fèi)的空間,因此這種做法在節(jié)省文件空間方面還是很有效的。
上面大概講了原理,下面我們來看看TC中的代碼,看看TC具體怎么實(shí)現(xiàn)的,我會在下面的代碼中給出注釋說明。TC主要通過2個宏來分別完成存放和讀取變長變量,這2個宏又分別對應(yīng)32位版本(最多存取4字節(jié)的值)和64位的版本(最多存放8字節(jié)的值),我僅分析32位的情況,64位情況類似。
1、  把一個變量按變長方式放到buffer中
/* set a buffer for a variable length number */
#define TCSETVNUMBUF(TC_len, TC_buf, TC_num) / // TC_num為正整數(shù)
  do { /
    int _TC_num = (TC_num); /
    if(_TC_num == 0){ /  // 存放的變量為0
      ((signed char *)(TC_buf))[0] = 0; /
      (TC_len) = 1; /  // 返回存放了1個字節(jié)長度
    } else { /
      (TC_len) = 0; /
      while(_TC_num > 0){ /  // 變量大于0,就一直循環(huán)存放
        int _TC_rem = _TC_num & 0x7f; / // 取變量低7位存放
        _TC_num >>= 7; / // 變量右移7位
        if(_TC_num > 0){ / // 去掉低7位后變量是否還有值?
// 按負(fù)數(shù)存放取得的變量低7位值,減一確保為負(fù)數(shù),因?yàn)橹虚g可能有0
          ((signed char *)(TC_buf))[(TC_len)] = -_TC_rem - 1; /         
} else { /  // 保留最后7位,按正數(shù)的形式
          ((signed char *)(TC_buf))[(TC_len)] = _TC_rem; /
        } /
        (TC_len)++; / // 存放的長度加1,表示用了多少字節(jié)來存放變量
      } /
    } /
  } while(false)
2、  從buffer中讀出按變長方式存放的變量值
/* read a variable length buffer */
#define TCREADVNUMBUF(TC_buf, TC_num, TC_step) /
  do { /
    TC_num = 0; /
    int _TC_base = 1; /
    int _TC_i = 0; / // 從buffer第一個成員開始讀取
    while(true){ /
      if(((signed char *)(TC_buf))[_TC_i] >= 0){ / // 該字節(jié)大于0,則是最后字節(jié)
        TC_num += ((signed char *)(TC_buf))[_TC_i] * _TC_base; / // 累加
        break; / // 退出結(jié)束
      } /
        // 該字節(jié)小于0,則不是最后字節(jié)
      TC_num += _TC_base * (((signed char *)(TC_buf))[_TC_i] + 1) * -1; / //累加
      _TC_base <<= 7; /
      _TC_i++; / // 移動buffer
    } /
    (TC_step) = _TC_i + 1; / // 讀取長度加1,表示讀了多少字節(jié)的變量

  } while(false)



以上為原文,有一點(diǎn)不明白,為什么不把變量的每個字節(jié)當(dāng)成無符號來存取,這樣不是更減少空間嗎?




歡迎光臨 Chinaunix (http://www.72891.cn/) Powered by Discuz! X3.2