前言
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