Folly与Boost、当然还有std等组件库的关系是互为补充,而不是彼此竞争。实际上,只有当我们需要的东西既没有,也无法满足所需的性能要求时,我们才开始定义自己的组件。
性能问题贯穿着Folly的大部分,有时导致比较具有特质性的设计(比如PackedSyncPtr.h和SmallLocks.h)。整体上确保良好的性能是所有Folly的统一主题。
逻辑设计
Folly是一组相对独立的组件的集合体,有些组件就是几个符号这么简单。内部依赖方面没有限制,这意味着某个特定的folly模块可以使用其他任何的folly组件。
所有符号都在顶层的命名空间folly中加以定义,当然除了宏。宏名称是ALL_UPPERCASE。命名空间folly定义了其他的内部命名空间,比如internal或detail。用户代码应该不依赖那些命名空间中的符号。
物理设计
在顶层,Folly采用经典的“结巴”(stuttering)方案folly/folly,这也是Boost及其他组件库所采用的。第一个目录充当库的安装根目录(可能是以folly-1.0/这样的形式);第二个目录是添加文件时用来辨别组件库,比如#include "folly/FBString.h"。
目录结构是扁平的(模仿命名空间结构),也就是说我们没有复杂的目录层次结构(这个情况在将来的版本中可能会有变化)。子目录experimental含有在folly里面使用的文件,可能用在Facebook端,但是被认为不够稳定,无法在客户端使用。你的代码不该使用folly/experimental中的文件,以免你在更新Folly时,出现问题。
folly/folly/test子目录包括了面向所有组件的单元测试,通常名为ComponentXyzTest.cpp,面向每个ComponentXyz.*。folly/folly/docs目录含有说明文档。
兼容性
目前,folly已在64位安装版Fedora 17、Ubuntu 12.04和Debian wheezy的gcc 4.6上进行了测试。它不用改动,就可以在其他64位Linux平台上运行。
组件
下面按字母顺序介绍了一系列Folly组件,另外附有每个组件的简短描述。
Arena.h,ThreadCachedArena.h
内存分配的简单地方:多次内存分配同时被释放。使用线程版本。
AtomicHashMap.h,AtomicHashArray.h
高性能的原子哈希图,采用几乎无锁的操作。
Benchmark.h
用于代码基准测试的小型框架。客户端代码注册基准测试,可选情况下使用一个变量来规定基准测试的范围(迭代和工作集大小等)。框架运行基准测试(受制于命令行标记),生成带计时信息的格式化输出。
Bits.h
各种位处理实用组件,针对速度而优化。
Bits.h
位变换函数,使用统一接口包装ffsl(l)图元。
ConcurrentSkipList.h
实现了用证实正确的可扩展并发跳跃表(Provably Correct Scalable Concurrent Skip List)描述的结构,这种跳跃表由Herlihy及其他人共同开发。
Conv.h
各种数据转换例程(尤其是to和from字符串),针对速度和安全进行了优化。
DiscriminatedPtr.h
类似boost::variant,但完全局限于指针。使用指针中最高位、未使用的16位作为鉴别器。所以sizeof(DiscriminatedPtr<int, string, Widget>) == sizeof(void*)。
dynamic.h
动态类型对象,创建时关注JSON对象。
Endian.h
Endian转换图元。
Escape.h
以C方式转义字符串。
eventfd.h
针对eventfd系统调用的包装器。
FBString.h
嵌入式实现std::string,进行了诸多优化。
FBVector.h
基本上嵌入式实现std::vector,进行了诸多优化。
Foreach.h
伪语句(作为宏语句来实现),用于迭代。
Format.h
Python式样的格式化实用组件。
GroupVarint.h
针对32位值的Group Varint编码。
Hash.h
各种流行的哈希函数实现。
Histogram.h
一个简单的类,用于收集直方图数据。
IntrusiveList.h
方便类型定义,用于使用boost::intrusive_list。
json.h
JSON序列化器和反序列化器。使用dynamic.h。
Likely.h
针对__builtin_expect的包装器。
Malloc.h
内存分配助手,尤其是使用jemalloc时。
MapUtil.h
一种助手,用于查找联合容器中的项目(比如std::map和std::unordered_map)。
PackedSyncPtr.h
一种高度专业化的数据结构,含有指针、1位旋转锁和15位整数,它们都在一个64位单词中。
Preprocessor.h
不好但又必不可少的组件。
PrettyPrint.h
针对数字的美化打印组件,用于添加所用单元的后缀:字节(kb、MB等)、度量单位后缀(k、M和G等)以及时间(s、ms、us和ns等)。
ProducerConsumerQueue.h
无锁单读取器单写入器队列。
Random.h
只定义了一个函数:randomNumberSeed()。
Range.h
Boost式样的范围工具和StringPiece专门化。
RWSpinLock.h
快速而紧凑的读取器/写入器旋转锁。
ScopeGuard.h
老式ScopeGuard用语的C++11版本。
SmallLocks.h
非常小的旋转锁(1字节和1位)。
small_vector.h
一种向量,含有小缓冲器方面的优化和可选的嵌入式PicoSpinLock。
sorted_vector_types.h
类似std::map的集合体,但是作为排序向量来实现。
StlAllocator.h
标准模板库(STL分配器),包装简单的分配/取消分配接口。
String.h
连接folly::fbstring和std::string的字符串实用组件。
Synchronized.h
高级同步库。
System.h
解码和errno实用组件。
ThreadCachedInt.h
使用线程缓存的高性能原子增量。
ThreadLocal.h
经过改进的线程本地存储,用于存储非平凡类型。
TimeoutQueue.h
按项目设定超时的队列。
Traits.h
类型特性,补充了在标准的C++11头<traits>中定义的那些类型特性。
Unicode.h
定义了codePointToUtf8函数。