├── Fast20 HotRing A Hotspot-Aware In-Memory Key-Value Store.pdf ├── README.md ├── data ├── data12.zip └── data345.zip ├── img ├── image-20200510172910121.png ├── image-20200511002856889.png ├── image-20200511203407929.png ├── image-20200511231816613.png ├── image-20200515205823151.png ├── image-20200516003719698.png ├── image-20200516003729841.png ├── image-20200516010000423.png ├── image-20200516010553517.png ├── image-20200523201030904.png ├── image-20200524011123719.png ├── image-20200524011500230.png ├── image-20200524011819115.png ├── image-20200524020134150.png └── image-20200524020520732.png ├── project ├── hotring-r │ ├── .vs │ │ └── hotring-r │ │ │ └── v15 │ │ │ ├── .suo │ │ │ ├── Browse.VC.db │ │ │ └── ipch │ │ │ ├── 8eb8dec412c8842c.ipch │ │ │ └── AutoPCH │ │ │ ├── 635422ef5a80d605 │ │ │ └── MAIN.ipch │ │ │ ├── 8ab8629a43859d90 │ │ │ └── HOTRING-R.ipch │ │ │ ├── c2393d5872ef76d2 │ │ │ └── HASHTABLE.ipch │ │ │ ├── dd4a42fec6d8bf50 │ │ │ └── 源.ipch │ │ │ └── f149c52b281ad32d │ │ │ └── MAIN.ipch │ ├── hotring-r.sln │ └── hotring-r │ │ ├── Debug │ │ └── hotring-r.log │ │ ├── hashTable.cpp │ │ ├── hotring-r.cpp │ │ ├── hotring-r.h │ │ ├── hotring-r.vcxproj │ │ ├── hotring-r.vcxproj.filters │ │ ├── hotring-r.vcxproj.user │ │ └── main.cpp └── other code │ ├── formula1.cpp │ ├── formula2.cpp │ ├── formula3.cpp │ └── radomdata.cpp └── research report.pdf /Fast20 HotRing A Hotspot-Aware In-Memory Key-Value Store.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Focus5679/HotRing-simple-and-simple-demo/b1588b96c153a62f6a0eb797519e7ace12544675/Fast20 HotRing A Hotspot-Aware In-Memory Key-Value Store.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 下载research report.pdf可以获得更好的阅读体验。 2 | 3 | # 一、主要内容 4 | 5 | ## 概要 6 | 7 | ​ 作者认为**内存中键值存储(In-memory key-value stores)**的热点问题被忽视了,并提出了一种名为**HotRing**的**热点可感知的KV数据结构**,它具有以下的特性: 8 | 9 | + 基于**有序环哈希索引结构**,通过让**头节点更靠近热点数据**来提高热点数据的访问速度 10 | + 提供**轻量**、**运行时**的**热点转移检测策略** 11 | + 支持**并发**且**无锁** 12 | 13 | ## 1介绍 14 | 15 | ​ 互联网公司在实际生产环境中**广泛应用内存中键值存储**来提高数据存储的性能。学者们**研究了不同场景下的热点问题**,并且在一些场景中提出了有效的解决方案。然而,**内存中键值存储场景下的热点问题被忽略**了,但这个问题在互联网时代的变得空前重要。目前很多数据结构实现的**KVS都不能感知热点项目**,基于哈希表的KVS如果希望能提高热点项目的访问性能,会造成很大的开销。所以作者提出了**基于有序环哈希索引结构的热点可感知KV数据结构**HotRing。 16 | 17 | ## 2背景与动机 18 | 19 | ### 2.1哈希索引与热点问题 20 | 21 | ​ 在KVS中,哈希索引是最常用的结构,一般哈希索引包含一个哈希表和一个**冲突链**。 22 | 23 | ![image-20200510172910121](img/image-20200510172910121.png) 24 | 25 | ​ 哈希索引无法感知热点项目,所以热点项目是平均地分布在冲突链中,在工作负载高度倾斜的情况下,这种分布会导致整体性能的严重下降。 26 | 27 | ​ 针对热点问题,目前有两种解决办法: 28 | 29 | + 使用CPU cache存储热点项目,但cache容量很小,只能存储全部容量的0.012%。 30 | + rehash,但会成倍地增加内存消耗,而性能提升有限,不划算。 31 | 32 | ### 2.2理论证明热点感知的好处 33 | 34 | ​ 通过公式: 35 | $$ 36 | E_{chain}=1+\frac{L}{2}=1+\frac{N}{2\cdot{B}}\tag{1} 37 | $$ 38 | 39 | $$ 40 | L:链长度\ N:总项目数\ B:总桶数\ E_{chain}:冲突链表访问内存的预期次数 41 | $$ 42 | 43 | ​ 44 | $$ 45 | f(x)=\frac{\frac{1}{x^\theta}}{\sum_{n=1}^N\frac{1}{n^\theta}}\tag{2} 46 | $$ 47 | 48 | $$ 49 | θ:偏度因子\ N:总项目数\ x:第x个热点项目\ f(x):第x个热点项目出现的频率 50 | $$ 51 | 52 | $$ 53 | \begin{equation}\begin{split} 54 | E_{ideal}&=1+\sum_{k=1}^LF(k)\cdot{k}\\ 55 | &=1+\sum_{k=1}^L[\sum_{i=(k-1)\cdot{B}+1}^{k\cdot{B}}f(i)]\cdot{k} 56 | \end{split}\end{equation} \tag{3} 57 | $$ 58 | 59 | $$ 60 | F(k):每个链上项目的累计访问频率\ E_{ideal}:冲突链表访问内存的预期次数 61 | $$ 62 | 63 | ​ 证明了采取热点感知的数据结构的性能提升,代码验证详见`formula1.cpp`, `formula2.cpp`, `formula3.cpp`。 64 | 65 | ### 2.3挑战与设计原则 66 | 67 | ​ 在设计解决方案时,需要满足以下两个条件: 68 | 69 | + 需要轻量级的热点感知策略,并且底层数据结构要支持热点转移 70 | + 将冲突链表改成环,以支持热点转移且可以访问到所有项目 71 | 72 | + 需要支持大规模并发 73 | + 采用无锁结构实现删除和插入操作 74 | + 实现热点移动检测,头部指针移动和重新哈希等基础操作 75 | 76 | ![image-20200511002856889](img/image-20200511002856889.png) 77 | 78 | ## 3HotRing设计 79 | 80 | ### 3.1有序环 81 | 82 | ​ 作者对于有序环的设计满足以下三个条件: 83 | 84 | ①将冲突链表首尾相接,变成环 85 | 86 | ②哈希表中的头指针可以指向环中任意项 87 | 88 | ③环中各项有序排列 89 | 90 | ​ 这种设计便于以任意节点作为遍历操作的首项,都可以遍历全部的项目,便于感知到热点项目后,将头指针指向热点项目。但由于并发访问有可能改变哈希表中头指针指向的项目(比如头指针指向的项目被删除),所以仅仅将头指针指向作为搜索停止条件是不够的,因此作者设计了环中节点的排序规则并制定了搜索停止条件。 91 | 92 | 排序规则: 93 | $$ 94 | order_k=(tag_k,key_k) 95 | $$ 96 | 搜索命中条件: 97 | $$ 98 | order_i=order_k\tag{4} 99 | $$ 100 | 搜索未命中(终止)条件: 101 | 102 | 原文公式: 103 | $$ 104 | \left \{ 105 | \begin{array}{} 106 | order_{i-1} 346 | 347 | + 证明问题严重性-> 348 | 349 | + 提出可能的解决方案-> 350 | 351 | + 实现解决方案-> 352 | 353 | + 证明解决方案的有效性 354 | 355 | 研究逻辑缜密,研究过程层层递进,结果令人信服。 356 | 357 | ### 解决方案具备参考价值 358 | 359 | ​ 论文中提出,在互联网时代,社会热点问题会在较短时间内被大量访问。并且社会热点会随着时间转移。所以,具备**热点感知**能力的存储系统有比较好的发展潜力,只给未来相关领域的研究提供了新的解决思路。 360 | 361 | ## 短处 362 | 363 | ### Rehash操作中激活新表描述的不清楚 364 | 365 | ​ 根据原文,Rehash操作在插入Rehash Item后,新表被激活,此时来自新表的访问通过比较tag来选择头节点,来自旧表的访问通过识别Rehash Node继续执行。 366 | 367 | + 前半句:当新表产生后,可以直接通过计算哈希值来确定New Head,而此处说新表需要通过比较tag来确定新的头节点,表述有些模糊。 368 | 369 | + 后半句:结合前文所述,结构采用比较order的方式来确定项目,其中$order_k=(tag_k,key_k)$ ,此处所表达的意思可能是:通过识别Rehash Node确保不会产生比较错误。 370 | 371 | 372 | ​ 如果此处能结合示意图进行举例说明,可以更清楚地表达作者的想法。 373 | 374 | ![image-20200523201030904](img/image-20200523201030904.png) 375 | 376 | ### 在测试部分介绍YCSB工作负载时,描述不够直观 377 | 378 | ​ 在文中只对ABCDF的工作负载情况进行了文字介绍。如果可以把每种工作负载的情况绘制成表格形式,那么可以有利于读者更直观地了解工作负载的配置情况与比较不同工作负载情况下的性能表现。 379 | 380 | ### 研究视角有局限 381 | 382 | ​ 论文核心问题是在工作负载高度不平衡的环境下提出的,研究视角主要聚焦于实际生产环境中产生的问题。作者在测试部分着重比较了在工作负载不平衡的情况下各种KVSes的比较,还可以分析比较一下工作负载相对平衡的环境下的性能表现。 383 | 384 | # 四、收获 385 | 386 | ## 专业知识方面 387 | 388 | ### CAS 389 | 390 | ​ CAS指Compare and Swap,其思想是利用三个参数:一个当前内存值V,旧的预期值A,即将更新的值B实现一种无锁且保证线程安全的机制。它的操作过程如下: 391 | 392 | + 线程拷贝需要修改的内存中的值保存为A 393 | + 线程得到即将更新的新值为B 394 | + 线程读取需要修改的内存中的当前值V,比较V和A是否相等 395 | + 相等,说明该值没有被其他线程改动,将内存中的值改为新值,修改成功 396 | + 不相等,说明该值已经被别线程改动过,修改失败 397 | 398 | ​ 比较修改操作需要保证是原子操作,一般是由CMPXCHG的汇编指令来实现,上层应用也可以通过加锁操作等来保证。(不过这丧失了无锁化的初衷) 399 | 400 | 401 | 402 | ​ ABA问题指在进行CAS操作时,内存中的值由A改成B又被改回A,而CAS线程只保存了第一个版本的内存值A,并不知道内存值已经被变动过。ABA问题一般可以通过给变量增加版本号来解决,将A->B->A的过程变成A1->B2->A3,那么进行CAS操作时既时发生ABA问题,线程也会察觉到,并保证不会进行修改操作。 403 | 404 | ### RCU 405 | 406 | ​ RCU是指Read-Copy-Update,是一种针对读取请求多,修改请求少环境下的锁结构,它的操作过程如下: 407 | 408 | + 读取线程不需要获得任何锁就可以访问数据 409 | + 修改线程在访问它时首先拷贝一个副本 410 | + 然后对副本进行修改 411 | + 当其他线程都退出对数据的操作后,再将原来数据的指针指向修改后的新数据 412 | + 释放存储旧数据的空间 413 | 414 | ​ 使用RCU机制时,读取线程不需要获取锁资源,所以在读取请求较多时,使用RCU可以有效提高系统性能。但RCU需要其他的锁机制来实现修改线程间的同步,并且修改线程还需要复制数据内容,延迟释放空间等。所以当修改频繁时,RCU机制的性能不是很好。 415 | 416 | ### HotRing数据结构 417 | 418 | ​ HotRing是一种具备热点感知能力的有序环哈希结构,它大大改善了工作负载高度不平衡环境下的存储系统性能。 419 | 420 | ## 研究常识方面 421 | 422 | ### 工作负载不平衡 423 | 424 | ​ 认识到工业界实际工作负载非常不平衡,一般状况下,超过一半(57.3%)的访问请求只会访问1%左右的数据,而极端状况下,超过九成(91.7%)的访问请求只会访问1%左右的数据。所以**热点问题**在各种存储系统中都是一个非常严重的性能瓶颈。 425 | 426 | ### 热点问题分布广泛 427 | 428 | ​ 在存储领域,热点问题分布非常广泛。来到互联网时代后,热点问题更加严重,当一个社会热点事件出现时,大量的访问请求会集中在极少的数据上。 429 | 430 | ### 热点感知方案具有潜力 431 | 432 | ​ 具备热点感知能力的存储系统可以更好的应对当前的互联网环境,同时,热点感知在处理**热点问题**上有很好的潜力,可以尝试应用在其他场景下。 433 | 434 | # 五、论文存疑的地方 435 | 436 | ## 疑问1 437 | 438 | ​ 在论文中,Rehash操作的第三步,Rehash线程会在过渡期等待所有针对旧哈希表的访问结束后开始分裂。并且,在过渡期中,HotRing仅仅阻塞了Rehash线程。但我考虑,这还不能保证Rehash操作的正确性。 439 | 440 | ​ Rehash操作中,如果存在针对新表的RCU操作,RCU线程若还未找到被更新项的前一项,旧环就被断开了,可能造成该RCU线程死循环。 441 | 442 | 443 | # 六、实践 444 | 445 | ## 设计目标: 446 | 447 | 1. 根据论文思想,复现论文方法,设计编写符合HotRing思想的数据结构。 448 | 2. 通过对比实验,体现HotRing相比HashTable的优点。 449 | 450 | ## 测试指标: 451 | 452 | | 指标 | 说明 | 453 | | ---------------------------------- | -------------------------- | 454 | | 总查找次数(findcnt) | 反应系统完成任务的总开销 | 455 | | 单次最高查找次数(maxFindcnt) | 一定程度上反应系统的尾延迟 | 456 | | 单次最低查找次数(minFindcnt) | 反应系统单次查询的最优表现 | 457 | | 平均单词查找次数(averageFindcnt) | 反应系统每次查询操作的 | 458 | | 消耗的时间(useTime) | 反应系统完成任务的总耗时 | 459 | 460 | ## 测试数据: 461 | 462 | ### 控制单一变量:theta 463 | 464 | | 数据文件 | 总项数 | 总查询数 | 键桶比 | theta | 备注 | 465 | | ---------- | ------ | ---------- | ------ | ----- | ---------------------- | 466 | | test1.data | 2000 | 10'000'000 | 2 | 0 | 工作负载分布完全平均 | 467 | | test2.data | 2000 | 10'000'000 | 2 | 1 | 工作负载分布不平衡 | 468 | | test3.data | 2000 | 10'000'000 | 2 | 2 | 工作负载分布极度不平衡 | 469 | 470 | ### 控制单一变量:键桶比 471 | 472 | | 数据文件 | 总项数 | 总查询数 | 键桶比 | theta | 备注 | 473 | | ---------- | ------ | ---------- | ------ | ----- | ----------- | 474 | | test2.data | 2000 | 10'000'000 | 2 | 1 | 平均链长为2 | 475 | | test4.data | 4000 | 10'000'000 | 4 | 1 | 平均链长为4 | 476 | | test5.data | 8000 | 10'000'000 | 8 | 1 | 平均链长为8 | 477 | 478 | ## 测试结果: 479 | 480 | | 数据文件 | 数据结构 | findcnt | maxFindcnt | minFindcnt | averageFindcnt | useTime | 481 | | ---------- | --------- | -------- | ---------- | ---------- | -------------- | ------- | 482 | | test1.data | HashTable | 16538091 | 10 | 1 | 1.65381 | 76s | 483 | | test1.data | HotRing | 16531911 | 9 | 1 | 1.65319 | 116s | 484 | | test2.data | HashTable | 22456351 | 6 | 1 | 2.24564 | 96s | 485 | | test2.data | HotRing | 10816535 | 5 | 1 | 1.08165 | 84s | 486 | | test3.data | HashTable | 22009405 | 8 | 1 | 2.20094 | 93s | 487 | | test3.data | HotRing | 10003612 | 7 | 1 | 1.00036 | 77s | 488 | 489 | 490 | 491 | | 数据文件 | 数据结构 | findcnt | maxFindcnt | minFindcnt | averageFindcnt | useTime | 492 | | ---------- | --------- | -------- | ---------- | ---------- | -------------- | ------- | 493 | | test2.data | HashTable | 22456351 | 6 | 1 | 2.24564 | 96s | 494 | | test2.data | HotRing | 10816535 | 5 | 1 | 1.08165 | 84s | 495 | | test4.data | HashTable | 23549070 | 8 | 1 | 2.35491 | 99s | 496 | | test4.data | HotRing | 11057968 | 7 | 1 | 1.1058 | 83s | 497 | | test5.data | HashTable | 22783760 | 7 | 1 | 2.27838 | 96s | 498 | | test5.data | HotRing | 10882926 | 6 | 1 | 1.08829 | 83s | 499 | 500 | ## 测试评价 501 | 502 | 1. 从两组实验中findcnt指标与averageFindcnt可以明显看出:当工作负载相对平衡时,HotRing与HashTable的总查询次数没有明显差距;但在工作负载极度不平衡下,hotring的总查找此处远远低于HashTable,本次测试仅仅测试了$10^7$量级下的查询性能比较。当测试量级更大时,这种差距应该会更加明显。 503 | 2. 根据`test1.data`可知,由于HotRing的search操作需要更多的判断条件与处理,所以当查找次数差不多时,HotRing的时间开销是要大于HashTable的。(此处与HotRing功能的具体实现方式也有很大关系) 504 | 3. 根据键桶比这一组测试结果发现:随着键桶比的提升,对HashTable与HotRing的性能影响不是非常明显,与论文中的测试结果有明显差距,推测可能的原因是:测试数据的量级比较小($10^3$级),干扰因素造成的影响较大,偶然性也比较大。 505 | 4. 通过maxFindcnt来反应尾延迟的效果很差,原因我认为有以下几点: 506 | 507 | + maxFindcnt只能反应最差的一次查询操作所需要的查询次数,所以偶然性非常大,单次异常数据会直接导致指标失效。 508 | + 测试尾延迟更应该关注各次查询开销(本实验中为查找次数)的分布情况,单独一次操作产生的数据指标,意义不大。 509 | 510 | 5. minFindcnt指标基本无用,在大规模数据测试下,单独一次操作产生的数据指标统计意义很小。 511 | 512 | ## 问题与解决: 513 | 514 | ### HotRing耗时远高于HashTable 515 | 516 | 原因:在编写HotRing的search函数时,调用了new与delete,导致开销很大,严重影响了HotRing的性能。 517 | 518 | 解决:在HotRing结构体内部定义了一个用于比较的htEntry,查询操作中直接对该变量赋值即可,避免频繁new与delete。 519 | 520 | ### 当键桶比变大时,HashTable的性能有明显改善,甚至略优于HotRing 521 | 522 | 原因:在随机数据程序中,取key值时,用于随机数取余的MOD值为项数的十倍,由于总项数扩大了,所以随机数取值范围也扩大了,这有可能对hashfunction有影响。 523 | 524 | 解决:将MOD值固定为20000。 525 | 526 | ## 测试截图: 527 | 528 | test1.data: 529 | 530 | ![image-20200524011123719](img/image-20200524011123719.png) 531 | 532 | test2.data: 533 | 534 | ![image-20200524011500230](img/image-20200524011500230.png) 535 | 536 | test3.data: 537 | 538 | ![image-20200524011819115](img/image-20200524011819115.png) 539 | 540 | test4.data: 541 | 542 | ![image-20200524020134150](img/image-20200524020134150.png) 543 | 544 | test5.data: 545 | 546 | ![image-20200524020520732](img/image-20200524020520732.png) 547 | 548 | ## 代码: 549 | 550 | 随机数据生成:`radomdata.cpp` 551 | 552 | 数据文件:`test1.data`, `test2.data`, `test3.data`, `test4.data`, `test5.data` 553 | 554 | 测试程序:`hotring-r.h`, `hotring-r.cpp`, `hashTable.cpp`, `main.cpp` 555 | 556 | # 七、未来研究设想 557 | 558 | ## 设计热点感知算法 559 | 560 | ​ 作者在论文中提出了两种轻量级的热点感知算法,未来可以设计更多的热点感知算法来应对不同的应用场景,比如: 561 | 562 | + 可以尝试设计热点感知算法来提前预测热点的来临 563 | 564 | ## 优化数据结构 565 | 566 | ​ 可以在作者设计的HotRing结构基础上继续优化该数据结构,比如: 567 | 568 | + 加入前向指针,令HotRing面对RCU操作,删除操作时,可以迅速确定前一项的位置,并且可以解决[疑问1](##疑问1)。 569 | 570 | ## 运用热点感知方案到其他场景 571 | 572 | ​ 热点感知方案的核心思想是:**找到热点信息,将热点信息放在系统中可以较快访问到的位置。**那么,我们可以将统计采样策略移植到传统的关系型数据库中,或者移植到计算机内存与CPU之间,设计独立的模块,在CPU访问Cache之前,通过统计采样,为CPU提供可能需要被访问的数据。 573 | 574 | # 参考 575 | 576 | [keys961 Blog 论文阅读-HotRing: A Hotspot-Aware In-Memory Key-Value Store](https://keys961.github.io/2020/02/28/%E8%AE%BA%E6%96%87%E9%98%85%E8%AF%BB-HotRing-A-Hotspot-Aware-In-Memory-Key-Value-Store/) 577 | 578 | [Glitter试做一号机 HotRing: A Hotspot-Aware In-Memory Key-Value Store](https://www.jianshu.com/p/0777755969ab) 579 | 580 | [FAST '20 - HotRing: A Hotspot-Aware In-Memory Key-Value Store讲解视频](https://www.youtube.com/watch?v=NUmcE9BDvVE) 581 | 582 | [云栖社区 存储顶会FAST'20论文揭秘Tair创新性引擎](https://yq.aliyun.com/articles/746727?type=2) 583 | 584 | [多核原子操作与CAS操作](https://www.zhihu.com/question/64915964/answer/225710737) 585 | 586 | [RCU操作原理](https://www.ibm.com/developerworks/cn/linux/l-rcu/) 587 | 588 | 《C++ Primer 5th》 589 | 590 | 《Redis设计与实现》 591 | 592 | -------------------------------------------------------------------------------- /data/data12.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Focus5679/HotRing-simple-and-simple-demo/b1588b96c153a62f6a0eb797519e7ace12544675/data/data12.zip -------------------------------------------------------------------------------- /data/data345.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Focus5679/HotRing-simple-and-simple-demo/b1588b96c153a62f6a0eb797519e7ace12544675/data/data345.zip -------------------------------------------------------------------------------- /img/image-20200510172910121.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Focus5679/HotRing-simple-and-simple-demo/b1588b96c153a62f6a0eb797519e7ace12544675/img/image-20200510172910121.png -------------------------------------------------------------------------------- /img/image-20200511002856889.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Focus5679/HotRing-simple-and-simple-demo/b1588b96c153a62f6a0eb797519e7ace12544675/img/image-20200511002856889.png -------------------------------------------------------------------------------- /img/image-20200511203407929.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Focus5679/HotRing-simple-and-simple-demo/b1588b96c153a62f6a0eb797519e7ace12544675/img/image-20200511203407929.png -------------------------------------------------------------------------------- /img/image-20200511231816613.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Focus5679/HotRing-simple-and-simple-demo/b1588b96c153a62f6a0eb797519e7ace12544675/img/image-20200511231816613.png -------------------------------------------------------------------------------- /img/image-20200515205823151.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Focus5679/HotRing-simple-and-simple-demo/b1588b96c153a62f6a0eb797519e7ace12544675/img/image-20200515205823151.png -------------------------------------------------------------------------------- /img/image-20200516003719698.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Focus5679/HotRing-simple-and-simple-demo/b1588b96c153a62f6a0eb797519e7ace12544675/img/image-20200516003719698.png -------------------------------------------------------------------------------- /img/image-20200516003729841.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Focus5679/HotRing-simple-and-simple-demo/b1588b96c153a62f6a0eb797519e7ace12544675/img/image-20200516003729841.png -------------------------------------------------------------------------------- /img/image-20200516010000423.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Focus5679/HotRing-simple-and-simple-demo/b1588b96c153a62f6a0eb797519e7ace12544675/img/image-20200516010000423.png -------------------------------------------------------------------------------- /img/image-20200516010553517.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Focus5679/HotRing-simple-and-simple-demo/b1588b96c153a62f6a0eb797519e7ace12544675/img/image-20200516010553517.png -------------------------------------------------------------------------------- /img/image-20200523201030904.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Focus5679/HotRing-simple-and-simple-demo/b1588b96c153a62f6a0eb797519e7ace12544675/img/image-20200523201030904.png -------------------------------------------------------------------------------- /img/image-20200524011123719.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Focus5679/HotRing-simple-and-simple-demo/b1588b96c153a62f6a0eb797519e7ace12544675/img/image-20200524011123719.png -------------------------------------------------------------------------------- /img/image-20200524011500230.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Focus5679/HotRing-simple-and-simple-demo/b1588b96c153a62f6a0eb797519e7ace12544675/img/image-20200524011500230.png -------------------------------------------------------------------------------- /img/image-20200524011819115.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Focus5679/HotRing-simple-and-simple-demo/b1588b96c153a62f6a0eb797519e7ace12544675/img/image-20200524011819115.png -------------------------------------------------------------------------------- /img/image-20200524020134150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Focus5679/HotRing-simple-and-simple-demo/b1588b96c153a62f6a0eb797519e7ace12544675/img/image-20200524020134150.png -------------------------------------------------------------------------------- /img/image-20200524020520732.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Focus5679/HotRing-simple-and-simple-demo/b1588b96c153a62f6a0eb797519e7ace12544675/img/image-20200524020520732.png -------------------------------------------------------------------------------- /project/hotring-r/.vs/hotring-r/v15/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Focus5679/HotRing-simple-and-simple-demo/b1588b96c153a62f6a0eb797519e7ace12544675/project/hotring-r/.vs/hotring-r/v15/.suo -------------------------------------------------------------------------------- /project/hotring-r/.vs/hotring-r/v15/Browse.VC.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Focus5679/HotRing-simple-and-simple-demo/b1588b96c153a62f6a0eb797519e7ace12544675/project/hotring-r/.vs/hotring-r/v15/Browse.VC.db -------------------------------------------------------------------------------- /project/hotring-r/.vs/hotring-r/v15/ipch/8eb8dec412c8842c.ipch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Focus5679/HotRing-simple-and-simple-demo/b1588b96c153a62f6a0eb797519e7ace12544675/project/hotring-r/.vs/hotring-r/v15/ipch/8eb8dec412c8842c.ipch -------------------------------------------------------------------------------- /project/hotring-r/.vs/hotring-r/v15/ipch/AutoPCH/635422ef5a80d605/MAIN.ipch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Focus5679/HotRing-simple-and-simple-demo/b1588b96c153a62f6a0eb797519e7ace12544675/project/hotring-r/.vs/hotring-r/v15/ipch/AutoPCH/635422ef5a80d605/MAIN.ipch -------------------------------------------------------------------------------- /project/hotring-r/.vs/hotring-r/v15/ipch/AutoPCH/8ab8629a43859d90/HOTRING-R.ipch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Focus5679/HotRing-simple-and-simple-demo/b1588b96c153a62f6a0eb797519e7ace12544675/project/hotring-r/.vs/hotring-r/v15/ipch/AutoPCH/8ab8629a43859d90/HOTRING-R.ipch -------------------------------------------------------------------------------- /project/hotring-r/.vs/hotring-r/v15/ipch/AutoPCH/c2393d5872ef76d2/HASHTABLE.ipch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Focus5679/HotRing-simple-and-simple-demo/b1588b96c153a62f6a0eb797519e7ace12544675/project/hotring-r/.vs/hotring-r/v15/ipch/AutoPCH/c2393d5872ef76d2/HASHTABLE.ipch -------------------------------------------------------------------------------- /project/hotring-r/.vs/hotring-r/v15/ipch/AutoPCH/dd4a42fec6d8bf50/源.ipch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Focus5679/HotRing-simple-and-simple-demo/b1588b96c153a62f6a0eb797519e7ace12544675/project/hotring-r/.vs/hotring-r/v15/ipch/AutoPCH/dd4a42fec6d8bf50/源.ipch -------------------------------------------------------------------------------- /project/hotring-r/.vs/hotring-r/v15/ipch/AutoPCH/f149c52b281ad32d/MAIN.ipch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Focus5679/HotRing-simple-and-simple-demo/b1588b96c153a62f6a0eb797519e7ace12544675/project/hotring-r/.vs/hotring-r/v15/ipch/AutoPCH/f149c52b281ad32d/MAIN.ipch -------------------------------------------------------------------------------- /project/hotring-r/hotring-r.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28010.2036 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hotring-r", "hotring-r\hotring-r.vcxproj", "{3B726636-688D-495A-9634-662A74725672}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {3B726636-688D-495A-9634-662A74725672}.Debug|x64.ActiveCfg = Debug|x64 17 | {3B726636-688D-495A-9634-662A74725672}.Debug|x64.Build.0 = Debug|x64 18 | {3B726636-688D-495A-9634-662A74725672}.Debug|x86.ActiveCfg = Debug|Win32 19 | {3B726636-688D-495A-9634-662A74725672}.Debug|x86.Build.0 = Debug|Win32 20 | {3B726636-688D-495A-9634-662A74725672}.Release|x64.ActiveCfg = Release|x64 21 | {3B726636-688D-495A-9634-662A74725672}.Release|x64.Build.0 = Release|x64 22 | {3B726636-688D-495A-9634-662A74725672}.Release|x86.ActiveCfg = Release|Win32 23 | {3B726636-688D-495A-9634-662A74725672}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {9770AC07-CFCC-41C4-B256-5C9D608683E1} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /project/hotring-r/hotring-r/Debug/hotring-r.log: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /project/hotring-r/hotring-r/hashTable.cpp: -------------------------------------------------------------------------------- 1 | #include "hotring-r.h" 2 | 3 | ht::ht(unsigned int sz) :table(0), findcnt(0), minFindcnt(0x7fffffff), maxFindcnt(0) 4 | { 5 | unsigned int htsz = 1; 6 | while (htsz < sz) htsz <<= 1; 7 | this->table.resize(htsz, nullptr); 8 | size = htsz; 9 | sizemask = htsz - 1; 10 | } 11 | 12 | unsigned int ht::hashFunction(const string & key) 13 | { 14 | unsigned int hash = 5381; 15 | 16 | for (char c : key) 17 | { 18 | hash += (hash << 5) + c; 19 | } 20 | //return key[0] << 7; 21 | return (hash & 0x7FFFFFFF); 22 | } 23 | 24 | void ht::setMinMax(const unsigned int onecnt) 25 | { 26 | this->maxFindcnt = max(this->maxFindcnt, onecnt); 27 | this->minFindcnt = min(this->minFindcnt, onecnt); 28 | } 29 | 30 | bool ht::insert(const string & key, const string & val) 31 | { 32 | // 去重 33 | if (search(key) != nullptr) return false; 34 | 35 | unsigned int hashValue = hashFunction(key); 36 | unsigned int index = hashValue & this->sizemask; 37 | unsigned int tag = hashValue & (~this->sizemask); 38 | htEntry *newItem = new htEntry(key, val, nullptr, tag); 39 | htEntry *pre = nullptr; 40 | htEntry *nxt = nullptr; 41 | 42 | //头插法插入 43 | newItem->setNext(table[index]); 44 | table[index] = newItem; 45 | 46 | return true; 47 | } 48 | 49 | bool ht::remove(const string & key) 50 | { 51 | htEntry *p = search(key); 52 | unsigned int hashValue = hashFunction(key); 53 | unsigned int index = hashValue & this->sizemask; 54 | 55 | if (p == nullptr) return false; 56 | 57 | if (table[index] == p) 58 | { 59 | table[index] = p->getNext(); 60 | } 61 | else 62 | { 63 | htEntry *pre = table[index]; 64 | while (pre && pre->getNext() != p) 65 | { 66 | pre = pre->getNext(); 67 | } 68 | pre->setNext(p->getNext()); 69 | } 70 | delete p; 71 | return true; 72 | } 73 | 74 | bool ht::update(const string & key, const string & val) 75 | { 76 | htEntry *p = search(key); 77 | if (p == nullptr) return false; 78 | p->setVal(val); 79 | return true; 80 | } 81 | 82 | htEntry *ht::search(const string & key) 83 | { 84 | unsigned int hashValue = hashFunction(key); 85 | unsigned int index = hashValue & this->sizemask; 86 | htEntry *p = table[index]; 87 | unsigned int precnt = findcnt; 88 | bool hotspotAware = false; 89 | 90 | ++this->findcnt; 91 | while (p && p->getKey() != key) { 92 | ++this->findcnt; 93 | p = p->getNext(); 94 | } 95 | setMinMax(this->findcnt - precnt); 96 | return p; 97 | } 98 | 99 | unsigned int ht::getfindcnt() 100 | { 101 | return this->findcnt; 102 | } 103 | 104 | unsigned int ht::getmaxFindcnt() 105 | { 106 | return this->maxFindcnt; 107 | } 108 | 109 | unsigned int ht::getminFindcnt() 110 | { 111 | return this->minFindcnt; 112 | } 113 | 114 | -------------------------------------------------------------------------------- /project/hotring-r/hotring-r/hotring-r.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Focus5679/HotRing-simple-and-simple-demo/b1588b96c153a62f6a0eb797519e7ace12544675/project/hotring-r/hotring-r/hotring-r.cpp -------------------------------------------------------------------------------- /project/hotring-r/hotring-r/hotring-r.h: -------------------------------------------------------------------------------- 1 |  2 | #pragma once 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | class htEntry { 9 | public: 10 | htEntry(const string &k, const string &v, htEntry *n, unsigned int t, unsigned char o, unsigned char r): 11 | key(k), val(v), next(n), tag(t), occupied(o), rehash(r) {} 12 | 13 | htEntry() : htEntry("", "", nullptr, 0, 0, 0) {} 14 | htEntry(const string &k, const string &v, htEntry *n, unsigned int t) : htEntry(k, v, n, t, 0, 0) {} 15 | htEntry(const string &k, unsigned t) : htEntry(k, "", nullptr, t, 0, 0){} 16 | 17 | string getKey()const; 18 | void setKey(const string &s); 19 | 20 | string getVal()const; 21 | void setVal(const string &s); 22 | 23 | htEntry *getNext()const; 24 | void setNext(htEntry *n); 25 | 26 | unsigned int getTag()const; 27 | void setTag(const unsigned int t); 28 | 29 | unsigned char getOccupied()const; 30 | void setOccupied(const unsigned char o); 31 | 32 | unsigned char getRehash()const; 33 | void setRehash(const unsigned char r); 34 | 35 | bool operator < (const htEntry &other); 36 | 37 | 38 | private: 39 | 40 | string key; // 键 41 | string val; // 值 42 | 43 | unsigned int tag; // tag值 44 | unsigned char occupied; // 占用标识,多线程实现时启用 45 | unsigned char rehash; // rehash标识 46 | 47 | htEntry *next; // 指向下个哈希表节点,形成链表 48 | }; 49 | 50 | class hotring { 51 | public: 52 | //构造函数 53 | hotring(unsigned int sz); 54 | ~hotring(); 55 | 56 | //插入 57 | bool insert(const string &key, const string &val); 58 | //删除 59 | bool remove(const string &key); 60 | //更新 61 | bool update(const string &key, const string &val); 62 | //查找 63 | htEntry *search(const string &key); 64 | 65 | unsigned int getfindcnt(); 66 | unsigned int getmaxFindcnt(); 67 | unsigned int getminFindcnt(); 68 | private: 69 | // 计算哈希值的函数 70 | unsigned int hashFunction(const string &key); 71 | 72 | // 测试所用函数 73 | void setMinMax(const unsigned int onecnt); 74 | 75 | private: 76 | vector table; // 哈希表数组 77 | unsigned int size; // 哈希表大小 78 | unsigned int sizemask; // 哈希表大小掩码,用于计算索引值 总是等于size-1 79 | unsigned int r; // 记录访问次数当r==R时,开始热点转移 80 | htEntry *compareItem; // 用于查询时比较 81 | 82 | // 测试所用变量 83 | const unsigned int R = 5; // 控制多少次访问后进行热点转移 84 | unsigned int findcnt; // 统计总的查找次数 85 | unsigned int maxFindcnt; // 统计最大查找次数,一定程度上反应尾延迟 86 | unsigned int minFindcnt; // 统计最小查找次数 87 | }; 88 | 89 | 90 | class ht { 91 | public: 92 | //构造函数 93 | ht(unsigned int sz); 94 | 95 | 96 | //插入 97 | bool insert(const string &key, const string &val); 98 | //删除 99 | bool remove(const string &key); 100 | //更新 101 | bool update(const string &key, const string &val); 102 | //查找 103 | htEntry *search(const string &key); 104 | 105 | unsigned int getfindcnt(); 106 | unsigned int getmaxFindcnt(); 107 | unsigned int getminFindcnt(); 108 | private: 109 | // 计算哈希值的函数 110 | unsigned int hashFunction(const string &key); 111 | 112 | // 测试所用函数 113 | void setMinMax(const unsigned int onecnt); 114 | 115 | private: 116 | vector table; // 哈希表数组 117 | unsigned int size; // 哈希表大小 118 | unsigned int sizemask; // 哈希表大小掩码,用于计算索引值 总是等于size-1 119 | unsigned int r; // 记录访问次数当r==R时,开始热点转移 120 | 121 | // 测试所用变量 122 | const unsigned int R = 5; // 控制多少次访问后进行热点转移 123 | unsigned int findcnt; // 统计总的查找次数 124 | unsigned int maxFindcnt; // 统计最大查找次数,一定程度上反应尾延迟 125 | unsigned int minFindcnt; // 统计最小查找次数 126 | }; -------------------------------------------------------------------------------- /project/hotring-r/hotring-r/hotring-r.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {3B726636-688D-495A-9634-662A74725672} 24 | Win32Proj 25 | hotringr 26 | 10.0.17134.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v141 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v141 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v141 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v141 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | true 78 | 79 | 80 | false 81 | 82 | 83 | false 84 | 85 | 86 | 87 | NotUsing 88 | Level3 89 | Disabled 90 | false 91 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 92 | true 93 | pch.h 94 | 95 | 96 | Console 97 | true 98 | 99 | 100 | 101 | 102 | Use 103 | Level3 104 | Disabled 105 | true 106 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 107 | true 108 | pch.h 109 | 110 | 111 | Console 112 | true 113 | 114 | 115 | 116 | 117 | Use 118 | Level3 119 | MaxSpeed 120 | true 121 | true 122 | true 123 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 124 | true 125 | pch.h 126 | 127 | 128 | Console 129 | true 130 | true 131 | true 132 | 133 | 134 | 135 | 136 | Use 137 | Level3 138 | MaxSpeed 139 | true 140 | true 141 | true 142 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 143 | true 144 | pch.h 145 | 146 | 147 | Console 148 | true 149 | true 150 | true 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /project/hotring-r/hotring-r/hotring-r.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | 源文件 23 | 24 | 25 | 源文件 26 | 27 | 28 | 29 | 30 | 头文件 31 | 32 | 33 | -------------------------------------------------------------------------------- /project/hotring-r/hotring-r/hotring-r.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /project/hotring-r/hotring-r/main.cpp: -------------------------------------------------------------------------------- 1 | #include "hotring-r.h" 2 | #include 3 | #include 4 | #include 5 | 6 | #define inputfile "test5.data" 7 | 8 | const int N = 10000000; //总访问数 9 | const int M = 1000; //总项数 10 | 11 | int main() 12 | { 13 | time_t start, stop; 14 | string key; 15 | string val; 16 | ht h(M); 17 | hotring hr(M); 18 | 19 | 20 | 21 | fstream input(inputfile); 22 | 23 | 24 | 25 | for (int i = 0; i < M; ++i) { 26 | input >> key >> val; 27 | h.insert(key, val); 28 | } 29 | 30 | start = time(NULL); 31 | while(input >> key){ 32 | h.search(key); 33 | } 34 | stop = time(NULL); 35 | 36 | cout << "HashTable:" << endl; 37 | cout << "findcnt:" << h.getfindcnt() << "次" << endl; 38 | cout << "maxFindcnt:" << h.getmaxFindcnt() << "次" << endl; 39 | cout << "minFindcnt:" << h.getminFindcnt() << "次" << endl; 40 | cout << "averageFindcnt:" << (double)h.getfindcnt() / N << "次" << endl; 41 | cout << "Use Time:" << (stop - start) << "s" << endl << endl; 42 | 43 | 44 | 45 | 46 | input.close(); 47 | input.open(inputfile); 48 | 49 | 50 | 51 | for (int i = 0; i < M; ++i) { 52 | input >> key >> val; 53 | hr.insert(key, val); 54 | } 55 | 56 | start = time(NULL); 57 | while (input >> key) { 58 | hr.search(key); 59 | } 60 | stop = time(NULL); 61 | 62 | cout << "HotRing:" << endl; 63 | cout << "findcnt:" << hr.getfindcnt() << "次" << endl; 64 | cout << "maxFindcnt:" << hr.getmaxFindcnt() << "次" << endl; 65 | cout << "minFindcnt:" << hr.getminFindcnt() << "次" << endl; 66 | cout << "averageFindcnt:" << (double)hr.getfindcnt() / N << "次" << endl; 67 | cout << "Use Time:" << (stop - start) << "s" << endl; 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /project/other code/formula1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: zsw 3 | * @Date: 2020-05-20 16:41:29 4 | * @Last Modified by: mikey.zhaopeng 5 | * @Last Modified time: 2020-05-20 16:41:29 6 | */ 7 | #include 8 | #include 9 | #include 10 | 11 | typedef long long ll; 12 | 13 | using namespace std; 14 | 15 | int N = 100; //总项数 16 | int B = 10; //总桶数 17 | int L = N/B; //总链数 18 | 19 | double Echain = 0; //预期访问内存次数 20 | 21 | int main(){ 22 | Echain = 1.0 + L/2; 23 | printf("Echain = %lf\n", Echain); 24 | return 0; 25 | } -------------------------------------------------------------------------------- /project/other code/formula2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | typedef long long ll; 6 | 7 | using namespace std; 8 | 9 | int N = 10000000; //总项数 10 | double theta = 1; //偏度因子 11 | 12 | double sum = 0; //频率之和 13 | double last_sum = 0; 14 | 15 | ll qpow(ll n, ll p){ 16 | ll res = 1; 17 | ll base = n; 18 | while(p){ 19 | if(p&1) res *= base; 20 | p = p >> 1; 21 | base = base * base; 22 | } 23 | return res; 24 | } 25 | double f(int x){ 26 | static double denominator = 0; //分母 27 | if(denominator == 0){ 28 | //计算分母,避免重复计算 29 | for(int i = 1; i <= N; ++i){ 30 | denominator += 1.0/qpow(i, theta); 31 | } 32 | } 33 | double res = (1.0/qpow(x, theta)) / denominator; 34 | return res; 35 | } 36 | int main(){ 37 | int div = N/100; 38 | for(int i = 1; i <= N; ++i){ 39 | double percent = f(i)*100; 40 | sum += percent; 41 | if(i % div == 0){ 42 | printf("%3dth=%8.5lf%% ", i/div, (sum - last_sum)); 43 | last_sum = sum; 44 | } 45 | 46 | if(i % (div*10) == 0) puts(""); 47 | } 48 | printf("%lf%%\n", sum); 49 | return 0; 50 | } -------------------------------------------------------------------------------- /project/other code/formula3.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | typedef long long ll; 6 | 7 | using namespace std; 8 | 9 | int N = 10000000; //总项数 10 | int B = 1000; //总桶数 11 | int L = N/B; //总链数 12 | double theta = 1; //偏度因子 13 | 14 | double Echain = 0; //传统冲突链表访问内存的预期次数 15 | double Eideal = 0; //应用热点感知后理想访问内存的预期次数 16 | 17 | ll qpow(ll n, ll p){ 18 | ll res = 1; 19 | ll base = n; 20 | while(p){ 21 | if(p&1) res *= base; 22 | p = p >> 1; 23 | base = base * base; 24 | } 25 | return res; 26 | } 27 | double f(int x){ 28 | static double denominator = 0; //分母 29 | if(denominator == 0){ 30 | //计算分母,避免重复计算 31 | for(int i = 1; i <= N; ++i){ 32 | denominator += 1.0/qpow(i, theta); 33 | } 34 | } 35 | double res = (1.0/qpow(x, theta)) / denominator; 36 | return res; 37 | } 38 | double F(int k){ 39 | double res = 0; 40 | for(int i = (k-1)*B+1; i <= k*B; ++i){ 41 | res += f(i); 42 | } 43 | return res; 44 | } 45 | int main(){ 46 | Echain = 1.0 + L/2; 47 | Eideal = 1.0; 48 | for(int k = 1; k <= L; ++k){ 49 | Eideal += F(k)*k; 50 | } 51 | printf("Echain = %lf Eideal = %lf\n", Echain, Eideal); 52 | return 0; 53 | } -------------------------------------------------------------------------------- /project/other code/radomdata.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #define outfile "test5.data" 13 | typedef long long ll; 14 | 15 | using namespace std; 16 | 17 | const int N = 10000000; //总访问数 18 | const int M = 8000; //总项数 19 | const int MOD = 20000; //取值时 20 | double theta = 1; //偏度因子 21 | 22 | double sum = 0; //频率之和 23 | double last_sum = 0; 24 | 25 | int vis[MOD + 50]; //用于保证随机时,key唯一 26 | vector frequency; //量级N下,各部分请求的频数 27 | vector > dta;//表示数据库已有的数据 28 | 29 | 30 | ll qpow(ll n, ll p) { 31 | ll res = 1; 32 | ll base = n; 33 | while (p) { 34 | if (p & 1) res *= base; 35 | p = p >> 1; 36 | base = base * base; 37 | } 38 | return res; 39 | } 40 | double f(int x) { 41 | static double denominator = 0; //分母 42 | if (denominator == 0) { 43 | //计算分母,避免重复计算 44 | for (int i = 1; i <= N; ++i) { 45 | denominator += 1.0 / qpow(i, theta); 46 | } 47 | } 48 | double res = (1.0 / qpow(x, theta)) / denominator; 49 | return res; 50 | } 51 | //将数组转成字符串 52 | string itos(int x) { 53 | string res; 54 | while (x) { 55 | res.push_back(x % 10 + '0'); 56 | x /= 10; 57 | } 58 | reverse(res.begin(), res.end()); 59 | return res; 60 | } 61 | 62 | 63 | int main() { 64 | int ed = 99; 65 | int div = N / 100; 66 | int key, val; 67 | int r; 68 | int fre; 69 | 70 | //计算当前量级下,访问分布的频数 71 | for (int i = 1; i <= N; ++i) { 72 | double percent = f(i); 73 | sum += percent; 74 | if (i % div == 0) { 75 | fre = (sum - last_sum)*N; 76 | //printf("%3dth=%8d", i / div, fre); 77 | frequency.push_back(fre); 78 | last_sum = sum; 79 | } 80 | //if (i % (div * 10) == 0) puts(""); 81 | } 82 | 83 | freopen(outfile, "w", stdout); 84 | srand((unsigned)time(NULL)); 85 | 86 | for (int i = 0; i < M; ++i) { 87 | while (vis[key = rand() % MOD]) {} //去重,得到一个不与其他key值重复的新key值 88 | vis[key] = 1; 89 | val = rand() % MOD; 90 | dta.push_back(pair(itos(key), itos(val))); 91 | printf("%d %d\n", key, val); 92 | } 93 | 94 | //模拟访问请求 95 | while (frequency[0]) { 96 | for (int i = 0; i <= ed; ++i) { 97 | if (frequency[i] > 0) { 98 | --frequency[i]; 99 | r = rand() % 10; 100 | printf("%s\n", dta[i * 10 + r].first.c_str()); 101 | } 102 | else { 103 | --ed; 104 | } 105 | } 106 | } 107 | return 0; 108 | } -------------------------------------------------------------------------------- /research report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Focus5679/HotRing-simple-and-simple-demo/b1588b96c153a62f6a0eb797519e7ace12544675/research report.pdf --------------------------------------------------------------------------------