哈希表

Redis源码剖析 字典 结构 ( dict.h/dict.c)

≯℡__Kan透↙ 提交于 2020-02-04 20:09:29
字典又称为符号表、关联数组 、或者映射。是一种用于保存键值对(key-value)的抽象结构数组。 例如:Redis中所有key到value的映射,就是通过字典结构维护,还有hash类型的键值。 1、Redis中字典的实现 Redis的字典是由哈希表实现的,一个哈希表有多个节点,每个节点保存一个键值对。 1.1哈希表(dict.c/dict.h) typedef struct dictht{ dictEntry** table;//存放一个数组的地址,数组中存放哈希节点dictEntry的地址 unsingned long size;//哈希表table的大小,出始大小为4 unsingned long sizemask;//用于将hash值映射到table位置的索引,大小为(size-1) unsingned long used;//记录哈希表已有节点(键值对)的数量 }dictht; 1.2哈希表节点 typedef struct dictEntry{ void *key; //key union{ void* val; uint64_t u64; int64_t s64; double d; }v; //val struct dictEntry *next; //指向下一个节点,用来解决 哈希冲突 }dictEntry; 1.3字典 typedef struct dict{

【Redis源代码剖析】 - Redis内置数据结构之字典dict

雨燕双飞 提交于 2020-02-04 20:07:13
原创作品,转载请标明: http://blog.csdn.net/Xiejingfa/article/details/51018337 今天我们来讲讲Redis中的哈希表。 哈希表在C++中相应的是map数据结构。但在Redis中称作dict(字典)。Redis仅仅是用了几个简单的结构体和几种常见的哈希算法就实现了一个简单的相似高级语言中的map结构。以下我们来详细分析一下dict的实现。 在学习数据结构的时候。我们接触过一种称作“散列表”的结构,能够依据关键字而直接訪问记录。 说的详细一点就是通过把key值映射到表中的一个位置来訪问。从而加快查找速度。 Redis中的dict数据结构和我们之前学过的“散列表”大同小异。总结例如以下: 1、dict的结构 Redis定义了dictEntry、dictType、dictht和dict四个结构体来实现散列表的功能。它们详细定义例如以下: (1)dictEntry结构体 /* 保存键值(key - value)对的结构体,相似于STL的pair。*/ typedef struct dictEntry { // 关键字key定义 void *key; // 值value定义,仅仅能存放一个被选中的成员 union { void *val; uint64_t u64; int64_t s64; double d; } v; //

redis 字典

三世轮回 提交于 2020-02-04 20:05:43
字典:(符号表) 字典就是一个存储kv的存储结构,类似与c++的map,redis数据库的底层就是使用字典实现的 除了数据库,字典也是哈希键的底层实现 字典使用哈希表实现,哈希表中存储的都是kv结构 typedef struct dictht { // 哈希表数组 dictEntry **table; // 哈希表大小 unsigned long size; // 哈希表大小掩码,用于计算索引值 // 总是等于 size - 1 unsigned long sizemask; // 该哈希表已有节点的数量 unsigned long used; } dictht; sizemask和哈希值一起决定了这儿节点应该放在哪里,我们每一个哈希表节点都有一个next属性,这个可以解决链表冲突的问题,使得多个键值一样的可以连在一起 下面我们看一下哈希表节点的定义: typedef struct dictEntry { // 键 void *key; // 值 union { void *val; uint64_t u64; int64_t s64; } v; // 指向下个哈希表节点,形成链表 struct dictEntry *next; } dictEntry; 下面是字典的定义: type主要是针对不同的类型,private是针对函数的参数 其中计算哈希值的函数就在type里面指向的

redis字典的底层实现hashTable

只愿长相守 提交于 2020-02-04 20:03:31
Redis的字典使用哈希表作为底层实现。一个哈希表里面可以有多个哈希表节点,而每个哈希表节点就保存了字典中的一个键值对 哈希表的数据结构为 table属性是一个数组,数组中的每个元素都是指向dictEntry结构的指针,每个dictEntry结构保存着一个键值对,size属性记录了table的大小 used哈希表目前已有的节点sizemask属性的值总是等于size-1\ dictEntry的数据结构为 key 属性保存着键值对中的键、而v属性保存着键值对中的值,其中键值对中的值可以为指针 、无符号64位整数 64位整数 val指针可以指向 字符串、列表、字典、集合 next 属性指向另一个哈希表节点的指针(next 是为了解决哈希冲突,将多个哈希值相同的键值对链接在一起) 典的数据结构 type属性和privdata属性是针对不同类型的键值对,为创建多态字典而设置的 type属性是指向dictType结构的指针,每个dictType结构保存了用于操作特定类型键值对的函数,redis会为用途不同的字典设置不同的类型特定函数 privdata属性则保存了需要传给那些类型特定函数的可选参数 ht属性是一个包含两个项的数组,数组中的每个项都是一个dictht哈希表字典只使用ht[0]哈希表,ht[1]哈希表只会在对ht[0]哈希表进行rehash时使用 除了ht[1

HashMap 和 HashTable差别

别等时光非礼了梦想. 提交于 2020-02-04 07:53:31
代码版本 JDK每一版本都在改进。本文讨论的HashMap和HashTable基于JDK 1.7.0_67。源码见这里 1. 时间 HashTable产生于JDK 1.1,而HashMap产生于JDK 1.2。从时间的维度上来看,HashMap要比HashTable出现得晚一些。 2. 作者 以下是HashTable的作者: 以下代码及注释来自java.util.HashTable * @author Arthur van Hoff * @author Josh Bloch * @author Neal Gafter 以下是HashMap的作者: 以下代码及注释来自java.util.HashMap * @author Doug Lea * @author Josh Bloch * @author Arthur van Hoff * @author Neal Gafter 可以看到HashMap的作者多了大神Doug Lea。不了解Doug Lea的,可以看这里。 3. 对外的接口(API) HashMap和HashTable都是基于哈希表来实现键值映射的工具类。讨论他们的不同,我们首先来看一下他们暴露在外的API有什么不同。 3.1 Public Method 下面两张图,我画出了HashMap和HashTable的类继承体系,并列出了这两个类的可供外部调用的公开方法。

HashMap和HashTable到底哪不同?

♀尐吖头ヾ 提交于 2020-02-04 07:45:38
          HashMap和HashTable有什么不同?在面试和被面试的过程中,我问过也被问过这个问题,也见过了不少回答,今天决定写一写自己心目中的理想答案。 /*--> */ /*--> */ 代码版本 JDK每一版本都在改进。本文讨论的HashMap和HashTable基于JDK 1.7.0_67。 1. 时间 HashTable产生于JDK 1.1,而HashMap产生于JDK 1.2。从时间的维度上来看,HashMap要比HashTable出现得晚一些。 2. 作者 以下是HashTable的作者: 以下代码及注释来自java.util.HashTable* @author Arthur van Hoff* @author Josh Bloch* @author Neal Gafter 以下是HashMap的作者: 以下代码及注释来自java.util.HashMap* @author Doug Lea* @author Josh Bloch* @author Arthur van Hoff* @author Neal Gafter 可以看到HashMap的作者多了大神Doug Lea。不了解Doug Lea的,可以看https://en.wikipedia.org/wiki/Doug_Lea。 3. 对外的接口(API)

哈希表

ⅰ亾dé卋堺 提交于 2020-02-04 03:03:51
Hash tabel:哈希表,又称散列表,是一种根据键码值(Key Value)而直接进行访问的数据结构。它把键码值映射到表中的一个位置来存储和访问,映射函数叫做哈希函数(又称散列函数)。在哈希表中,每个存储单元我们称之为位桶数组,而每个位桶数组中的元素是链表数据结构。这里的链表是单向链表,每个链表都有两个数据域,一个用来存放键码key,另一个用来存放值value,除此之外,还有一个标签即哈希值和一个指针域用来指向下一个链表。哈希码实际上是键key对象的内存地址经过处理后的结构,由于每个对象的内存地址一般都不一样,所以哈希码一般也不同,但是也有相同的情况。而哈希值是通过哈希码计算得来的,哈希值是链表在哈希表中存放的具体位置,即位桶数组的下标索引。一般来说,常用的有除法散列法、乘法散列法、全域散列法等。这里只简单说一下除法散列法。除法散列法即用哈希码除以位桶数组的长度然后取余得到哈希值,然后在位桶数组的相应哈希值索引处插入链表。 这里在位桶数组大小的设定上有一定的要求。原则上,我们应尽可能避免位桶数组的大小为2的整数次幂。如果数组的大小是2的p次幂,p为正整数,那么经过除法散列函数计算得到的哈希值的低p位将会和哈希码k的低p位相同。也就是说,哈希值和哈希码之间的相关性很大。如果几个键码的哈希码的低p位相同,经过除法散列函数所得到的哈希值也会相同。这样

Java的HashMap

断了今生、忘了曾经 提交于 2020-02-04 01:08:55
HashMap 概述 HashMap是一个 jdk8源码 构造器 有4个构造器: public HashMap() public HashMap(int initialCapacity) public HashMap(int initialCapacity, float loadFactor) public HashMap(Map<? extends K, ? extends V> m) 除了显式设置loadFactor,其他情况都是设置为默认的0.75。 传入另外一个Map需要满足泛型上下界的要求,比如只能由<String,String>转成<Object,Object>。 主要成员变量 Node<K,V>[] table; 哈希表。 Set<Map.Entry<K,V>> entrySet; 用来遍历的Entry集合。 int size; map中元素个数。 int modCount; 源码上说的是结构化修改的次数,关系不大。 int threshold; 阈值,当size大于这个阈值,就要resize final float loadFactor; 加载因子,表示哈希表中元素的密集程度,默认是0.75。 put table 哈希表,就是一个Node数组,而Node是HashMap里一个静态内部类,实现了Map接口里的Entry接口,可以看出Node类其实是一个链表节点

20200202数据结构和算法 之用哈希表实现DNA检测

一个人想着一个人 提交于 2020-02-03 03:13:33
可以使用哈希表来存储色盲基因库数据,通过哈希函数把 4 位色盲基因映射到哈希表中,大大提高检索的效率 # include <Windows.h> # include <iostream> # include <stdio.h> using namespace std ; # define isEqual(a, b) (0==strcmp((const char*)a,(const char*)b)) # define DEFAULT_SIZE 128 typedef struct _listNode { struct _listNode * next ; void * key ; void * data ; } listNode ; typedef listNode * list ; typedef listNode * element ; typedef struct _hashTable { int tableSize ; list * theLists ; } hashTable ; hashTable * initHash ( int tableSize ) ; int hashFunction ( void * key , int tableSize ) ; //哈希函数 element findElement ( hashTable * & hashTable ,

MySQL 使用B+树

半腔热情 提交于 2020-02-02 13:31:25
概述 首先需要澄清的一点是,MySQL 跟 B+ 树没有直接的关系,真正与 B+ 树有关系的是 MySQL 的默认存储引擎 InnoDB,MySQL 中存储引擎的主要作用是负责数据的存储和提取,除了 InnoDB 之外,MySQL 中也支持 MyISAM 作为表的底层存储引擎。 我们在使用 SQL 语句创建表时就可以为当前表指定使用的存储引擎,你能在 MySQL 的文档 Alternative Storage Engines 中找到它支持的全部存储引擎,例如: MyISAM 、 CSV 、 MEMORY 等,然而默认情况下,使用如下所示的 SQL 语句来创建表就会得到 InnoDB 存储引擎支撑的表: CREATE TABLE t1 ( a INT, b CHAR (20), PRIMARY KEY (a)) ENGINE=InnoDB; 想要详细了解 MySQL 默认存储引擎的读者,可以通过之前的文章 『浅入浅出』MySQL 和 InnoDB 了解包括 InnoDB 存储方式、索引和锁等内容,我们在这里主要不会介绍 InnoDB 相关的过多内容。 我们今天最终将要分析的问题其实还是,为什么 MySQL 默认的存储引擎 InnoDB 会使用 MySQL 来存储数据,相信对 MySQL 稍微有些了解的人都知道,无论是表中的数据(主键索引)还是辅助索引最终都会使用 B+ 树来存储数据