在golang中使用leveldb


leveldb是一個非常強悍的kv數據庫,自然,我也希望能在go中使用。

假設有官方的go leveldb實現,那我會優先考慮。譬如這個。可是該庫文檔全然沒有,而且在網上沒發現有人用於實戰環境。對其是否能在生產環境中使用打上問號,保險起見,我還是決定不使用。

由於leveldb有c的接口,所以通過cgo能非常方便的進行集成,所以我決定採用該種方式,幸運的是,已經有人做了cgo的版本號,也就是levigo

使用levigo。須要編譯安裝leveldb,假設須要壓縮支持還須要編譯snappy,為了簡單。我寫了一個構件腳本,例如以下:

#!/bin/bash
#refer https://github.com/norton/lets/blob/master/c_src/build_deps.sh

#你必須在這里設置實際的snappy以及leveldb源代碼地址
SNAPPY_SRC=./snappy
LEVELDB_SRC=./leveldb

SNAPPY_DIR=/usr/local/snappy
LEVELDB_DIR=/usr/local/leveldb

if [ ! -f $SNAPPY_DIR/lib/libsnappy.a ]; then
    (cd $SNAPPY_SRC && \
        ./configure --prefix=$SNAPPY_DIR && \
        make && \
        make install)
else
    echo "skip install snappy"
fi

if [ ! -f $LEVELDB_DIR/lib/libleveldb.a ]; then
    (cd $LEVELDB_SRC && \
        echo "echo \"PLATFORM_CFLAGS+=-I$SNAPPY_DIR/include\" >> build_config.mk" >> build_detect_platform &&
        echo "echo \"PLATFORM_CXXFLAGS+=-I$SNAPPY_DIR/include\" >> build_config.mk" >> build_detect_platform &&
        echo "echo \"PLATFORM_LDFLAGS+=-L $SNAPPY_DIR/lib -lsnappy\" >> build_config.mk" >> build_detect_platform &&
        make SNAPPY=1 && \
        make && \
        mkdir -p $LEVELDB_DIR/include/leveldb && \
        install include/leveldb/*.h $LEVELDB_DIR/include/leveldb && \
        mkdir -p $LEVELDB_DIR/lib && \
        cp -af libleveldb.* $LEVELDB_DIR/lib)
else
    echo "skip install leveldb"
fi

function add_path()
{
  # $1 path variable
  # $2 path to add
  if [ -d "$2" ] && [[ ":$1:" != *":$2:"* ]]; then
    echo "$1:$2"
  else
    echo "$1"
  fi
}

export CGO_CFLAGS="-I$LEVELDB_DIR/include -I$SNAPPY_DIR/include"
export CGO_LDFLAGS="-L$LEVELDB_DIR/lib -L$SNAPPY_DIR/lib -lsnappy"
export LD_LIBRARY_PATH=$(add_path $LD_LIBRARY_PATH $SNAPPY_DIR/lib)
export LD_LIBRARY_PATH=$(add_path $LD_LIBRARY_PATH $LEVELDB_DIR/lib)

go get github.com/jmhodges/levigo 

對於leveldb在go里面的使用,levigo做了非常好的封裝,可是有一點我不怎么習慣。在leveldb中。對於read和write的操作,都須要傳入一個Option的東西。這玩意大多數時候都是一個默認Option對象,不是必需每次在go里面進行創建刪除。

所以我對其進行了封裝。提供了例如以下的接口,這樣使用的都是默認的option。

func (db *DB) Put(key, value []byte) error 
func (db *DB) Get(key []byte) ([]byte, error)
func (db *DB) Delete(key []byte) error 

同一時候對於iterator。我參考c++的模型,提供了iterator以及reverse_iterator兩種模式。例如以下:

func (db *DB) Iterator(begin []byte, end []byte, limit int) *Iterator 
func (db *DB) ReverseIterator(rbegin []byte, rend []byte, limit int) *Iterator 

詳細的代碼在這里


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM