Brpc源码浅析(一)Flatmap实现

源码与官方文档路径

flat_map.h(486行代码)
flat_map_inl.h(657行代码)
flatmap.md

原理简析

flatmap内存布局
如图所示,flatmap使用的是开链哈希。使用时先申请一块N*sizeof(Bucket)大小的连续虚拟内存。Bucket本身会存储value值,因此当哈希算法足够优秀时(即不会有拉链或很短的拉链),可以实现接近原生数组的查找性能。
数组大小的选取有两种方式:

  1. 数组大小为素数,当除以一个素数时,会产生最分散的余数
  2. 数组大小为2的指数倍:这会屏蔽被除数中的位,可能是最糟糕的选取方式。但是好处是可以通过位移运算提高计算余数的效率。

flatmap默认选取的是第二种方式,因为作者认为flatmap选取的哈希算法murmurhash3已经足够好了

主要数据结构介绍

Bucket
如上图所示,我们先看一下Bucket结构的实现,Bucket结构体是在Flatmap类内部实现的

    struct Bucket {
        explicit Bucket(const _K& k) : next(NULL)
        { new (element_spaces) Element(k); }
        Bucket(const Bucket& other) : next(NULL)
        { new (element_spaces) Element(other.element()); }
        bool is_valid() const { return next != (const Bucket*)-1UL; }
        void set_invalid() { next = (Bucket*)-1UL; }
        // NOTE: Only be called when in_valid() is true.
        Element& element() {
            void* spaces = element_spaces; // Suppress strict-aliasing
            return *reinterpret_cast<Element*>(spaces);
        }
        const Element& element() const {
            const void* spaces = element_spaces;
            return *reinterpret_cast<const Element*>(spaces);
        }
        Bucket* next;
        char element_spaces[sizeof(Element)];
    };

在指定分配好的内存位置new对象的用法参考:C++ new 的用法 (总结)
我们可以看到,每个Bucket都有一个指针指向一整个开链,还有一个存储kv对象的element。对于该位置上没有元素的Bucket,我们将其next指针指向-1表示非法,不再需要额外的标记位。
至于这里为什么需要用char数组的方式存储Element对象,不直接存放一个Element对象,个人觉得应该是都可以,用char数组的方式可能看起来更加解耦。

FlatMapElement
也就是Bucket中的Element,这也是个模板类

template <typename K, typename T>
class FlatMapElement {
public:
    typedef std::pair<const K, T> value_type;
    explicit FlatMapElement(const K& k) : _key(k), _value(T()) {}
    const K& first_ref() const { return _key; }
    T& second_ref() { return _value; }
    value_type& value_ref() { return *reinterpret_cast<value_type*>(this); }
    inline static const K& first_ref_from_value(const value_type& v)
    { return v.first; }
    inline static const T& second_ref_from_value(const value_type& v)
    { return v.second; }
private:
    const 
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值