STL hashtable阅读记录

时间:2022-12-09 08:41:51
unordered_map,unordered_set等相关内容总结:
unordered_map和unordered_set是在开发过程中常见的stl数据结构。其本质是hashtable。在SGI_STL中,hashtable解决冲突的办法是拉链法。下面是一些对STL中堆hashtable中有关代码阅读的一些记录。
与之相关联的几个文件 
gcc/libstdc++-v3/include/bits/hashtable_policy.h
gcc/libstdc++-v3/include/bits/functional_hash.h
gcc/libstdc++-v3/src/c++11/hashtable_c++0x.cc
 
 
 
第一部分:基本数据组织说明
hashtable的重要数据组织成员及辅助理解图(一个可能的hash数据结构情况)
_Bucket[] _M_buckets
_Hash_node_base _M_before_begin
size_type _M_bucket_count // 初始桶编号为1
size_type _M_element_count
STL hashtable阅读记录
 
 
由上图可以大致总结出在SGI-STL中hashtable数据的组织。几个要点:
①.hashtable实际上是维护了一个单链标。其头节点是一个特殊的成员_M_before_begin,其没有实际的数据。按照名字来理解,是第一个数据的前一个节点。
看一下对应的相关注释:
The non-empty buckets contain the node before the first node,this design makes it possible to implement somethiing like a std::forward_list::insert_after on a container insertion and std::forward_list::erase_afer on container erase calls._M_before_begin is equivalent to  std::forward_list_list::before_begin.Note that one of the non-empty buckets contains &_M_before_begin which is not a dereferenceable node so  the node pointer ina bucket shall never be dereferenced ,only its next node can be.
②._M_buckets这个二级指针的作用是什么,其目的是为了通用的可以使用_M_next()函数调用拿到每个桶的头节点(对于上图就是A,D)。比如_M_buckets[1]._M_next就是桶号为1的头结点A。_M_buckets[2]._M_next就是桶号为2的数据结构的头结点D。同时对于上图示例,应当有_M_before_begin和_M_buckets[1]是相等的(见黑色实线)
 
 
第二部分:几个常见接口的调用流程及调用栈
hashtable的定义
STL hashtable阅读记录
 
一些方便查阅的 using和typedef
STL hashtable阅读记录
 
STL hashtable阅读记录
①.插入的key是如何生成的
    1.对于简单类型(int等):key计算的相关代码 const key_type& __k = this->_M_extract()(__node->_M_v())
    计算key值是通过_M_extrace()来计算的,其是模板参数中的_ExtraceKey,
   对于unordered_map在其定义中其模板参数中_ExtraceKey是__detail::Select1st 当定义为unordered_map<int,node>,insert(std::make_pair(0,node(a)); 其就返回pair中的first,即0。
   对于如果定义类似于key不是简单类型的。需要自己定义hash函数否则不能通过编译,举例https://www.zhihu.com/question/30921173
    
struct pairhash {public:
template <typename T, typename U>
std::size_t operator()(const std::pair<T, U> &x) const
{
    return std::hash<T>()(x.first) ^ std::hash<U>()(x.second);
}};
class abc {
    std::unordered_map<std::pair<int,int>, int, pairhash> rules;
};
在这种情况下。__detail::Select1st获取到的数据就是std::pair<int,int>作为key对应的值
②.hash值如何生成
 __hash_code __code = this->_M_hash_code(__key);   ======> return _M_h1()(__k);  ======> 在key为int的时候传递的参数是std::hash<int> 
其最后会调用一个宏_Cxx_hashtable_define_trivial_hash(int),其在文件functional_hash.h中,该文件内涵多种不同类型的特化hash类。该文件定义了这些简单类型是如何hash的,下面是该宏的定义,看到这种情况下,其hash值就是直接强转成size_t类型。
STL hashtable阅读记录
 
③.如何确定一对pair的hash桶编号    size_type __bkt = _M_bucket_index(__k,__code) ====> return ___hash_code_base::_M_bucket_index(__k,__c,_M_bucket_count); } ====> return _M_h2()(__c,__n);    
    其中_M_h2获取的是模板参数_H2,对于unordered_map传递进来的是__detail::_Mod_range_hashing,其内容很简单。
STL hashtable阅读记录
可见桶编号值为hash值mod桶数量
④.rehash流程:主要思路是根据当前桶的数量和元素数量,在一个大的素数表中lowerbound查找下一步合适的桶编号。
下面是一个判定是否需要rehash桶以及如果需要后算出下一个合理的桶数量。至于最终的真正_M_rehash_aux流程。主题是数据指针迁移,并且保证新的new_buckets结构像前图一样。
 
 
 
STL hashtable阅读记录
 
 
 
STL hashtable阅读记录
 
 
 
 
 
 
 

STL hashtable阅读记录的更多相关文章

  1. EventBus源码解析 源码阅读记录

    EventBus源码阅读记录 repo地址: greenrobot/EventBus EventBus的构造 双重加锁的单例. static volatile EventBus defaultInst ...

  2. Elasticsearch6&period;3&period;2启动过程源码阅读记录

    Elasticsearch6.3.2启动过程源码阅读记录 网上有很多关于es的源码分析,觉得自己技术深度还不够,所以这些文章只是看源码过程中的一个笔记,谈不上分析. 整个启动过程以类名.方法名,按顺序 ...

  3. x264阅读记录-2

    x264阅读记录-2 7. x264_encoder_encode函数-1 查看该函数代码(Encoder.c文件)可以发现,该函数中注释很详细,对编码的整个步骤展示的也相对比较清晰. 在查看具体的代 ...

  4. x264阅读记录-1

    x264阅读记录-1 采用x264版本是x264-snapshot-20060316-2245. 1. main函数 x264的main函数位于x264.c中,下面是main函数调用情况: (1)_s ...

  5. 《Javascript高级程序设计》阅读记录(七):第七章

    <Javascript高级程序设计>中,2-7章中已经涵盖了大部分精华内容,所以摘录到博客中,方便随时回忆.本系列基本完成,之后的章节,可能看情况进行摘录. 这个系列以往文字地址: &lt ...

  6. 《Javascript高级程序设计》阅读记录(六):第六章 下

    这个系列以往文字地址: <Javascript高级程序设计>阅读记录(一):第二.三章 <Javascript高级程序设计>阅读记录(二):第四章 <Javascript ...

  7. 《Javascript高级程序设计》阅读记录(五):第六章 上

    这个系列以往文字地址: <Javascript高级程序设计>阅读记录(一):第二.三章 <Javascript高级程序设计>阅读记录(二):第四章 <Javascript ...

  8. 《Javascript高级程序设计》阅读记录(三):第五章 上

    这个系列以往文字地址: <Javascript高级程序设计>阅读记录(一):第二.三章 <Javascript高级程序设计>阅读记录(二):第四章 这个系列,我会把阅读< ...

  9. 《Javascript高级程序设计》阅读记录(一):第二、三章

    <Javascript高级程序设计>阅读记录(一) 这个系列,我会把阅读<Javascript高级程序设计>之后,感觉讲的比较深入,而且实际使用价值较大的内容记录下来,并且注释 ...

随机推荐

  1. 一些有意思的VR设备介绍

    1.计算机(Computers) 不久以前,一个VR系统需要百万美元的超级计算机:而如今*的VR系统正在使用桌面便携式计算机簇,极大的降低了价格和维护成本. 2.跟踪器(Tracking) 为了能与 ...

  2. git基本配置

    用户信息 你个人的用户名称和电子邮件地址,用户名可随意修改,git 用于记录是谁提交了更新,以及更新人的联系方式. $ git config --global user.name "Donl ...

  3. outline使用方法&comma;outline与border的区别&colon;

    在浏览器里,当鼠标点击或使用Tab键让一个链接或者一个radio获得焦点的时候,该元素将会被一个轮廓虚线框围绕.这个轮廓虚线框就是 outline . outline 能告诉用户那一个可以激发事件的h ...

  4. IDL数组计算

    函数 作用 min 最小值 max 最大值 total 求和 stddev 标准差 mean 平均值  

  5. 【shell】通配符

    ‘’与“” [root@andon ~]# name='$date' [root@andon ~]# echo $name $date [root@andon ~]# name=abc [root@a ...

  6. c&num;中获取服务器IP,客户端IP以及Request&period;ServerVariables详细说明

    客户端ip: Request.ServerVariables.Get("Remote_Addr").ToString();  客户端主机名: Request.ServerVaria ...

  7. Java &lbrack;Leetcode 235&rsqb;Lowest Common Ancestor of a Binary Search Tree

    题目描述: Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in ...

  8. &lbrack;状压dp&rsqb;POJ1185 炮兵阵地

    中文题 题意不再赘述 对于中间这个“P” 根据dp的无后效性 我们只需考虑前面的 就变成了 只需考虑: 也就是状压前两行 具体与HDOJ的4539类似: 看HDOJ 4539 仅仅是共存状态的判断不同 ...

  9. Mock&period;js简易教程,脱离后端独立开发,实现增删改查功能(转)

    在我们的生产实际中,后端的接口往往是较晚才会出来,并且还要写接口文档,于是我们的前端的许多开发都要等到接口给我们才能进行,这样对于我们前端来说显得十分的被动,于是有没有可以制造假数据来模拟后端接口呢, ...

  10. 学习Vue 入门到实战——学习笔记

    闲聊: 自从进了现在的公司,小颖就再没怎么接触vue了,最近不太忙,所以想再学习下vue,就看了看vue相关视频,顺便做个笔记嘻嘻. 视频地址:Vue 入门到实战1.Vue 入门到实战2 学习内容: ...