leveldb注释4–平台相关

0 编译
leveldb没有使用autoconf/automake来生成Makefile,而是自己编写了Makefile以及平台检测脚本。Makefile中会先调用检测脚本build_detect_platform,并将设置的环境变量保存在build_config.mk文件里。随后Makefile会include build_config.mk文件以进行编译,相关Makefile代码如下,其中的PLATFORM_CCFLAGS等参数将在build_detect_platform中设置并输出给build_config.mk文件:

---
# detect what platform we're building on
$(shell CC=$(CC) CXX=$(CXX) TARGET_OS=$(TARGET_OS) \
    ./build_detect_platform build_config.mk ./)
# this file is generated by the previous line to set build flags and sources
include build_config.mk

CFLAGS += -I. -I./include $(PLATFORM_CCFLAGS) $(OPT)
CXXFLAGS += -I. -I./include $(PLATFORM_CXXFLAGS) $(OPT)

LDFLAGS += $(PLATFORM_LDFLAGS)
LIBS += $(PLATFORM_LIBS)
---

build_detect_platform脚本内部使用’uname -s’命令来检测类Unix/Linux操作系统的各版本并设置合适的变量(如CC/PLATFORM等变量,以及选择合适的底层平台文件,主要是port/port_posix.cc),然后会依次检测编译环境中是否支持c++ 0x、snappy、tcmalloc,比如检测snappy是否安装的代码如下,对于snappy,若已安装,则会定义-DSNAPPY宏:

    # Test whether Snappy library is installed
    # http://code.google.com/p/snappy/
    $CXX $CXXFLAGS -x c++ - -o /dev/null 2>/dev/null  <<EOF
      #include <snappy.h>
      int main() {}
EOF
    if [ "$?" = 0 ]; then
        COMMON_FLAGS="$COMMON_FLAGS -DSNAPPY"
        PLATFORM_LIBS="$PLATFORM_LIBS -lsnappy"
    fi

如果你想更进一步,连leveldb本身提供的Makefile都不想使用,你想将源代码集成进来,则只需要注意包含port/port_posix.cc文件或者其他合适的跨平台文件,以及定义合适的平台参数,比如对于POSIX环境,可简单的使用’-DLEVELDB_PLATFORM_POSIX’就可以编译。

这里简单介绍了leveldb的编译过程,下面来看看其对平台的具体支持。

leveldb大致通过3层来实现平台语义的支持。
第一层是对外接口,在env.cc/.h与mutexlock.h中实现,mutexlock.h提供了锁的上层接口,而env则主要提供了文件与线程操作的上层接口。这部分代码对于不同平台没有多大差别。主要定义了一个抽象接口。
第二层是文件与线程操作的实际实现,对于posix,则为env_posix.cc。
第三层则是一些原子操作的封装,比如信号、锁等。对于posix,对应的文件为port_posix.cc/.h。

第一层:
Env:环境对象,提供文件、目录、线程等的操作接口。用户可自定义新Env对象,以加强对系统的控制;否则会使用默认的Env对象。对于posix,就是PosixEnv对象。
SequentialFile:顺序读文件
RandomAccessFile:随机读文件
WritableFile:顺序写文件
FileLock:文件锁

第二层:
PosixSequentialFile是对SequentialFile接口的实现,也就是简单调用fread读文件。
posix的RandomAccessFile实现有两个,一个是PosixRandomAccessFile,另一个是PosixMmapReadableFile,前者调用pread读取指定偏移的文件数据,后者为使用mmap来读取文件。
PosixMmapFile是对WritableFile接口的实现,始终使用mmap来写文件。

最终的PosixEnv对象通过调用这些子类来对外提供服务。对于随机读文件,在64位环境下,最多允许1000个文件使用mmap的方式,其他则使用pread方式。

第三层:
利用C++的语言特性定义了Mutex、CondVar,以在使用过程中自动释放pthread_mutex_t、pthread_cond_t资源。另外,也提供了Snappy的操作接口:Snappy_Compress与Snappy_Uncompress。

大部分代码并不复杂,这里就不一一分析了。

helpers/memenv目录下实现了自定义的Env类 — InMemoryEnv,完全基于内存操作的Env对象,对自定义Env对象感兴趣的可了解下。

此条目发表在 leveldb 分类目录,贴了 , , , , 标签。将固定链接加入收藏夹。

发表评论

电子邮件地址不会被公开。 必填项已被标记为 *

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>