前言
RocksDB是在LevelDB原来的代码上进行改进完善的,所以在用法上与LevelDB非常的相似,其特点在http://blog.csdn.net/tzdjzs/article/details/20838945已在详细说明
从https://github.com/facebook/rocksdb/wiki/Performance-Benchmarks 来看,RocksDB对比LevelDB的性能有大的提高,由于英文水平不行,这里就不翻译英文说明了。
编译
由于家里的笔记本配置低,一旦运行虚拟机就会卡机,因此才会选择cygwin编译
1. 编译环境
从INSTALL.md文件内容来看,编译RocksDB需要使用到C++11的特点,需要gcc4.7以上版本,RocksDB需要压缩表内容,需要第三方库zlib,bzip2,snappy,并且需要一个编译参数处理库:gflags。第三方库的编译过程可以查看文件说明,而cygwin要支持新的gcc,可以使用cygwin的setup.exe来进行安装,这里推荐163的镜像:mirrors.163.com,从那里可以查看怎么添加cygwin源的。本人使用的是gcc4.8
2. 修改源码
由于本身不支持 Windows 平台, 在 Cygwin 里编译的话, 也会报”Unknow platform”错误,但对比leveldb来说,修改源码的地方会相对较多
2.1 修改build_detect_platform文件
把
PLATFORM_CXXFLAGS="-std=c++11"
改为
PLATFORM_CXXFLAGS="-std=gnu++11"
好像cygwin不能很好支持c++11参数,后来上网找了一下,可以改为gnu++11
在case "$TARGET_OS" in 判断中增加对cygwin平台的支持
CYGWIN_*) PLATFORM=OS_LINUX COMMON_FLAGS="$COMMON_FLAGS $MEMCMP_FLAG -lpthread -DOS_CYGWIN" PLATFORM_LDFLAGS="-lpthread" PORT_FILE=port/port_posix.cc ;;
2.2 修改Makefile
把
WARNING_FLAGS = -Wall -Werror改为
WARNING_FLAGS = -Wall
由于编译会有一个warning,因此需要去掉-Werror参数
2.3 在include/rocksdb/slice.h增加 头文件引用
#include <cstdio>
2.4 修改include/rocksdb/status.h,增加 以下内容
#include <sstream> #include <cstdlib> #if defined(OS_CYGWIN) namespace std { template <class Tdigit> string to_string(Tdigit value) { stringstream stream; stream << value; return stream.str(); } inline int stoi(const string& str) { return ::atoi(str.c_str()); } } #endif这里主要是因为std::to_string及std::stoi是c++11新加的,虽然在cygwin下编译时已增加gnu++11参数,但不知道为何还是不能支持这两个参数的定义,后来就直接增加这两个参数的定义来暂时解决问题 **2.5 修改port/port_posix.h** 在
#if defined(OS_MACOSX) || defined(OS_SOLARIS) || defined(OS_FREEBSD) ||\ defined(OS_NETBSD) || defined(OS_OPENBSD) || defined(OS_DRAGONFLYBSD) ||\ defined(OS_ANDROID) // Use fread/fwrite/fflush on platforms without _unlocked variants #define fread_unlocked fread #define fwrite_unlocked fwrite #define fflush_unlocked fflush #endif需要增加对cygwin平台的支持,改为
#if defined(OS_MACOSX) || defined(OS_SOLARIS) || defined(OS_FREEBSD) ||\ defined(OS_NETBSD) || defined(OS_OPENBSD) || defined(OS_DRAGONFLYBSD) ||\ defined(OS_ANDROID) || defined(OS_CYGWIN) // Use fread/fwrite/fflush on platforms without _unlocked variants #define fread_unlocked fread #define fwrite_unlocked fwrite #define fflush_unlocked fflush #endif
2.6 修改 util/env_posix.cc
需要修改PosixRandomAccessFile函数,把其中一句代码注释掉,最后为
public: PosixRandomAccessFile(const std::string& fname, int fd, const EnvOptions& options) : filename_(fname), fd_(fd), use_os_buffer_(options.use_os_buffer) { //assert(!options.use_mmap_reads); }在NowNanos函数中增加对cygwin平台的支持
virtual uint64_t NowNanos() { #if defined(OS_LINUX) || defined(OS_CYGWIN) struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); return static_cast<uint64_t>(ts.tv_sec) * 1000000000 + ts.tv_nsec; #elif __MACH__ clock_serv_t cclock; mach_timespec_t ts; host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); clock_get_time(cclock, &ts); mach_port_deallocate(mach_task_self(), cclock); #endif return static_cast<uint64_t>(ts.tv_sec) * 1000000000 + ts.tv_nsec; }
3. 编译
4. 注意的地方
4.1 好像单元测试的并不能完全通过,由于初步接触,虽然使用了gdb跟踪,但还是不能找到正确的原因,其中上面的2.5把options.use_mmap_reads注释掉,主要是为了通过第一个单元测试db_test,但更新rocksdb主代码后又出现另外的情况,暂时不跟踪了,后来编写一个简单的测试盒子时正常运行,因此先不管单元测试例子的异常情况。
4.2 编译出来的静态库有30多M,比起leveldb静态库不到1M的大小,实在是相差太大。
5. 例子
编译完后,编写一个简单的测试例子来查看结果
5.1 例子源码
#include "rocksdb/db.h" #include <string> #include <iostream> int main(int argc,char**argv) { rocksdb::DB* db; rocksdb::Options options; options.create_if_missing = true; std::string key1 = "abc"; std::string key2 = "ddd"; std::string value; rocksdb::Status status = rocksdb::DB::Open(options, "/tmp/mytestdb", &db); assert(status.ok()); status = db->Get(rocksdb::ReadOptions(), key1, &value); std::cout<<"get key:"<<key1<<",value:"<<value<< std::endl; value.clear(); value = "hello"; status = db->Put(rocksdb::WriteOptions(), key2, value); value.clear(); status = db->Get(rocksdb::ReadOptions(), key2, &value); std::cout<<"get key:"<<key2<<",value:"<<value<< std::endl; status = db->Delete(rocksdb::WriteOptions(), key1); delete db; return 0; }
5.2 Makefile
INCLUDEDIR=rocksdb.git all: g++ --std=gnu++11 -DSNAPPY -DZLIB -I../$(INCLUDEDIR) -I../$(INCLUDEDIR)/include -c testdb.cpp g++ testdb.o -L../$(INCLUDEDIR) -lrocksdb -lsnappy -lz -o testdb
5.3 编译
$ make g++ --std=gnu++11 -DSNAPPY -DZLIB -I../rocksdb.git -I../rocksdb.git/include -c testdb.cpp g++ testdb.o -L../rocksdb.git -lrocksdb -lsnappy -lz -o testdb** **5.4 运行结果**
$ ./testdb.exe get key:abc,value: get key:ddd,value:hello