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

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
最近訪問(wèn)板塊 發(fā)新帖
查看: 1610 | 回復(fù): 0
打印 上一主題 下一主題

[算法] Tokyo Cabinet中變量壓縮存取的問(wèn)題 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2015-01-14 15:02 |只看該作者 |倒序?yàn)g覽
在TC中,很多地方為了節(jié)約存儲(chǔ)空間,在保存變量時(shí)不會(huì)直接存放變量類型長(zhǎng)度的值(比如4字節(jié)或8字節(jié)的值)到文件中,它會(huì)探測(cè)變量用來(lái)表示值的有效字節(jié)數(shù),然后把這些有意義的字節(jié)保存起來(lái),在后面讀取該變量時(shí),TC會(huì)把該變量的所有有效字節(jié)都讀出來(lái),從而計(jì)算出該變量所表示的值。
為了實(shí)現(xiàn)這個(gè)功能,TC的做法是:把變量的每個(gè)字節(jié)當(dāng)成一個(gè)有符號(hào)數(shù),最高位僅做為符號(hào)位使用,前面7位才用來(lái)表示真正的值,這樣一來(lái),文件中的4個(gè)字節(jié)的數(shù)僅有28位用來(lái)保存長(zhǎng)度信息,如果我們要保存0xFFFFFFFF這個(gè)值,就需要在文件中占用5個(gè)字節(jié),然而,這種情況的值畢竟是少數(shù)(4字節(jié)整型數(shù)只有超過(guò)2^28時(shí)才會(huì)在文件中占用5字節(jié),其它情況都會(huì)少于或等于4字節(jié)),我們一般存放的值都很小,就只需要少于4個(gè)字節(jié)的存儲(chǔ)長(zhǎng)度,比如存放小于2^7的所有值只需要1個(gè)字節(jié)空間,存放2^7到2^14之間的值僅需要2字節(jié)等等,通過(guò)這中方式節(jié)省的空間會(huì)遠(yuǎn)遠(yuǎn)少于我們浪費(fèi)的空間,因此這種做法在節(jié)省文件空間方面還是很有效的。
上面大概講了原理,下面我們來(lái)看看TC中的代碼,看看TC具體怎么實(shí)現(xiàn)的,我會(huì)在下面的代碼中給出注釋說(shuō)明。TC主要通過(guò)2個(gè)宏來(lái)分別完成存放和讀取變長(zhǎng)變量,這2個(gè)宏又分別對(duì)應(yīng)32位版本(最多存取4字節(jié)的值)和64位的版本(最多存放8字節(jié)的值),我僅分析32位的情況,64位情況類似。
1、  把一個(gè)變量按變長(zhǎng)方式放到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個(gè)字節(jié)長(zhǎng)度
    } 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)++; / // 存放的長(zhǎng)度加1,表示用了多少字節(jié)來(lái)存放變量
      } /
    } /
  } while(false)
2、  從buffer中讀出按變長(zhǎng)方式存放的變量值
/* 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第一個(gè)成員開(kāi)始讀取
    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++; / // 移動(dòng)buffer
    } /
    (TC_step) = _TC_i + 1; / // 讀取長(zhǎng)度加1,表示讀了多少字節(jié)的變量

  } while(false)



以上為原文,有一點(diǎn)不明白,為什么不把變量的每個(gè)字節(jié)當(dāng)成無(wú)符號(hào)來(lái)存取,這樣不是更減少空間嗎?
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過(guò)ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP