CN110928483A - 数据存储、数据获取方法及设备 - Google Patents
数据存储、数据获取方法及设备 Download PDFInfo
- Publication number
- CN110928483A CN110928483A CN201811095845.8A CN201811095845A CN110928483A CN 110928483 A CN110928483 A CN 110928483A CN 201811095845 A CN201811095845 A CN 201811095845A CN 110928483 A CN110928483 A CN 110928483A
- Authority
- CN
- China
- Prior art keywords
- array
- hash
- key
- value
- storage
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Granted
Links
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F3/00—Input arrangements for transferring data to be processed into a form capable of being handled by the computer; Output arrangements for transferring data from processing unit to output unit, e.g. interface arrangements
- G06F3/06—Digital input from, or digital output to, record carriers, e.g. RAID, emulated record carriers or networked record carriers
- G06F3/0601—Interfaces specially adapted for storage systems
- G06F3/0628—Interfaces specially adapted for storage systems making use of a particular technique
- G06F3/0638—Organizing or formatting or addressing of data
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F3/00—Input arrangements for transferring data to be processed into a form capable of being handled by the computer; Output arrangements for transferring data from processing unit to output unit, e.g. interface arrangements
- G06F3/06—Digital input from, or digital output to, record carriers, e.g. RAID, emulated record carriers or networked record carriers
- G06F3/0601—Interfaces specially adapted for storage systems
- G06F3/0602—Interfaces specially adapted for storage systems specifically adapted to achieve a particular effect
- G06F3/0608—Saving storage space on storage systems
Landscapes
- Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Human Computer Interaction (AREA)
- Physics & Mathematics (AREA)
- General Engineering & Computer Science (AREA)
- General Physics & Mathematics (AREA)
- Information Retrieval, Db Structures And Fs Structures Therefor (AREA)
Abstract
本申请提供了一种数据存储方法。该方法通过将键值对的键从对象转换为哈希值,将键值对的值从对象转换为实例数据,改进了键和值本身的数据结构,去除了键和值的对象头以及对齐填充等部分,也就节省了对象头以及对齐填充占用的存储空间,因此减少了键值对中对象本身的存储开销,实现了对键值对压缩存储的功能,提高了键值存储的效率,降低了由于内存空间过大而触发的内存回收等问题的概率,从而提高存储系统的性能。
Description
技术领域
本申请涉及存储技术领域,特别涉及一种数据存储、数据获取方法及设备。
背景技术
键值(key-value,缩写:KV)存储是一种重要的存储技术。使用键值存储时,会将数据按照键值对的形式进行组织、索引和存储。对于任一键值对来说,根据该键值对的键进行键值查询,即可得到该键值对的值。
在JAVA等面向对象的程序语言中,任意键值对的键是一种对象,任意键值对的值也是一种对象。在数据存储阶段,当得到需要存储的键值对时,会确定键值对的键,得到键对象,确定键值对的值,得到值对象,以键对象为键,以值对象为值,进行键值存储。在数据查询阶段,当得到键对象时,会以键对象为键,进行键值查询,得到值对象,输出值对象。
目前的键值对的数据量较大,键值对占用的存储空间较多,影响了存储设备的存储性能。
发明内容
本申请实施例提供了一种数据存储、数据获取方法及设备,能够解决相关技术中键值对的数据量较大、占用的存储空间较多的技术问题。所述技术方案如下:
第一方面,提供了一种数据存储方法,所述方法包括:
获取待处理的键值对,所述键值对的键为第一对象,所述键值对的值为第二对象;
对所述第一对象进行处理,得到所述第一对象的哈希值;
对所述第二对象进行拆箱转换,得到所述第二对象的实例数据;
将所述哈希值和所述实例数据分别存储至第一数组和第二数组,所述第一数组和所述第二数组不同。
本实施例提供的方法,通过将键值对的键从对象转换为哈希值,将键值对的值从对象转换为实例数据,改进了键和值本身的数据结构,去除了键和值的对象头以及对齐填充等部分,从而节省了对象头以及对齐填充占用的存储空间,因此减少了键值对中对象本身带来的存储开销,实现了对键值对进行压缩存储的功能,减少了键值存储需要占用的存储空间,提高了键值存储的效率。并且,通过改进了基于链表的存储结构,使用多数组的存储结构存储键值对,可以避免遍历链表中的节点造成的时间开销,从而提高存储键值对的速度。尤其是,应用在通过内存空间存储键值对的场景中,通过节约键值对中对象本身占用的内存,可以极大地节约键值对占用的内存空间,也就降低了键值对占用的内存空间过大时会触发的内存回收以及其他资源和性能问题的概率,因此可以显著地提高存储系统的性能。
可选地,所述对所述第一对象进行处理,得到所述第一对象的哈希值,包括:
获取所述第一对象包括的所述哈希值。
通过这种可选方式,若第一对象本身就封装了哈希值,则可以直接获取第一对象本身的哈希值,从而复用该哈希值以进行存储,而无需进行哈希运算,从而提高了运算效率。
可选地,所述对所述第一对象进行处理,得到所述第一对象的哈希值,包括:
对所述第一对象进行哈希运算,得到所述哈希值。
可选地,所述获取待处理的键值对,包括:
从哈希表的链表的任一节点中读取所述键值对。
通过这种可选方式,可以实现数据迁移的功能,达到性能优化的效果。具体来说,通过从哈希表的链表的节点中读取键值对,将键值对压缩后存储至第一数组和第二数组中,可以将哈希表中键值对本身的数据结构从对象优化为数据,同时将哈希表的链表存储结构优化为多数组的存储结构,从而将原有的哈希表转换为数据结构和存储结构更加优化的哈希表,从而实现数据存储方式的平滑过渡,提高了灵活性。
可选地,所述将所述哈希值和所述实例数据分别存储至第一数组和第二数组,包括:
向所述第一数组的第一位置添加所述哈希值;
根据所述第一位置,在所述第二数组中,获取所述第一位置对应的第二位置;
向所述第二数组的所述第二位置添加所述实例数据。
通过这种可选方式,可以实现使用开放地址存储法存储键值对的功能,从而提高存储键值对的速度。具体来说,当在第一数组的第一位置添加哈希值后,可以根据该第一位置,直接在第二数组中定位到对应的第二位置,从而直接向第二位置添加第二对象的实例数据。相对于链地址法来说,由于无需遍历链表中的每个节点,也无需对链表中每个节点存储的键与待处理的键值对的键进行逐个比对,即可完成对键值对中值的存储,因此可以提高键值对中值的存储速度,从而极大地提高键值对的存储效率。
可选地,所述将所述哈希值和所述实例数据分别存储至第一数组和第二数组,包括:
当未检测到哈希冲突事件时,将所述哈希值和所述实例数据分别存储至所述第一数组和所述第二数组;
所述方法还包括:
当检测到哈希冲突事件时,将所述第一对象和所述实例数据分别存储至第三数组和第四数组,所述第三数组和所述第四数组不同。
通过这种可选方式,可以根据是否检测到哈希冲突事件,灵活地选择不同的存储方式。若未检测到哈希冲突事件,则将键转换成的哈希值和值转换成的实例数据分别存储至第一数组和第二数组,从而实现键和值均压缩存储的功能。若检测到哈希冲突事件,则将键转换前的第一对象和值转换成的实例数据分别存储至第三数组和第四数组,从而实现值压缩存储的功能。通过在检测到哈希冲突事件进行退化,可以降低哈希冲突事件的概率,也就节省了在键值对触发哈希冲突事件时,要为键值对重新探测存储位置所带来的处理资源开销以及时间开销,因此可以显著地提高存储系统的性能。
可选地,所述将所述第一对象和所述实例数据分别存储至第三数组和第四数组,包括:
向所述第三数组的第三位置添加所述第一对象;
根据所述第三位置,在所述第四数组中,获取所述第三位置对应的第四位置;
向所述第四数组的所述第四位置添加所述实例数据。
通过这种可选方式,可以实现使用开放地址存储法存储键值对的功能,从而提高存储键值对的速度。具体来说,当在第三数组的第三位置添加第一对象后,可以根据该第三位置,直接在第四数组中定位到对应的第四位置,从而直接向第四位置添加第四对象的实例数据,以完成对键值对中值的压缩存储。相对于链地址法来说,由于无需遍历链表中的每个节点,也无需对链表中每个节点存储的键与待处理的键值对的键进行逐个比对,即可完成对键值对中值的存储,可以提高键值对中值的存储速度,从而极大地提高键值存储效率。
可选地,所述将所述第一对象和所述实例数据分别存储至第三数组和第四数组之前,所述方法还包括:
根据哈希表的哈希冲突历史记录,对所述哈希冲突事件进行检测,所述哈希表已存储所述键值对。
基于这种可选的检测方式,可以根据哈希表的哈希冲突历史记录,提前预知存储键值对时是否具有触发哈希冲突事件的概率,则在存储键值对的过程中,可以直接预先得到的哈希冲突事件的检测结果,确定对键值对采用的压缩存储方式,从而极大的降低哈希冲突事件的概率。
可选地,所述根据哈希表的哈希冲突历史记录,对哈希冲突事件进行检测,包括:
当所述哈希冲突历史记录包括所述键值对的哈希冲突记录时,检测到所述哈希冲突事件。
通过这种可选的检测方式,可以实现单条退化存储的功能。具体来说,对于任一个键值对,当检测到该键值对会触发哈希冲突事件时,则对于该键值对,可以将第一对象的哈希值和第二对象的实例数据分别存储至第一数组和第二数组;而当检测到该键值对不会触发哈希冲突事件时,则对于该键值对,可以将第一对象和第二对象的实例数据分别存储至第三数组和第四数组。如此,可以针对该键值对的检测结果,从键和值均进行压缩存储的方式以及键退化而值进行压缩存储的方式中,为该键值对选择一种压缩存储方式,对该键值对进行存储。进一步地,当需要存储多个键值对时,可以分别检测每个键值对是否会触发哈希冲突事件,根据每个键值对是否会触发哈希冲突事件,分别为每个键值对选择对应的压缩存储方式,如此,可以为同一哈希表中的不同键值对,分别采用不同的压缩存储方式进行存储,极大地提高键值存储以及哈希存储的灵活性。
可选地,所述根据哈希表的哈希冲突历史记录,对哈希冲突事件进行检测,包括:
当所述哈希冲突历史记录包括所述哈希表中任一键值对的哈希冲突记录时,检测到所述哈希冲突事件。
通过这种可选的检测方式,可以实现整体退化存储的功能。具体来说,当哈希表中的任一键值对在历史存储过程中,触发了哈希冲突事件,使得哈希冲突历史记录中包括该键值对的哈希冲突记录时,会检测到哈希冲突事件,则对于哈希表中的每个键值对,均可以将第一对象和第二对象的实例数据分别存储至第三数组和第四数组;而当哈希表中的所有键值对在历史存储过程中,均未触发哈希冲突事件,使得哈希冲突历史记录中不包括任一键值对的哈希冲突记录时,不会检测到哈希冲突事件,则对于哈希表中的每个键值对,均可以将第一对象的哈希值和第二对象的实例数据分别存储至第一数组和第二数组。如此,可以针对哈希表的整体检测结果,从键和值均进行压缩的存储方式以及键退化而值压缩的存储方式中,为该哈希表中的所有键值对选择同一种压缩存储方式,对该哈希表整体进行压缩存储。
第二方面,提供了一种数据获取方法,所述方法包括:
根据数据获取指令中的第一对象,获取所述第一对象的哈希值;
在第一数组中,获取所述哈希值所处的位置,得到第一位置;
根据所述第一位置,在第二数组中,获取所述第一位置对应的第二位置,所述第二数组和所述第一数组不同;
从所述第二数组的所述第二位置读取第二对象的实例数据;
对所述第二对象的实例数据进行装箱转换,得到所述第二对象。
本实施例提供的方法,根据第一对象的哈希值在第一数组所处的第一位置,可以在第二数组中,直接定位到第一位置对应的第二位置,从第二位置读取第二对象的实例数据,通过装箱转换,即可得到第二对象,而无需遍历链表中的每个节点,因此避免了遍历链表中的节点所造成的时间开销,可以提高读取键值对的值的速度,从而提高存储系统的性能。
可选地,所述方法还包括:
当检测到哈希冲突事件时,在第三数组中,获取所述第一对象所处的位置,得到第三位置;
根据所述第三位置,在第四数组中,获取所述第三位置对应的第四位置,所述第四数组和所述第三数组不同;
从所述第四数组的所述第四位置读取所述第二对象。
通过这种可选方式,当检测到哈希冲突事件时,可以根据第一对象在第一数组所处的第一位置,直接在第二数组中,定位到第一位置对应的第二位置,从第二位置读取第二对象,一方面,由于无需遍历链表中的每个节点,也就避免了遍历链表中的节点所造成的时间开销,因此可以提高读取键值对的值的速度,从而提高存储系统的性能。另一方面,可以降低哈希冲突事件的概率,也就节省了在键值对触发哈希冲突事件时,要为键值对重新探测存储位置带来的处理资源开销以及时间开销,因此可以显著地提高存储系统的性能。
第三方面,提供了一种计算设备,所述计算设备用于执行上述数据存储方法。具体地,所述计算设备包括用于执行上述第一方面或第一方面的任一种可选方式所述的数据存储方法的功能模块。
第四方面,提供了一种计算设备,所述计算设备用于执行上述数据获取方法。具体地,所述计算设备包括用于执行上述第二方面或第二方面的任一种可选方式所述的数据获取方法的功能模块。
第五方面,提供一种计算设备,所述计算设备包括处理器和存储器,所述存储器中存储有至少一条指令,所述指令由所述处理器加载并执行以实现上述第一方面或第一方面的任一种可选方式所述的数据存储方法所执行的操作。
第六方面,提供一种计算设备,所述计算设备包括处理器和存储器,所述存储器中存储有至少一条指令,所述指令由所述处理器加载并执行以实现上述第二方面或第二方面的任一种可选方式所述的数据获取方法所执行的操作。
第七方面,提供了一种计算设备集群,该计算设备集群包括至少一个计算设备。上述第三方面中不同的模块可以分布在所述计算设备集群中的不同的计算设备上运行。具体来说,每个计算设备包括处理器和存储器。至少一个计算设备的处理器用于访问所述存储器中的代码以执行第一方面或第一方面的任意可选方式提供的数据存储方法。
第八方面,提供了一种计算设备集群,该计算设备集群包括至少一个计算设备。上述第四方面中不同的模块可以分布在该计算设备集群中的不同的计算设备上运行。具体来说,每个计算设备包括处理器和存储器。至少一个计算设备的处理器用于访问所述存储器中的代码以执行第二方面或第二方面的任意可选方式提供的数据获取方法。
第九方面,提供一种非瞬态的可读存储介质,所述非瞬态的可读存储介质被至少一台计算设备执行时,所述至少一台计算设备执行前述第一方面或第一方面的任意可选方式中提供的数据存储方法。所述存储介质中存储了程序。所述存储介质的类型包括但不限于易失性存储器,例如随机访问存储器,非易失性存储器,例如快闪存储器、硬盘(harddisk drive,HDD)、固态硬盘(solid state drive,缩写:SSD)。
第十方面,提供一种非瞬态的可读存储介质,所述非瞬态的可读存储介质被至少一台计算设备执行时,所述至少一台计算设备执行前述第二方面或第二方面的任意可选方式中提供的数据获取方法。所述存储介质中存储了程序。所述存储介质的类型包括但不限于易失性存储器,例如随机访问存储器,非易失性存储器,例如快闪存储器、硬盘、固态硬盘。
第十一方面,提供了一种包含指令的计算机程序产品,所述计算设备程序产品被至少一台计算设备执行时,所述至少一台计算设备执行前述第一方面或第一方面的任意可选方式中提供的数据存储方法。该计算机程序产品可以为一个软件安装包,在需要使用前述第一方面或第一方面的任意可选方式中提供的数据存储方法的情况下,可以下载该计算机程序产品并在计算设备上执行该计算机程序产品。
第十二方面,提供了一种包含指令的计算机程序产品,所述计算设备程序产品被至少一台计算设备执行时,所述至少一台计算设备执行前述第二方面或第二方面的任意可选方式中提供的数据获取方法。该计算机程序产品可以为一个软件安装包,在需要使用前述第二方面或第二方面的任意可选方式中提供的数据获取方法的情况下,可以下载该计算机程序产品并在计算设备上执行该计算机程序产品。
第十三方面,提供一种存储系统,在一种可能的实现方式中,所述系统包括:第三方面所述的计算设备和第四方面所述的计算设备。在另一种可能的实现方式中,所述系统包括:第七方面所述的计算设备集群和第八方面所述的计算设备集群。在另一种可能的实现方式中,所述系统包括:第三方面所述的计算设备和第七方面所述的计算设备集群。在另一种可能的实现方式中,所述系统包括:第四方面所述的计算设备和第八方面所述的计算设备集群。
第十四方面,提供了一种芯片,所述芯片包括处理器和/或程序指令,当所述芯片运行时,实现上述第一方面或第一方面的任一种可选方式所述的数据存储方法。
第十五方面,提供了一种芯片,所述芯片包括处理器和/或程序指令,当所述芯片运行时,实现上述第二方面或第二方面的任一种可选方式所述的数据获取方法。
附图说明
图1是本申请实施例提供的一种数据存储方法的流程图;
图2是本申请实施例提供的一种第一对象的结构示意图;
图3是本申请实施例提供的一种第二对象的结构示意图;
图4是本申请实施例提供的一种哈希表的结构示意图;
图5是本申请实施例提供的一种哈希表中链表的节点的结构示意图;
图6是本申请实施例提供的一种键值对的键在压缩前后的对比图;
图7是本申请实施例提供的一种键值对的值在压缩前后的对比图;
图8是本申请实施例提供的一种优化后的哈希表的结构示意图;
图9是本申请实施例提供的一种键值存储的逻辑框架图;
图10是本申请实施例提供的一种数据存储方法的流程图;
图11是本申请实施例提供的一种数据存储方法的初始化过程的流程图;
图12是本申请实施例提供的一种数据获取方法的流程图;
图13是本申请实施例提供的一种数据获取方法的流程图;
图14是本申请实施例提供的一种计算设备的结构示意图;
图15是本申请实施例提供的一种计算设备的结构示意图。
图16是本申请实施例提供的一种计算设备的结构示意图;
图17为本申请实施例提供的一种计算设备集群的结构示意图;
图18为本申请实施例提供的一种计算设备集群的结构示意图;
图19是本申请实施例提供的一种计算设备的结构示意图;
图20为本申请实施例提供的一种计算设备集群的结构示意图;
图21为本申请实施例提供的一种计算设备集群的结构示意图。
具体实施方式
为使本申请的目的、技术方案和优点更加清楚,下面将结合附图对本申请实施方式作进一步地详细描述。
以下对本申请涉及的技术术语进行解释:
(1)对象
对象是Java等面向对象的程序语言中数据存储的基本单位。对象通常包括对象头(英文:header)、实例数据(英文:instance data)以及对齐填充(英文:padding)。对象头包括对象运行时产生的数据以及对象所属的类等信息,实例数据包括对象中的有效数据,对齐填充用于将对象的大小补全到8字节的整数倍。
(2)数据类型
数据类型可以包括数字类型、字符类型以及布尔型。其中数字类型可以包括整数类型以及浮点数类型。具体来说,字节(英文:byte)型是8位、有符号的、以二进制补码表示的整数;短(英文:short)型是16位、有符号的、以二进制补码表示的整数;整(英文:int)型是32位、有符号的以二进制补码表示的整数;长(英文:long)型是64位、有符号的以二进制补码表示的整数;浮点数(英文:float)型是单精度、32位、符合电气和电子工程师协会(institute of electrical and electronics engineers,缩写:IEEE)754标准的浮点数;双精度(英文:double)型是双精度、64位、符合IEEE 754标准的浮点数;布尔(英文:boolean)型是表示一位的信息;字符(英文:char)型是单一的16位统一码(英文:unicode)字符。
(3)数组
数组是一种存储位置连续、顺序的存储结构。数组的长度可以在初始化时确定。数组的每个位置具有对应的数组下标,数组下标用于标识数组中对应的位置。通过任一数组下标,仅需一次寻址,即可定位到数组中对应的位置,从而迅速地访问到该位置中存储的数据,时间复杂度为O(1)。
(4)链表
链表是一种存储位置非连续、非顺序的存储结构。链表包括一个或多个节点,链表中不同节点的顺序通过节点中指针或引用的顺序指示。链表中上一个节点会持有下一个节点的指针或引用。如果要访问链表中的某个节点,需要遍历链表,根据当前遍历到的节点中的指针或引用,找到链表中下一个节点,直到找到需要的节点为止。
(5)哈希表
目前的哈希表是一种包括数组和链表的存储结构。数组是哈希表的主干,链表用于解决哈希表中的哈希冲突事件。在数据存储阶段,当通过键对象,定位到哈希表中的任一数组位置后,若该数组位置挂载有链表,需要遍历链表,若链表中键对象对应的位置已具有对应的节点,则覆盖该节点,否则要在链表中新增节点。数据存储的时间复杂度为O(n);在数据查询阶段,当通过键对象,定位到哈希表中的任一数组位置后,若该数组位置挂载有链表,也需要遍历链表,根据获取接口传入的键对象以及链表中节点的键对象,对链表中每个节点逐一比对查找,直到在链表中找到目标节点后,从目标节点中读取值对象。
(6)哈希冲突
哈希冲突也称哈希碰撞,是一种不同数据的存储位置产生冲突的事件。对于任一键值对来说,对键进行哈希运算,得到了存储位置后,当向该存储位置存储键值对时,若发现该存储位置已经存储了其他键值对,即产生了哈希冲突事件,此时需要重新为该键值对重新探测其他的存储位置。
在示例性实施例中,还提供了一种非瞬态的可读存储介质,例如包括指令的存储器,所述非瞬态的可读存储介质被至少一台计算设备执行时,所述至少一台计算设备执行下述方法实施例提供的数据存储方法以及数据获取方法中的至少一项。所述存储介质中存储了程序。所述存储介质的类型包括但不限于易失性存储器,例如随机访问存储器,非易失性存储器,例如快闪存储器、硬盘、固态硬盘。
图1是本申请实施例提供的一种数据存储方法的流程图,该方法的执行主体可以是计算设备,包括以下步骤:
101、计算设备获取待处理的键值对。
键值对包括第一对象和第二对象,键值对的键(英文:key)为第一对象,键值对的值(英文:value)为第二对象。键值对在实际程序中可以记录为“<key,value>”,其中,“<>”是标明键值对的符号,“key”表示键值对的键,“value”表示键值对的值。
第一对象是指待处理的键值对中作为键的对象。第一对象也可以称为键对象、key对象或K对象。第一对象至少包括对象头和实例数据,另外第一对象还可以包括对齐填充。可选地,第一对象可以是字符串(英文:String)对象,当然,第一对象也可以为字符串对象以外的其他数据类型的对象。
示例性地,假设键值对为<String,Double>,则对于该键值对来说,第一对象为String对象。参见图2,String对象的数据结构可以如图2所示。String对象包括String对象的对象头(英文:header)、实例数据(英文:instance data)以及对齐填充(英文:padding)。其中,String对象的实例数据包括哈希值(英文:int hash)、引用(英文:reference)、字符数组(英文:char value)。其中,char value本身也是对象。char value包括char value的对象头以及n个字符(英文:char)。
该String对象共计占用(64+2*n)字节。String对象的对象头占用16字节,哈希值为int型,占用4字节,引用占用16字节,char value占用(24+2*n)字节,对齐填充占用4字节。在String对象的char value中,char value的对象头占用24字节,char value的实例数据占用2*n字节。可见,对于该String对象来说,除了char value的实例数据以外,该String对象本身共计占用了64字节:16字节的String对象的对象头、4字节的哈希值、16字节的引用、24字节的char value的对象头以及4字节的对齐填充。
第二对象是指待处理的键值对中作为值的对象。第二对象也可以称为值对象、value对象或V对象。第二对象至少包括对象头和实例数据,另外第二对象还可以包括对齐填充。可选地,第二对象可以是双精度(英文:Double)对象,当然,第二对象也可以是Double对象以外的其他数据类型的对象。
示例性地,假设键值对为<String,Double>,则对于该键值对来说,键值对的值为Double对象。参见图3,Double对象的数据结构可以如图3所示。该Double对象包括Double对象的对象头以及双精度值(英文:double value)。该Double对象共计占用24字节,其中,Double对象的对象头占用16字节,double value占用8字节。也即是,该Double对象本身共计占用16字节。
需要说明的是,上文中的术语“第一对象”以及“第二对象”仅是为了区分描述不同的对象,而不应理解为明示或暗示不同对象的顺序、相对重要性以及数量关系。
可选地,待处理的键值对的获取方式可以包括以下获取方式一至获取方式二中任一项或多项的组合:
获取方式一、从哈希表的链表的任一节点中读取键值对。
哈希表可以是原生的哈希表。对于哈希表已存储的每个键值对,该键值对中的键和值可以均是对象。哈希表可以采用数组、链表以及红黑树的存储结构实现。哈希表的主干可以是数组,数组中包括一个或多个节点,每个节点在数组中占用一个位置。数组中的每个节点可以挂载一个链表。具体来说,数组中的每个节点可以作为链表的头节点,可以存储链表中第二个节点的引用或指针。而链表中第二个节点会存储链表中第三个节点的引用或指针,依次类推,链表中每个节点存储下一个节点的引用或指针。哈希表在实际程序中可以记录为“HashMap”。哈希表可以缓存在内存中。
示例性地,参见图4,哈希表的存储结构可以如图4所示。哈希表中的主干为节点(英文:node)数组,节点数组本身是一种对象。节点数组包含节点数组的对象头以及节点数组中的每个节点。节点数组的每个节点用于存储键值对。示例性地,参见图5,节点的数据结构可以如图5所示。节点包括哈希值、第一对象、第二对象以及链表中下一个节点的引用(英文:node next)。
关于获取哈希表中键值对的具体方式,可选地,可以遍历哈希表的链表的每个节点,对于当前遍历到的链表的节点,可以从该节点中读取键值对,作为待处理的键值对。
通过从哈希表中读取键值对,后续使用第一数组和第二数组存储键值对,可以实现键值对的搬迁功能,即,将键值对从原有的哈希表中搬迁至优化后的哈希表中。那么,由于原有的哈希表为基于数组和链表的存储结构,使用链地址法存取键值对,而优化后的哈希表为基于数组的存储结构,优化后的哈希表能够使用开放地址法存取键值对,存取速度更快,并且键值对本身采用了压缩存储的方式,占用的内存空间更少,可以实现将原有的哈希表转换为优化后的哈希表的功能,达到在原有的哈希表的基础上进行性能优化的效果。
获取方式二、当接收到数据存储指令时,获取数据存储指令中的键值对,作为待处理的键值对。
数据存储指令用于指示存储键值对,数据存储指令可以携带键值对。可选地,数据存储指令可以为put(插入)指令。可选地,数据存储指令可以通过对存储接口的调用操作触发。
存储接口用于提供数据存储服务,存储接口可以称为put接口。当需要存储任一键值对时,可以向该存储接口传入键值对,则计算设备可以接收到数据存储指令,从而执行后续存储键值对的业务逻辑。其中,存储接口的输入参数可以是第一对象和第二对象。
可选地,可以将待处理的键值对缓存在内存中,当然也可以通过内存以外的存储空间存储键值对,本实施例对此不做限定。
102、计算设备对第一对象进行处理,得到第一对象的哈希值。
第一对象的哈希值为一种唯一值,即,如果第一对象不变,则对第一对象进行哈希运算后,得到的哈希值不变。可选地,第一对象的哈希值可以是对第一对象的哈希码(hashcode)值进行哈希运算后得到的值。第一对象的哈希值可以在实际程序中记录为inthash。可选地,第一对象的哈希值可以是整型数据,即int型数据;当然,第一对象的哈希值也可以是整型数据以外的其他类型的数据,本实施例对第一对象的哈希值的数据类型不做限定。
通过对第一对象进行处理,将第一对象转换为哈希值,可以改变键值对的键本身的数据结构,将键值对的键从一种对象转换为一种基础数据,从而去除了对象中的对象头以及对齐填充,因此节省了对象头以及对齐填充占用的存储空间,后续过程中通过将第一对象的哈希值作为键进行存储,可以实现对键值对的键进行压缩存储的功能,从而节省了键值对的键占用的存储空间,进而可以提高存储键值对的效率和性能。
示例性地,参见图6,如果第一对象为String对象,通过将String对象转换为inthash值,可以将String对象占用的存储空间从64字节减少到4字节,从而节约了60字节的存储空间。
可选地,获取第一对象的哈希值的实现方式至少可以包括以下实现方式一至实现方式二中任一项或多项的组合。
实现方式一、获取第一对象包括的哈希值。
第一对象中可以封装哈希值,则可以直接获取第一对象本身的哈希值,从而复用该哈希值以进行存储,而无需进行哈希运算,从而提高了运算效率。举例来说,可以获取String对象中的int hash值。
实现方式二、对第一对象进行哈希运算,得到第一对象的哈希值。
例如,可以采用哈希码(英文:hashcode)方法,对第一对象进行哈希运算,得到第一对象的哈希值。
可选地,第一对象可以是通过内存缓存的对象。相应地,对第一对象进行处理后,可以将得到的第一对象的哈希值缓存在内存中,从而达到节约内存空间的效果。当然,第一对象也可以通过内存以外的其他存储空间缓存。例如,第一对象可以通过计算设备的任一本地存储器缓存,那么,通过在该本地存储器上对第一对象进行压缩存储,可以达到节约该本地存储器的存储空间的效果。又如,第一对象可以通过与该计算设备网络连接的网络存储器缓存,那么,通过在该网络存储器上对第一对象进行压缩存储,可以达到节约该网络存储器的存储空间的效果。
103、计算设备对第二对象进行拆箱转换,得到第二对象的实例数据。
第二对象的实例数据可以不包括第二对象的对象头以及第二对象的对齐填充。第二对象的实例数据的数据量小于第二对象。第二对象的实例数据可以看做第二对象的有效载荷,第二对象的实例数据可以是JAVA中的基本数据类型。可选地,第二对象的实例数据可以是双精度型数据,即double型数据;当然,第二对象的实例数据也可以是double型数据以外的其他数据类型的数据,本实施例对第二对象的实例数据的数据类型不做限定。
拆箱转换是指将数据的类型从对象转换成值的技术过程。具体来说,可以对第二对象的实例数据进行检测,判断第二对象的实例数据是否为指定的值类型,当第二对象的实例数据为指定的值类型时,将第二对象的实例数据复制给值类型的变量。
可选地,对第二对象进行拆箱装换的次数可以为一次或多次。例如,若第二对象为复合对象,即第二对象中又嵌套了一个或多个对象,可以对第二对象进行多次拆箱转换,最终对最内层对象进行拆箱转换后,可以去除第二对象中每层对象的对象头以及对齐填充,剩下最内层对象的实例数据,从而进一步减少第二对象的数据量,节约第二对象占用的存储空间。
通过对第二对象进行拆箱转换为实例数据,可以改变键值对的值本身的数据结构,将键值对的值从一种对象转换为一种基础数据,在实现键值存储功能的基础上,去除了对象中的对象头以及对齐填充,因此节省了对象头以及对齐填充占用的存储空间,后续过程中通过对第二对象的实例数据进行存储,可以极大地节约第二对象占用的存储空间,从而实现对键值对的值进行压缩存储的功能,进而可以提高存储键值对的效率和性能。
例如,参见图7,通过将Double对象转换为double值,可以将Double对象占用的存储空间从24字节减少到8字节,从而节约了16字节的存储空间。
可选地,第二对象可以是通过内存缓存的对象。相应地,对第二对象进行拆箱转换后,可以将得到的第二对象的实例数据存储在内存中,从而达到节约内存空间的效果。当然,第二对象也可以通过内存以外的其他存储空间存储。例如,第二对象可以通过计算设备的任一本地存储器存储,那么,通过在该本地存储器上对第二对象进行拆箱转换,可以达到节约该本地存储器的存储空间的效果。又如,第二对象可以通过计算设备网络连接的网络存储器存储,那么,通过在该网络存储器上对第二对象进行拆箱转换,可以达到节约该网络存储器的存储空间的效果。
104、计算设备将哈希值和实例数据分别存储至第一数组和第二数组,第一数组和第二数组不同。
第一数组用于存储键值对的键。通过将第一对象的哈希值存储至第一数组,可以达到以哈希值作为键,进行键值存储的功能。可选地,第一数组可以位于优化后的哈希表中。该优化后的哈希表在实际程序中可以记录为optimized hashmap。优化后的哈希表可以存储在内存中。示例性地,请参见图8,优化后的哈希表的存储结构可以如图8所示。可选地,第一数组可以为整型数组,即int型数组,该整型数组中的每个位置可以用于存储整型数据。
示例性地,请参见图8,第一数组可以为图8中的“int[]”,其中,“[]”是用于标明数组的符号,“int[]”表示类型为int型的数组。第一数组的位置可以如图8中int[]下方的小方框所示,第一数组中存储的哈希值可以如小方框中的“int”所示。当然,第一数组也可以是int型以外的其他任意类型的数组,本实施例对第一数组的数组类型不做限定。
可选地,第一数组的长度可以为素数,通过将第一数组的长度设置为素数,在进行哈希运算时能够产生较为分散的余数,从而最大程度上降低产生哈希冲突事件的概率。可选地,第一数组可以用于在未检测到哈希冲突时,存储键值对的键。可选地,第一数组可以缓存在内存中,可以在内存中占用一段连续的存储空间,第一数组的每个位置可以在内存中顺序排列。
第二数组用于存储任一键值对的值。通过将第二对象的实例数据存储至第二数组,可以达到以实例数据作为值,进行键值存储的功能。可选地,第二数组可以位于优化后的哈希表中。可选地,第二数组可以为双精度型数组,即double型数组,该双精度型数组中的每个位置可以用于存储双精度型数据。
示例性地,请参见图8,第二数组可以为图8中的“double[]”,其中,“[]”是用于标明数组的符号,“double[]”表示类型为double型的数组。第二数组中的位置可以如图8中double[]下方的小方框所示,第二数组中存储的实例数据可以如小方框中的“double”所示。当然,第二数组也可以是double型以外的其他任意类型的数组,本实施例对第二数组的数组类型不做限定。
可选地,第二数组可以用于在未检测到哈希冲突时,存储键值对的值。可选地,第二数组和上文中的第一数组可以是优化后的哈希表中配套出现的数组。第二数组可以缓存在内存中,可以在内存中占用一段连续的存储空间,第二数组的每个位置可以在内存中顺序排列。
可选地,将哈希值和实例数据分别存储至第一数组和第二数组具体可以包括步骤A至步骤C:
步骤A、向第一数组的第一位置添加第一对象的哈希值。
第一位置是指第一对象的哈希值的存储位置,第一位置可以是第一数组中的任一位置。
关于向第一位置添加第一对象的哈希值的具体过程,可选地,可以通过哈希查找算法,对第一对象的哈希值进行运算,得到第一数组的数组下标,根据第一数组的数组下标,在第一数组中获取该数组下标对应的位置,得到第一位置,向第一数组的第一位置添加第一对象的哈希值。示例性地,假设得到的数组下标为5,可以获取第一数组中数组下标为5的位置,向该数组下标为5的位置添加第一对象的哈希值。其中,第一数组的数组下标用于标记第一数组中的第一位置,该数组下标在实际程序中可以记录为索引(英文:index)值。哈希查找算法可以通过哈希功能(英文:hash functions)函数实现。
可选地,当第一数组的存储容量不足时,可以对第一数组进行扩容。具体的,在向第一数组添加第一对象的哈希值的过程中,当第一数组中已占用的位置达到扩容阈值时,可以确定第一数组的存储容量不足,则可以创建扩容后的第一数组,将第一数组中已存储的哈希值存储至扩容后的第一数组中。其中,扩容后的第一数组的长度大于第一数组原先的长度,因此对第一数组进行扩容后,可以提高第一数组的存储容量,以便存储更多的哈希值。
其中,扩容后的第一数组的长度可以为素数,从而保证对第一数组进行扩容后,仍然能够降低哈希冲突事件的概率。其中,扩容阈值可以根据装载因子确定,例如,扩容阈值可以是装载因子与第一数组的长度的乘积。该装载因子可以较小。
可选地,可以采用开放地址存储法,向第一数组添加第一对象的哈希值。其中,该开放地址存储法也称开放定址法,是一种在数组中探测存储位置的方法。该开放地址法可以包括线性探测法、二次探测法等。通过采用开放地址存储法存储第一对象的哈希值,可以根据数组下标,直接在第一数组中定位到对应的位置,以便在定位到的位置存储第一对象的哈希值。相对于链地址法来说,由于无需遍历链表中的每个节点,也无需对链表中每个节点存储的键与待处理的键值对的键进行逐个比对,可以提高存储键值对中键的速度,从而极大地提高键值存储效率。
步骤B、根据该第一位置,在第二数组中,获取第一位置对应的第二位置。
第二位置是指第二对象的实例数据的存储位置,第二位置可以是第二数组中的任一位置。
关于第二位置与第一位置的对应关系,可选地,第一位置在第一数组中的数组下标可以和第二位置在第二数组中的数组下标相同。具体来说,可以根据第一位置在第一数组的数组下标,在第二数组中,获取该数组下标指向的位置,作为第二位置。如此,第一对象的哈希值在第一数组中的排列顺序可以和第二对象的实例数据在第二数组中的排列顺序相同。示例性地,以第一对象的哈希值为int hash值、第二对象的实例数据为double值为例,如果int hash值在第一数组中的第5个位置存储,则double值可以在第二数组的第5个位置存储。
当然,第一位置对应的数组下标也可以和第二位置对应的数组下标不同,例如第一位置对应的数组下标和第二位置对应的数组下标可以相差预设偏移量,又如第一位置对应的数组下标也可以和第二位置对应的数组下标成线性映射关系,可以只要求第一位置与第二位置对应即可,本实施例对第一位置与第二位置之间的具体对应关系不做限定。
步骤C、向第二数组的第二位置添加第二对象的实例数据。
可选地,可以采用开放地址存储法,向第二数组的第二位置添加第二对象的实例数据。通过采用开放地址存储法存储第二对象的实例数据,可以根据数组下标,直接在第二数组中定位到对应的位置,以便在定位到的位置存储第二对象的实例数据。相对于链地址法来说,由于无需遍历链表中的每个节点,可以提高存储键值对中值的速度,从而极大地提高键值存储效率。
综上所述,上文阐述了对键值对进行压缩存储的流程。可选地,可以当未检测到哈希冲突事件时,将哈希值和实例数据分别存储至第一数组和第二数组,从而节省键值对中键和值占用的存储空间,实现对键值对的键和值均进行压缩存储的功能。可选地,可以当检测到哈希冲突事件时,将第一对象和实例数据分别存储至第三数组和第四数组,从而对键值对的值进行压缩存储,而对键值对的键仍按照原有的存储方式进行存储。如此,若存在产生哈希冲突事件的概率时,能够将键值对的键从第一对象的哈希值退化为第一对象,从而将键从压缩存储的方式退化为原有的存储方式。
第三数组用于在检测到哈希冲突事件时存储键值对的键。可选地,第三数组可以为字符串(String)型数组。该字符串型的数组中的每个位置可以用于存储字符串型数据;当然,第三数组也可以是字符串型的数组以外的其他类型的数组。例如可以根据第一对象的类型,设置第三数组的数组类型,本实施例对第三数组的数组类型不做限定。
可选地,第三数组的长度可以为素数,通过将第三数组的长度设置为素数,在进行哈希运算时能够产生较为分散的余数,从而最大程度上降低产生哈希冲突事件的概率。可选地,第三数组可以缓存在内存中,可以占用一段连续的内存空间,第三数组中的每个位置可以在内存中顺序排列。
第四数组用于在检测到哈希冲突事件时存储键值对的值。可选地,第四数组可以为双精度型数组,即double型数组;当然,第四数组的数组类型也可以是双精度型数组以外的其他任意数组类型,本实施例对第四数组的数组类型不做限定。可选地,第四数组和上文中的第三数组可以是优化后的哈希表中配套出现的数组。可选地,第四数组可以缓存在内存中。
可选地,将哈希值和实例数据分别存储至第一数组和第二数组的步骤具体可以包括以下步骤a至步骤c。
步骤a、向第三数组的第三位置添加第一对象。
关于向第三数组添加第一对象的具体过程,可选地,可以通过哈希查找算法,对第一对象进行运算,得到第三数组的数组下标。可以根据第三数组的数组下标,在第三数组中,获取该数组下标对应的位置,得到第三位置,向第三数组的第三位置添加该第一对象。示例性地,假设得到的数组下标为5,可以获取第三数组中数组下标为5的位置,向该数组下标为5的位置添加第一对象。其中,第三数组的数组下标用于标记第三数组的第三位置,数组下标在实际程序中可以表示为index值。
可选地,当第三数组的存储容量不足时,可以对第三数组进行扩容。对第三数组进行扩容的过程与上述对第一数组进行扩容的过程同理,在此不做赘述。
可选地,可以采用开放地址存储法,向第三数组添加第一对象。其中,采用开放寻址法添加第一对象的过程与上述采用开放寻址法添加第一对象的哈希值的过程同理,在此不做赘述。
步骤b、根据第三位置,在第四数组中,获取第三位置对应的第四位置。
步骤c、向第四数组的第四位置添加实例数据。
第三位置是指检测到哈希冲突事件时第一对象的存储位置,第三位置可以是第三数组中的任一位置。第四位置是指检测到哈希冲突事件时第二对象的实例数据的存储位置,第四位置可以是第四数组中的任一位置。
关于第四位置与第三位置的对应关系,第四位置对应的数组下标可以和第三位置对应的数组下标相同。具体来说,可以根据第三位置在第三数组的数组下标,在第四数组中,获取该数组下标指向的位置,作为第四位置。如此,第一对象在第三数组中的排列顺序可以和第二对象的实例数据在第四数组中的排列顺序相同。示例性地,以第一对象为String对象、第二对象的实例数据为double值为例,如果String对象在第三数组的第5个位置存储,则double值可以在第四数组的第5个位置存储。
当然,第四位置对应的数组下标也可以和第三位置对应的数组下标不同,例如第三位置对应的数组下标和第四位置对应的数组下标可以相差预设偏移量,又如第三位置对应的数组下标也可以和第四位置对应的数组下标成线性映射关系,本实施例对第三位置与第四位置之间的具体对应关系不做限定。
可选地,对哈希冲突事件进行检测的方式可以为:根据哈希表的哈希冲突历史记录,对哈希冲突事件进行检测,该哈希表已存储键值对。该哈希冲突历史记录用于记录哈希表中不同键值对之间的哈希冲突事件。例如,哈希冲突历史记录可以携带哈希冲突事件标识,该哈希冲突事件标识的取值可以用于指示哈希表中不同键值对是否产生过哈希冲突事件。可选地,哈希冲突历史记录可以包括哈希冲突事件位,该哈希冲突事件位用于承载该哈希冲突事件标识。另外,哈希冲突历史记录还可以包括产生过哈希冲突事件的键值对的标识,该键值对的标识用于指示产生过哈希冲突事件的键值对。
可选地,对哈希冲突事件进行检测的方式可以包括以下检测方式一以及检测方式二中任一项或多项的组合。
检测方式一、可以判断哈希冲突历史记录中是否包括待处理的键值对的哈希冲突记录,当哈希冲突历史记录包括该键值对的哈希冲突记录时,检测到哈希冲突事件;当哈希冲突记录中不包括键值对的哈希冲突记录时,检测不会产生哈希冲突事件。
通过检测方式一,可以实现单条退化存储的功能。具体来说,对于任一个键值对,当检测到该键值对会触发哈希冲突事件时,则对于该键值对,可以将第一对象的哈希值和第二对象的实例数据分别存储至第一数组和第二数组;而当检测到该键值对不会触发哈希冲突事件时,则对于该键值对,可以将第一对象和第二对象的实例数据分别存储至第三数组和第四数组。如此,可以针对该键值对的检测结果,从键和值均进行压缩存储的方式以及键退化而值进行压缩存储的方式中,为该键值对选择一种压缩存储方式,对该键值对进行存储。
进一步地,当需要存储多个键值对时,可以分别检测每个键值对是否会触发哈希冲突事件,根据每个键值对是否会触发哈希冲突事件,分别为每个键值对选择对应的压缩存储方式。可选地,该多个待处理的键值对可以均属于哈希表。如此,可以为同一哈希表中的不同键值对,分别采用不同的压缩存储方式进行存储,极大地提高键值存储以及哈希存储的灵活性。
在一个示例性场景中,假设原有的哈希表中包括100个键值对,检测到其中的10个键值对会触发哈希冲突事件,检测到其中的90个键值对不会触发哈希冲突事件。则对10个键值对来说,可以将这10个键值对的第一对象以及第二对象的实例数据分别存储至第三数组和第四数组,对10个键值对进行压缩存储。而对90个键值对来说,可以将这90个键值对的第一对象的哈希值以及第二对象的实例数据分别存储至第一数组和第二数组,对90个键值对进行压缩存储。
检测方式二、可以判断哈希冲突历史记录中是否包括哈希表中的任一键值对的哈希冲突记录,当哈希冲突历史记录中包括哈希表中的任一键值对的哈希冲突记录时,检测到哈希冲突事件。当哈希冲突记录中不包括哈希冲突记录时,检测不会产生哈希冲突事件。
通过检测方式二,可以实现整体退化存储的功能。具体来说,当哈希表中的任一键值对在历史存储过程中,触发了哈希冲突事件,使得哈希冲突历史记录中包括该键值对的哈希冲突记录时,会检测到哈希冲突事件,则对于哈希表中的每个键值对,均可以将第一对象和第二对象的实例数据分别存储至第三数组和第四数组;而当哈希表中的所有键值对在历史存储过程中,均未触发哈希冲突事件,使得哈希冲突历史记录中不包括任一键值对的哈希冲突记录时,不会检测到哈希冲突事件,则对于哈希表中的每个键值对,均可以将第一对象的哈希值和第二对象的实例数据分别存储至第一数组和第二数组。如此,可以针对原有的哈希表的整体检测结果,从键和值均进行压缩的存储方式以及键退化而值压缩的存储方式中,为该原有的哈希表中的所有键值对选择同一种压缩存储方式,对该原有的哈希表整体进行压缩存储。
在一个示例性场景中,假设原有的哈希表中包括100个键值对,其中检测到某10个键值对会触发哈希冲突事件。则对100个键值对来说,可以直接将这100个键值对的第一对象以及第二对象的实例数据分别存储至第三数组和第四数组。
可选地,对哈希冲突事件进行检测的步骤可以作为存储键值对之前执行的预置步骤。具体来说,可以预先对哈希冲突事件进行检测,得到哈希冲突事件的检测结果,则在存储键值对时,可以直接根据哈希冲突事件的检测结果,确定对键值对采用的压缩存储方式。可选地,也可以在进行键值存储时,实时根据当前存储的键值对检测哈希冲突事件。本实施例对检测哈希冲突事件的时机不做限定。
可选地,上述方式一以及方式二可以仅是对哈希冲突事件进行检测的实现方式的举例,也可以采用其他实现方式对哈希冲突事件进行检测,例如,可以根据第一对象的哈希值以及已存储的至少一个对象的哈希值,对哈希冲突事件进行检测。本实施例对检测哈希冲突事件的方式不做限定。
可选地,也可以无需执行对哈希冲突事件进行检测的过程。例如,可以获取压缩存储方式信息,根据压缩存储方式信息,确定对键值对采用的压缩存储方式。其中,该压缩存储方式信息用于指示对键进行退化存储或对键和值均进行压缩存储。在一种可能的实现中,该压缩存储方式信息可以作为存储(put)接口的传入参数,通过向该存储接口传入压缩存储方式信息,可以直接控制对键值对采用的压缩存储方式。
综上所述,参见图9,本实施例提供的数据存储方法可以由图9所示的哈希存储装置实现。该哈希存储装置可以通过软件实现。该哈希存储装置包括存储(put)接口、构建(英文:build)模块以及存储(英文:storage)模块。
该存储接口可以用于接收输入的待处理的键值对。
该构建模块可以用于执行对键和值进行处理的步骤。具体来说,该构建模块可以接收向存储接口传入的键值对,也可以接收已有的哈希表中的键值对。构建模块的主要功能为对键值对进行内存处理。构建模块的功能包括而不限于:第一,对键进行内存压缩,实现方式可以为将键从第一对象转换为哈希值;第二,对值进行内存压缩,实现方式可以为将值从第二对象转换为实例数据;第三,是在检测到哈希冲突事件时,将键从哈希值退化为第一对象。
该存储模块可以用于基于数组结构,采用开放地址存储法进行键值存储。具体来说,如图9中存储模块内的实线框所示,当未检测到哈希冲突事件时,存储模块可以将键以哈希值的形式,压缩存储在int型数组中,将值以实例数据的形式,压缩存储在double型数组中。如图9中存储模块内的虚线框所示,当检测到哈希冲突事件后,存储模块可以将键退化存储在String型数组中。
在一个示例性场景中,参见图10,假设某个键值对为<K,V>,其中第一对象为K,第二对象为V,图10提供了通过本实施例提供的方法,针对该键值对进行键值存储的程序流程图。在图10中,int[]为第一数组的示例,v[]为第二数组的示例,K[]为第三数组的示例,v'[]为第四数组的示例,int hash值为K的实例数据的举例,v为V的实例数据的举例。
当应用程序通过put接口,向构建模块传入键值对后,构建模块可以对K进行哈希运算后,转换为int hash值,或者获取K中封装的int hash值。构建模块还可以对V进行拆箱转换后,转换为v。
当未检测到哈希冲突事件时,构建模块可以向存储模块发送int hash值和v,存储模块可以接收int hash值和v,根据int hash值,计算int[]中的位置,假设int[]中的位置记录为index,可以根据index,向int[]中添加int hash值。之后,可以判断int[]的存储容量是否不足。若int[]的存储容量不足,则对int[]进行扩容,再向扩容后的int[]添加inthash值;若int[]的存储容量足够,则直接向int[]添加int hash值。之后,可以向v[]中index对应的位置添加v。
当检测到哈希冲突事件时,构建模块可以向存储模块发送K和v,存储模块可以接收K和v,根据K,计算K[]中的位置。假设K[]中的位置记录为index',可以根据index',向K[]中添加K。之后,可以判断K[]的存储容量是否不足。若K[]的存储容量不足,则对K[]进行扩容,再向扩容后的K[]添加K;若K[]的存储容量足够,则直接向K[]添加K。之后,可以向v'[]中index'对应的位置添加v。
可选地,参见图11,本实施例提供的优化后的哈希表可以通过以下步骤一至步骤三创建。
步骤一、生成优化后的哈希表的基础结构。
可选地,构建模块可以提供哈希表的创建接口,当应用程序需要生成优化后的哈希表时,可以调用哈希表的创建接口,生成哈希表生成指令,向构建模块发送哈希表生成指令。构建模块接收到哈希表生成指令时,响应该哈希表生成指令,会执行后续生成优化后的哈希表的流程。其中,哈希表的创建接口在实际程序中可以记录为“optimized hashmap<K,V>”。
步骤二、设置优化后的哈希表的初始容量。
可选地,优化后的哈希表的初始容量可以通过哈希表的创建接口指定。例如,可以将初始容量设置为创建接口的传入参数,向该创建接口传入初始容量,则可以获取向创建接口传入的初始容量作为优化后的哈希表的初始容量。可选地,优化后的哈希表的初始容量也可以根据默认容量以及默认装载因子确定。该默认装置因子可以较小。
可选地,若将原有的哈希表转换为优化后的哈希表,可以根据哈希表的大小设置优化后的哈希表的初始容量。例如,可以将哈希表的大小作为优化后的哈希表的初始容量。具体来说,可以根据哈希表中存储的键值对的数量,设置优化后的哈希表中数组的长度。
由于哈希表的大小已知,通过根据哈希表的大小设置优化后的哈希表的初始容量,可以保证优化后的哈希表的初始容量的准确性,令优化后的哈希表的初始容量不至于过大,从而降低浪费存储空间的概率,也令优化后的哈希表的初始容量不至于过小,从而尽可能地降低哈希冲突时间的概率,从而尽可能地避免频繁地对优化后的哈希表扩容,从而提升哈希表的存储性能。
可选地,可以根据哈希表的哈希冲突历史记录,设置优化后的哈希表的初始容量。例如,若哈希表的哈希冲突历史记录中哈希冲突事件的频率较高,可以适应性地提高优化后的哈希表的初始容量,若哈希表的哈希冲突历史记录中哈希冲突事件的频率较低,可以适应性地降低优化后的哈希表的初始容量。
可选地,在执行步骤二后,可以执行下述步骤三和步骤四中任一项或多项的组合。
步骤三、生成第一数组以及第二数组。
可选地,可以根据步骤二中设置的初始容量,申请一定大小的存储空间。可以生成第一数组以及第二数组,在该存储空间中缓存第一数组以及第二数组。其中,第一数组的数组类型可以设置为int型,第二数组的数组类型可以根据键值对中值的对象类型确定。可选地,该存储空间可以是内存空间。
步骤四、生成第三数组以及第四数组。
其中,第三数组的数组类型可以根据键值对中键的对象类型确定,第四数组的数组类型可以根据键值对中值的对象类型确定。
需要说明的第一点是,步骤三和步骤四可以择一执行,也可以均执行。以步骤三和步骤四择一执行为例,当根据哈希表的哈希冲突历史记录,未检测到哈希冲突事件时,可以执行步骤三,当根据哈希表的哈希冲突历史记录,检测到哈希冲突事件时,可以执行步骤四。
需要说明的第二点是,优化后的哈希表的创建流程可以在键值存储前的任一时刻执行,本实施例对创建优化后的哈希表的时机不做限定。
本实施例提供的键值存储方法至少可以在以下四种场景中提高存储性能。
场景一、第一对象不存在哈希冲突,并且第二对象可以进行拆箱转换。在该场景下,键值对可以从两种对象转换为两种基础数据,即,键值对可以从<K,V>转换为<int,v>。通过使用数组的存储结构以及键和值均压缩存储的方式,可以节约键值对中键和值占用的存储空间,并提高存储键值对的速度,优化效果明显。
场景二、第一对象存在哈希冲突,并且第二对象可以进行拆箱转换。在该场景下,键值对的值可以从对象转换为基础数据,即,键值对可以从<K,V>转换为<K,v>。通过使用数组的存储结构以及值压缩存储的方式,可以节约键值对中值占用的存储空间,并提高存储键值对的速度,优化效果明显。
场景三、第一对象不存在哈希冲突,并且第二对象无法进行拆箱转换。在该场景下,键值对的键可以从对象转换为基础数据,即,键值对可以从<K,V>转换为<int,V>。通过使用数组的存储结构以及键压缩存储的方式,可以节约键值对中键占用的存储空间,并提高存储键值对的速度,优化效果明显。
场景四、第一对象存在哈希冲突,并且第二对象无法进行拆箱转换。在该场景下,通过使用数组的存储结构,可以提高存储键值对的速度,优化效果明显。
另外,在原生的哈希表中存储的数据量较大的场景下,内存处理效果明显。在一个示例性场景中,某高维逻辑回归(logistic regression,缩写:LR)模型包括5000万高维特征参数。当该LR模型使用原生的哈希表进行存储时,会在内存中占用数吉字节(Gigabyte,缩写:GB或G)空间,在工程应用中会带来一系列的资源和性能问题。例如,不仅会带来大量的存储资源开销,并且,由于占用了大量的存储资源,会导致设备整体性能的下降,还会提高触发垃圾回收(garbage collection,缩写:GC)机制的概率。而使用本申请提供的键值处理以及基于数组的存储方法进行存储后,该LR模型在内存中仅占用500兆(MByte,缩写:MB)。
需要说明的是,上述仅是以单台计算设备上执行数据存储的流程为例,对本申请提供的数据存储方法进行示例性说明。可选地,也可以由分布式系统执行本申请提供的数据存储方法。例如,可以由存储节点1执行步骤101,将第一对象发送给存储节点2,将第二对象发送给存储节点3。存储节点2执行步骤102后,可以将第一对象的哈希值发送给存储节点4。存储节点3执行步骤103后,可以将第二对象的实例数据发送给存储节点4。存储节点4可以执行步骤104,将存储节点2发送的哈希值以及存储节点3发送的实例数据分别存储至第一数组和第二数组。
本实施例提供的方法,通过将键值对的键从对象转换为哈希值,将键值对的值从对象转换为实例数据,改进了键和值本身的数据结构,去除了键和值的对象头以及对齐填充等部分,从而节省了对象头以及对齐填充占用的存储空间,因此减少了键值对中对象本身带来的存储开销,实现了对键值对进行压缩存储的功能,减少了键值存储需要占用的存储空间,提高了键值存储的效率。并且,通过改进了基于链表的存储结构,使用基于多数组的存储结构存储键值对,可以避免遍历链表中的节点造成的时间开销,从而提高存储键值对的速度。尤其是,应用在通过内存空间存储键值对的场景中,通过节约键值对中对象本身占用的内存,可以极大地节约键值对占用的内存空间,也就降低了键值对占用的内存空间过大时会触发的内存回收以及其他资源和性能问题的概率,因此可以显著地提高存储系统的性能。
图12是本申请实施例提供的一种数据获取方法的流程图,该方法的执行主体可以是计算设备,该方法包括以下步骤:
1201、计算设备根据数据获取指令中的第一对象,获取第一对象的哈希值。
数据获取指令用于指示获取已存储的键值对的值,即获取第二对象。数据获取指令可以携带已存储的键值对的键,即第一对象。可选地,数据获取指令可以为get(获取)指令。可选地,数据获取指令可以通过对获取接口的调用操作触发。
该获取接口用于提供数据查询服务,在实际程序中可以记录为get接口,获取接口的输入参数可以是第一对象。当需要查询任一键值对的值时,可以向该获取接口输入该键值对的键,则计算设备可以接收到数据获取指令,从而响应该数据获取指令,执行后续键值查询的业务逻辑。
可选地,获取第一对象的哈希值的实现方式至少可以包括以下实现方式(1)至实现方式(2)中任一项或多项的组合。
实现方式(1)获取第一对象包括的哈希值。
该实现方式(1)与上述图1实施例中步骤102的实现方式一同理,在此不做赘述。
实现方式(2)对第一对象进行哈希运算,得到第一对象的哈希值。
该实现方式(2)与上述图1实施例中步骤102的实现方式二同理,在此不做赘述。
1202、计算设备在第一数组中,获取第一对象的哈希值所处的位置,得到第一位置。
关于获取第一位置的具体过程,可选地,可以通过哈希查找算法,对第一对象的哈希值进行运算,得到第一数组的数组下标。可以根据第一数组的数组下标,在第一数组中,获取该数组下标对应的位置,作为第一位置。可选地,可以读取第一位置存储的第一对象的哈希值,判断第一位置存储的第一对象的哈希值与步骤1201中获取到的第一对象的哈希值是否相同,当第一位置存储的第一对象的哈希值与步骤1201中获取到的第一对象的哈希值相同时,将数组下标对应的位置作为第一位置。
可选地,可以采用开放寻址法,在第一数组中获取第一位置。其中,该开放寻址法是指在哈希表的数组中探测存储位置的方法。通过采用开放地址法查询键值对的键所处的位置,可以直接在数组中定位到第一位置。相对于链地址法来说,由于无需遍历链表中的每个链表位置,也无需通过逐个比对每个链表位置中的键与待查询的键值对的键是否相同,因此可以极大地提高存储效率。当然,也可以采用开放寻址法以外的方法进行寻址,本实施例对此不做限定。
1203、计算设备根据第一位置,在第二数组中,获取第一位置对应的第二位置,第二数组和第一数组不同。
该步骤与上述图1实施例中步骤104的步骤B同理,在此不做赘述。
1204、计算设备从第二数组的第二位置读取第二对象的实例数据。
1205、计算设备对第二对象的实例数据进行装箱转换,得到第二对象。
装箱转换是指将数据从值类型转换成对象类型的技术过程。通过进行装箱转换,会将实例数据与第二对象的对象头以及对齐填充进行封装,得到第二对象。可选地,对第二对象的实例数据进行装箱转换的次数可以为一次或多次。
综上所述,上文阐述了对键值对进行压缩存储后进行数据查询的流程。可选地,可以当未检测到哈希冲突事件时,执行上述步骤1202至步骤1205,可选地,可以当检测到哈希冲突事件时,以执行以下步骤一至步骤三。
步骤一、在第三数组中,获取第一对象所处的位置,得到第三位置。
步骤二、根据第三位置,在第四数组中,获取第三位置对应的第四位置。
步骤三、从第四数组的第四位置读取第二对象。
可选地,关于检测哈希冲突事件的过程,可选地,可以在第二位置为空闲位置,即第二位置未存储数据时,检测到哈希冲突事件。可选地,也可以当第二位置未存储第二对象的实例数据,例如第二位置填充了无意义数据时,检测到哈希冲突事件,本实施例对数据查询时检测哈希冲突事件的方式不做限定。
综上所述,参见图9,本实施例提供的数据存储方法可以由图9所示的哈希存储装置实现。该哈希存储装置可以提供获取(英文:get)接口以及存储模块。该获取接口可以用于接收输入的待查询的键值对中的第一对象。该存储模块可以用于基于数组结构,采用开放寻址法进行键值查询。具体来说,如图9中存储模块内的实线框所示,当未检测到哈希冲突事件时,存储模块可以以第一对象的哈希值为键,在int型数组和double型数组中进行键值查询,当检测到哈希冲突事件时,存储模块可以以第一对象为键,在String型数组和double型数组中进行键值查询。当查询到第二对象后,存储模块可以向获取接口发送第二对象。
在一个示例性场景中,参见图13,假设某个键值对为<K,V>,其中第一对象为K,第二对象为V,图13提供了通过本实施例提供的方法,针对该键值对进行键值查询的程序流程图。在图13中,int[]为第一数组的示例,v[]为第二数组的示例,K[]为第三数组的示例,v'[]为第四数组的示例,int hash值为K的实例数据的举例,v为V的实例数据的举例。
当应用程序通过get接口,向构建模块传入K后,构建模块可以对K进行哈希运算后,转换为int hash值,或者获取K中封装的int hash值。
当未检测到哈希冲突事件时,构建模块可以向存储模块发送int hash值,存储模块可以接收int hash值,根据int hash值,计算int[]中的位置,假设int[]中的位置记录为index,可以根据index,从v[]中index对应的位置读取v。
当检测到哈希冲突事件时,构建模块可以向存储模块发送K,存储模块可以接收K,根据K,计算K中的位置。假设K[]中的位置记录为index',可以根据index',从v'[]中index'对应的位置读取v。
需要说明的是,上述仅是以单台计算设备上执行数据获取的流程为例,对本申请提供的数据获取方法进行示例性说明。可选地,也可以由分布式系统执行本申请提供的数据获取方法。例如,可以由存储节点2执行步骤1201后,可以将第一对象的哈希值发送给存储节点4。存储节点4可以根据存储节点2发送的第一对象的哈希值,执行步骤1202至步骤1205,以得到第二对象。
本实施例提供的方法,通过在第一数组中,获取第一对象的哈希值所处的位置,得到第一位置,根据第一位置,在第二数组中,获取第一位置对应的第二位置,从第二位置读取第二对象的实例数据;对第二对象的实例数据进行装箱转换,得到第二对象,实现了基于多数组的存储结构以及开放寻址法进行键值查询的功能,可以避免遍历链表中的节点所造成的时间开销,从而提高键值查询的速度,进而提高存储系统的性能。
图14是本申请实施例提供的一种计算设备的结构示意图。参见图14,该计算设备包括:获取模块1401、处理模块1402以及存储模块1403。
该获取模块1401,用于执行上述步骤101;
该处理模块1402,用于执行上述步骤102和步骤103;
该存储模块1403,用于执行上述步骤104。
可选地,该处理模块1402,用于执行上述步骤102中的实现方式一或者实现方式二。
可选地,该获取模块1401,用于执行上述步骤101中的获取方式一。
可选地,该存储模块1403,用于执行上述步骤104中的步骤A至步骤C。
可选地,该存储模块1403,用于当未检测到哈希冲突事件时,执行上述步骤104中的步骤A至步骤C;当检测到哈希冲突事件时,执行上述步骤104中的步骤a至步骤c。
可选地,该计算设备还包括:
检测模块,用于根据哈希表的哈希冲突历史记录,对该哈希冲突事件进行检测。
可选地,该检测模块,用于执行上述步骤104中的检测方式一或者检测方式二。
需要说明的第一点是:图14实施例所述的各个模块具体可以是软件中执行相应功能的软件模块,即,“模块”可以是一组计算机程序构成的功能模块,该计算机程序可以是源程序或目标程序,该计算机程序可以通过任意编程语言实现。通过上述各个模块,计算设备可以基于处理器加存储器的硬件来实现存储数据的功能,也即是,可以通过计算设备的处理器,运行存储在计算设备的存储器中的软件代码,来执行相应的软件来实现存储数据的功能。
需要说明的第二点是:图14实施例提供的计算设备在存储数据时,仅以上述各功能模块的划分进行举例说明,实际应用中,可以根据需要而将上述功能分配由不同的功能模块完成,即将计算设备的内部结构划分成不同的功能模块,以完成以上描述的全部或者部分功能。另外,上述实施例提供的计算设备与数据存储方法实施例属于同一构思,其具体实现过程详见方法实施例,这里不再赘述。
图15是本申请实施例提供的一种计算设备的结构示意图。参见图15,该计算设备包括:获取模块1501、读取模块1502以及转换模块1503;
该获取模块1501,用于执行上述步骤1201至步骤1203;
该读取模块1502,用于执行上述步骤1204;
该转换模块1503,用于执行上述步骤1205。
可选地,该获取模块1501,还用于当检测到哈希冲突事件时,执行上述步骤1205提及的步骤一至步骤二;
该读取模块1502,还用于执行上述步骤1205提及的步骤三。
需要说明的第一点是:图15实施例所述的各个模块具体可以是软件中执行相应功能的软件模块,即,“模块”可以是一组计算机程序构成的功能模块,该计算机程序可以是源程序或目标程序,该计算机程序可以通过任意编程语言实现。通过上述各个模块,计算设备可以基于处理器加存储器的硬件来实现获取数据的功能,也即是,可以通过计算设备的处理器,运行存储在计算设备的存储器中的软件代码,来执行相应的软件来实现获取数据的功能。
需要说明的第二点是:图15实施例提供的计算设备在获取数据时,仅以上述各功能模块的划分进行举例说明,实际应用中,可以根据需要而将上述功能分配由不同的功能模块完成,即将计算设备的内部结构划分成不同的功能模块,以完成以上描述的全部或者部分功能。另外,上述实施例提供的计算设备与数据获取方法实施例属于同一构思,其具体实现过程详见方法实施例,这里不再赘述。
本申请还提供了一种计算设备。如图16所示,计算设备1600包括总线1601、处理器1602、通信接口1603和存储器1604。处理器1602、存储器1604和通信接口1603之间通过总线1601通信。
其中,处理器可以为中央处理器(英文:central processing unit,缩写:CPU)。存储器可以包括易失性存储器(英文:volatile memory),例如随机存取存储器(英文:randomaccess memory,缩写:RAM)。存储器还可以包括非易失性存储器(英文:non-volatilememory),例如只读存储器(英文:read-only memory,缩写:ROM),快闪存储器,HDD或SSD。存储器中存储有可执行代码,处理器执行该可执行代码以执行前述数据存储方法。存储器中还可以包括操作系统等其他运行进程所需的软件模块。操作系统可以为LINUXTM,UNIXTM,WINDOWSTM等。
计算设备1600的存储器1604中存储了图14实施例中各个模块对应的代码,处理器1602执行这些代码实现了图14实施例中的各个模块的功能,即执行了图1实施例所示的数据存储方法。计算设备1600可以为云环境中的计算设备,或边缘环境中的计算设备,或终端环境中的计算设备。
本申请还提供了一种计算设备集群,如图17所示,该计算设备集群包括至少一台计算设备1700,每个计算设备1700可以执行图1实施例中的任一个或多个步骤,也即是,每个计算设备1700可以运行图14实施例中的任一个或多个模块。图14实施例中的不同模块可以在该计算设备集群中的不同计算设备1700上执行。其中,每个计算设备1700的结构与图16实施例中计算设备1600的结构相同。具体来说,每个计算设备1700包括总线1701、处理器1702、通信接口1703和存储器1704。处理器1702、存储器1704和通信接口1703之间通过总线1701通信。不同计算设备1700之间可以通过通信网络建立通信通路。每个计算设备1700上运行获取模块1401、处理模块1402以及存储模块1403中的任意一个或多个。任一计算设备1700可以为云环境中的计算设备,或边缘环境中的计算设备,或终端环境中的计算设备。
进一步的,由于键值对占用的存储空间较大,另外根据业务需要,可能需要存储大量的键值对,因此计算设备1700本身可能无法存储全部的键值对,有鉴于此,本申请还提出了一种计算设备集群。如图18所示,存储模块1403部署在云存储服务中(例如对象存储服务),用户在云存储服务中申请一定容量的存储空间作为存储模块1403,计算设备集群可以将键值对进行处理后,存入存储模块1403中。计算设备1700运行时,通过通信网络从远端的存储模块1403中获取所需的键值对。每个计算设备1700上运行获取模块1401、处理模块1402中的任意一个或多个。任一计算设备1700可以为云环境中的计算设备,或边缘环境中的计算设备,或终端环境中的计算设备。
本申请还提供了一种计算设备1900。如图19所示,计算设备1900包括总线1901、处理器1902、通信接口1903和存储器1904。处理器1902、存储器1904和通信接口1903之间通过总线1901通信。
其中,处理器1902可以为中央处理器(英文:central processing unit,缩写:CPU)。存储器可以包括易失性存储器(英文:volatile memory),例如随机存取存储器(英文:random access memory,缩写:RAM)。存储器还可以包括非易失性存储器(英文:non-volatile memory),例如只读存储器(英文:read-only memory,缩写:ROM),快闪存储器,HDD或SSD。存储器中存储有可执行代码,处理器1902执行该可执行代码以执行前述数据获取方法。存储器中还可以包括操作系统等其他运行进程所需的软件模块。操作系统可以为LINUXTM,UNIXTM,WINDOWSTM等。
计算设备1900的存储器中存储了图15实施例中各个模块对应的代码,处理器1902执行这些代码实现了图15实施例中的各个模块的功能,即执行了图12实施例所示的数据获取方法。计算设备1900可以为云环境中的计算设备,或边缘环境中的计算设备,或终端环境中的计算设备。
本申请还提供了一种计算设备集群,如图20所示,该计算设备集群包括至少一台计算设备2000,每个计算设备2000可以执行图12实施例中的任一个或多个步骤,也即是,每个计算设备2000可以运行图15实施例中的任一个或多个模块。图15实施例中的不同模块可以在该计算设备集群上的不同计算设备上执行。其中,每个计算设备2000的结构与图19实施例中计算设备1900的结构相同。具体来说,每个计算设备2000包括总线2001、处理器2002、通信接口2003和存储器2004。处理器2002、存储器2004和通信接口2003之间通过总线2001通信。不同计算设备2000之间可以通过通信网络建立通信通路。每个计算设备2000上运行获取模块1501、读取模块1502以及转换模块1503中的任意一个或多个。任一计算设备2000可以为云环境中的计算设备,或边缘环境中的计算设备,或终端环境中的计算设备。
进一步的,由于键值对占用的存储空间较大,另外根据业务需要,可能需要存储大量的键值对,因此计算设备2000本身可能无法存储全部的键值对,有鉴于此,本申请还提出了一种计算设备集群。如图21所示,读取模块1502部署在云存储服务中(例如对象存储服务),用户在云存储服务中申请一定容量的存储空间以存储键值对,并相应地在云存储服务中部署读取模块1502,该读取模块1502可以访问该存储空间并读取键值对。计算设备2000运行时,通过通信网络从远端的读取模块1502中读取键值对的值。每个计算设备2000上运行获取模块1501以及转换模块1503中的任意一个或多个。任一计算设备2000可以为云环境中的计算设备,或边缘环境中的计算设备,或终端环境中的计算设备。
在一个示例性实施例中,本申请还提供了一种包含指令的计算机程序产品,该计算设备程序产品被至少一台计算设备执行时,该至少一台计算设备执行前述数据存储方法。该计算机程序产品可以为一个软件安装包,在需要使用前述数据存储方法的情况下,可以下载该计算机程序产品并在计算设备上执行该计算机程序产品。
在一个示例性实施例中,本申请还提供了一种包含指令的计算机程序产品,该计算设备程序产品被至少一台计算设备执行时,该至少一台计算设备执行前述数据获取方法。该计算机程序产品可以为一个软件安装包,在需要使用前述数据获取方法的情况下,可以下载该计算机程序产品并在计算设备上执行该计算机程序产品。
在一个示例性实施例中,本申请还提供了一种存储系统,在一种可能的实现方式中,该系统包括:执行上述数据存储方法的计算设备和执行上述数据获取方法的计算设备。在另一种可能的实现方式中,该系统包括:执行上述数据存储方法的计算设备集群和执行上述数据获取方法的计算设备集群。在另一种可能的实现方式中,该系统包括:执行上述数据存储方法的计算设备和执行上述数据获取方法的计算设备集群。在另一种可能的实现方式中,该系统包括:执行上述数据存储方法的计算设备和执行上述数据获取方法的计算设备集群。
在一个示例性实施例中,本申请还提供了一种芯片,该芯片包括处理器和/或程序指令,当该芯片运行时,实现上述实施例中数据存储方法所执行的操作。
在一个示例性实施例中,本申请还提供了一种芯片,该芯片包括处理器和/或程序指令,当该芯片运行时,实现上述实施例中数据获取方法所执行的操作。
上述所有可选技术方案,可以采用任意结合形成本申请的可选实施例,在此不再一一赘述。
上述各个附图对应的流程的描述各有侧重,某个流程中没有详述的部分,可以参见其他流程的相关描述。
在上述实施例中,可以全部或部分地通过软件、硬件、固件或者其任意组合来实现。当使用软件实现时,可以全部或部分地以计算机程序产品的形式实现。所述计算机程序产品包括一个或多个计算机程序指令。在计算机上加载和执行所述计算机程序指令时,全部或部分地产生按照本申请实施例所述的流程或功能。所述计算机可以是通用计算机、专用计算机、计算机网络、或者其他可编程装置。所述计算机指令可以存储在计算机可读存储介质中,或者从一个计算机可读存储介质向另一个计算机可读存储介质传输,例如,所述计算机程序指令可以从一个网站站点、计算机、服务器或数据中心通过有线或无线方式向另一个网站站点、计算机、服务器或数据中心进行传输。所述计算机可读存储介质可以是计算机能够存取的任何可用介质或者是包含一个或多个可用介质集成的服务器、数据中心等数据存储设备。所述可用介质可以是磁性介质(例如软盘、硬盘、磁带)、光介质(例如,数字视频光盘(digital video disc,DVD)、或者半导体介质(例如固态硬盘)等。
本申请中术语“和/或”,仅仅是一种描述关联对象的关联关系,表示可以存在三种关系,例如,A和/或B,可以表示:单独存在A,同时存在A和B,单独存在B这三种情况。另外,本申请中的字符“/”,一般表示前后关联对象是一种“或”的关系。
本申请中术语“多个”的含义是指两个或两个以上,例如,多个数据包是指两个或两个以上的数据包。
本申请中术语“第一”“第二”等字样用于对作用和功能基本相同的相同项或相似项进行区分,本领域技术人员可以理解,“第一”“第二”等字样不对数量和执行顺序进行限定。
本领域普通技术人员可以理解实现上述实施例的全部或部分步骤可以通过硬件来完成,也可以通过程序来指令相关的硬件完成,所述的程序可以存储于一种计算机可读存储介质中,上述提到的存储介质可以是只读存储器,磁盘或光盘等。
以上所述仅为本申请的可选实施例,并不用以限制本申请,凡在本申请的精神和原则之内,所作的任何修改、等同替换、改进等,均应包含在本申请的保护范围之内。
Claims (20)
1.一种数据存储方法,其特征在于,所述方法包括:
获取待处理的键值对,所述键值对的键为第一对象,所述键值对的值为第二对象;
对所述第一对象进行处理,得到所述第一对象的哈希值;
对所述第二对象进行拆箱转换,得到所述第二对象的实例数据;
将所述哈希值和所述实例数据分别存储至第一数组和第二数组,所述第一数组和所述第二数组不同。
2.根据权利要求1所述的方法,其特征在于,所述对所述第一对象进行处理,得到所述第一对象的哈希值,包括:
获取所述第一对象包括的所述哈希值;或者,
对所述第一对象进行哈希运算,得到所述哈希值。
3.根据权利要求1或2所述的方法,其特征在于,所述获取待处理的键值对,包括:
从哈希表的链表的任一节点中读取所述键值对。
4.根据权利要求1至3任一所述的方法,其特征在于,所述将所述哈希值和所述实例数据分别存储至第一数组和第二数组,包括:
向所述第一数组的第一位置添加所述哈希值;
根据所述第一位置,在所述第二数组中,获取所述第一位置对应的第二位置;
向所述第二数组的所述第二位置添加所述实例数据。
5.根据权利要求1至4任一所述的方法,其特征在于,所述将所述哈希值和所述实例数据分别存储至第一数组和第二数组,包括:
当未检测到哈希冲突事件时,将所述哈希值和所述实例数据分别存储至所述第一数组和所述第二数组;
所述方法还包括:
当检测到哈希冲突事件时,将所述第一对象和所述实例数据分别存储至第三数组和第四数组,所述第三数组和所述第四数组不同。
6.根据权利要求5所述的方法,其特征在于,所述将所述第一对象和所述实例数据分别存储至第三数组和第四数组,包括:
向所述第三数组的第三位置添加所述第一对象;
根据所述第三位置,在所述第四数组中,获取所述第三位置对应的第四位置;
向所述第四数组的所述第四位置添加所述实例数据。
7.根据权利要求5所述的方法,其特征在于,所述将所述第一对象和所述实例数据分别存储至第三数组和第四数组之前,所述方法还包括:
根据哈希表的哈希冲突历史记录,对哈希冲突事件进行检测,所述哈希表已存储所述键值对。
8.根据权利要求7所述的方法,其特征在于,所述根据哈希表的哈希冲突历史记录,对哈希冲突事件进行检测,包括:
当所述哈希冲突历史记录包括所述键值对的哈希冲突记录时,检测到所述哈希冲突事件;或者,
当所述哈希冲突历史记录包括所述哈希表中任一键值对的哈希冲突记录时,检测到所述哈希冲突事件。
9.一种数据获取方法,其特征在于,所述方法包括:
根据数据获取指令中的第一对象,获取所述第一对象的哈希值;
在第一数组中,获取所述哈希值所处的位置,得到第一位置;
根据所述第一位置,在第二数组中,获取所述第一位置对应的第二位置,所述第二数组和所述第一数组不同;
从所述第二数组的所述第二位置读取第二对象的实例数据;
对所述第二对象的实例数据进行装箱转换,得到所述第二对象。
10.根据权利要求9所述的方法,其特征在于,所述方法还包括:
当检测到哈希冲突事件时,在第三数组中,获取所述第一对象所处的位置,得到第三位置;
根据所述第三位置,在第四数组中,获取所述第三位置对应的第四位置,所述第四数组和所述第三数组不同;
从所述第四数组的所述第四位置读取所述第二对象。
11.一种计算设备,其特征在于,所述计算设备,包括:
获取模块,用于获取待处理的键值对,所述键值对的键为第一对象,所述键值对的值为第二对象;
处理模块,用于对所述第一对象进行处理,得到所述第一对象的哈希值;对所述第二对象进行拆箱转换,得到所述第二对象的实例数据;
存储模块,用于将所述哈希值和所述实例数据分别存储至第一数组和第二数组,所述第一数组和所述第二数组不同。
12.根据权利要求11所述的计算设备,其特征在于,所述处理模块,用于获取所述第一对象包括的所述哈希值;或者,对所述第一对象进行哈希运算,得到所述哈希值。
13.根据权利要求11或12所述的计算设备,其特征在于,所述获取模块,用于从哈希表的链表的任一节点中读取所述键值对。
14.根据权利要求11至13任一所述的计算设备,其特征在于,所述存储模块,用于向所述第一数组的第一位置添加所述哈希值;根据所述第一位置,在所述第二数组中,获取所述第一位置对应的第二位置;向所述第二数组的所述第二位置添加所述实例数据。
15.根据权利要求11至14任一所述的计算设备,其特征在于,所述存储模块,用于当未检测到哈希冲突事件时,将所述哈希值和所述实例数据分别存储至所述第一数组和所述第二数组;当检测到哈希冲突事件时,将所述第一对象和所述实例数据分别存储至第三数组和第四数组,所述第三数组和所述第四数组不同。
16.根据权利要求15所述的计算设备,其特征在于,所述存储模块,用于向所述第三数组的第三位置添加所述第一对象;根据所述第三位置,在所述第四数组中,获取所述第三位置对应的第四位置;向所述第四数组的所述第四位置添加所述实例数据。
17.根据权利要求16所述的计算设备,其特征在于,所述计算设备还包括:
检测模块,用于根据哈希表的哈希冲突历史记录,对哈希冲突事件进行检测,所述哈希表已存储所述键值对。
18.根据权利要求17所述的计算设备,其特征在于,所述检测模块,用于当所述哈希冲突历史记录包括所述键值对的哈希冲突记录时,检测到所述哈希冲突事件;或者,当所述哈希冲突历史记录包括所述哈希表中任一键值对的哈希冲突记录时,检测到所述哈希冲突事件。
19.一种计算设备集群,其特征在于,包括至少一个计算设备,每个计算设备包括处理器和存储器,所述至少一个计算设备的处理器用于执行如权利要求1至权利要求8中任一项所述的数据存储方法。
20.一种非瞬态的可读存储介质,其特征在于,所述非瞬态的可读存储介质被计算设备集群中的至少一个计算设备执行时,所述至少一个计算设备执行权利要求1至权利要求8中任一项所述的数据存储方法。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201811095845.8A CN110928483B (zh) | 2018-09-19 | 2018-09-19 | 数据存储、数据获取方法及设备 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201811095845.8A CN110928483B (zh) | 2018-09-19 | 2018-09-19 | 数据存储、数据获取方法及设备 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN110928483A true CN110928483A (zh) | 2020-03-27 |
CN110928483B CN110928483B (zh) | 2021-04-09 |
Family
ID=69856079
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201811095845.8A Active CN110928483B (zh) | 2018-09-19 | 2018-09-19 | 数据存储、数据获取方法及设备 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN110928483B (zh) |
Cited By (8)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN111694559A (zh) * | 2020-05-21 | 2020-09-22 | 北京云杉世纪网络科技有限公司 | Gc程序语言中哈希表的实现方法及装置 |
CN111897784A (zh) * | 2020-07-13 | 2020-11-06 | 安徽大学 | 一种面向键值存储的近数据计算集群系统 |
CN112069091A (zh) * | 2020-08-17 | 2020-12-11 | 北京科技大学 | 一种应用于分子动力学模拟软件的访存优化方法及装置 |
CN112153696A (zh) * | 2020-09-25 | 2020-12-29 | Oppo广东移动通信有限公司 | Rlc sdu分段处理方法、装置及终端 |
CN112434035A (zh) * | 2020-11-20 | 2021-03-02 | 上海交通大学 | 基于机器学习的并发哈希索引数据结构的索引方法及系统 |
CN112612925A (zh) * | 2020-12-29 | 2021-04-06 | 上海优扬新媒信息技术有限公司 | 数据的存储方法、读取方法以及电子设备 |
CN113377819A (zh) * | 2021-07-07 | 2021-09-10 | 山东方寸微电子科技有限公司 | 一种哈希表滚动查找方法、系统及芯片 |
CN116340275A (zh) * | 2023-03-14 | 2023-06-27 | 深圳乐信软件技术有限公司 | Redis复杂对象内存压缩存储方法、装置及设备 |
Citations (6)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN103020262A (zh) * | 2012-12-24 | 2013-04-03 | Tcl集团股份有限公司 | 一种数据存储方法、系统及数据存储设备 |
US20160147750A1 (en) * | 2014-11-25 | 2016-05-26 | Rolando Blanco | Versioned Insert Only Hash Table for In-Memory Columnar Stores |
CN106202548A (zh) * | 2016-07-25 | 2016-12-07 | 网易(杭州)网络有限公司 | 数据存储方法、查找方法及装置 |
CN106326475A (zh) * | 2016-08-31 | 2017-01-11 | 中国科学院信息工程研究所 | 一种高效的静态哈希表实现方法及系统 |
CN106844676A (zh) * | 2017-01-24 | 2017-06-13 | 北京奇虎科技有限公司 | 数据存储方法及装置 |
CN108205577A (zh) * | 2016-12-20 | 2018-06-26 | 阿里巴巴集团控股有限公司 | 一种数组构建、数组查询的方法、装置及电子设备 |
-
2018
- 2018-09-19 CN CN201811095845.8A patent/CN110928483B/zh active Active
Patent Citations (6)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN103020262A (zh) * | 2012-12-24 | 2013-04-03 | Tcl集团股份有限公司 | 一种数据存储方法、系统及数据存储设备 |
US20160147750A1 (en) * | 2014-11-25 | 2016-05-26 | Rolando Blanco | Versioned Insert Only Hash Table for In-Memory Columnar Stores |
CN106202548A (zh) * | 2016-07-25 | 2016-12-07 | 网易(杭州)网络有限公司 | 数据存储方法、查找方法及装置 |
CN106326475A (zh) * | 2016-08-31 | 2017-01-11 | 中国科学院信息工程研究所 | 一种高效的静态哈希表实现方法及系统 |
CN108205577A (zh) * | 2016-12-20 | 2018-06-26 | 阿里巴巴集团控股有限公司 | 一种数组构建、数组查询的方法、装置及电子设备 |
CN106844676A (zh) * | 2017-01-24 | 2017-06-13 | 北京奇虎科技有限公司 | 数据存储方法及装置 |
Non-Patent Citations (1)
Title |
---|
孙勇 等: "面向云计算的键值型分布式存储系统研究", 《电子学报》 * |
Cited By (15)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN111694559A (zh) * | 2020-05-21 | 2020-09-22 | 北京云杉世纪网络科技有限公司 | Gc程序语言中哈希表的实现方法及装置 |
CN111694559B (zh) * | 2020-05-21 | 2023-07-21 | 北京云杉世纪网络科技有限公司 | Gc程序语言中哈希表的实现方法及装置 |
CN111897784A (zh) * | 2020-07-13 | 2020-11-06 | 安徽大学 | 一种面向键值存储的近数据计算集群系统 |
CN111897784B (zh) * | 2020-07-13 | 2022-12-06 | 安徽大学 | 一种面向键值存储的近数据计算集群系统 |
CN112069091A (zh) * | 2020-08-17 | 2020-12-11 | 北京科技大学 | 一种应用于分子动力学模拟软件的访存优化方法及装置 |
CN112069091B (zh) * | 2020-08-17 | 2023-09-01 | 北京科技大学 | 一种应用于分子动力学模拟软件的访存优化方法及装置 |
CN112153696A (zh) * | 2020-09-25 | 2020-12-29 | Oppo广东移动通信有限公司 | Rlc sdu分段处理方法、装置及终端 |
CN112434035A (zh) * | 2020-11-20 | 2021-03-02 | 上海交通大学 | 基于机器学习的并发哈希索引数据结构的索引方法及系统 |
CN112434035B (zh) * | 2020-11-20 | 2022-09-23 | 上海交通大学 | 基于机器学习的并发哈希索引数据结构的索引方法及系统 |
CN112612925B (zh) * | 2020-12-29 | 2022-12-23 | 度小满科技(北京)有限公司 | 数据的存储方法、读取方法以及电子设备 |
CN112612925A (zh) * | 2020-12-29 | 2021-04-06 | 上海优扬新媒信息技术有限公司 | 数据的存储方法、读取方法以及电子设备 |
CN113377819B (zh) * | 2021-07-07 | 2023-02-03 | 山东方寸微电子科技有限公司 | 一种哈希表滚动查找方法、系统及芯片 |
CN113377819A (zh) * | 2021-07-07 | 2021-09-10 | 山东方寸微电子科技有限公司 | 一种哈希表滚动查找方法、系统及芯片 |
CN116340275A (zh) * | 2023-03-14 | 2023-06-27 | 深圳乐信软件技术有限公司 | Redis复杂对象内存压缩存储方法、装置及设备 |
CN116340275B (zh) * | 2023-03-14 | 2024-03-01 | 深圳市乐信信息服务有限公司 | Redis复杂对象内存压缩存储方法、装置及设备 |
Also Published As
Publication number | Publication date |
---|---|
CN110928483B (zh) | 2021-04-09 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN110928483B (zh) | 数据存储、数据获取方法及设备 | |
US9639501B1 (en) | Apparatus and methods to compress data in a network device and perform ternary content addressable memory (TCAM) processing | |
CN105207678B (zh) | 一种改进型lz4压缩算法的硬件实现系统 | |
KR101745456B1 (ko) | HiL 시뮬레이션 환경에서 대용량 데이터를 전송하기 위한 전자제어 장치, 이를 포함하는 시스템 및 그 방법 | |
US9306851B1 (en) | Apparatus and methods to store data in a network device and perform longest prefix match (LPM) processing | |
EP3780438B1 (en) | Data transmission method and related device | |
CN108874987B (zh) | 表项管理方法、装置及交换芯片 | |
EP3196776A1 (en) | Method and device for data processing | |
KR102326830B1 (ko) | 전송 블록 크기를 확정하는 방법, 장치 및 기기 | |
CN113900810A (zh) | 分布式图处理方法、系统及存储介质 | |
CN115941598A (zh) | 一种流表半卸载方法、设备及介质 | |
CN114710467B (zh) | Ip地址存储方法、装置和硬件网关 | |
CN116578746A (zh) | 对象去重方法及装置 | |
WO2022199400A1 (zh) | 持久内存文件系统元数据的检索方法和装置、存储结构 | |
CN115834027B (zh) | 一种消息填充方法、装置、设备及计算机可读存储介质 | |
CN111294285B (zh) | 一种网络数据的分发方法及负载均衡器 | |
CN116346382A (zh) | 一种阻断恶意tcp连接的方法、装置及电子设备 | |
CN104636432A (zh) | 一种日志文件压缩和解压的方法及装置 | |
CN115167869A (zh) | 一种Java对象序列化和反序列化的方法、电子设备及介质 | |
US10996882B2 (en) | Fittest stripe selection for storage of data in storage systems | |
CN113051024B (zh) | 虚拟机热迁移方法、装置、电子设备及存储介质 | |
EP4086781A1 (en) | Data reading method and terminal | |
CN113986312A (zh) | 软件升级方法、装置、电子设备及计算机可读存储介质 | |
CN112241336A (zh) | 用于备份数据的方法、设备和计算机程序产品 | |
CN103714091A (zh) | 一种生成对象识别符及从其中提取属性信息的方法及装置 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant | ||
TR01 | Transfer of patent right | ||
TR01 | Transfer of patent right |
Effective date of registration: 20220222 Address after: 550025 Huawei cloud data center, jiaoxinggong Road, Qianzhong Avenue, Gui'an New District, Guiyang City, Guizhou Province Patentee after: Huawei Cloud Computing Technology Co.,Ltd. Address before: 518129 Bantian HUAWEI headquarters office building, Longgang District, Guangdong, Shenzhen Patentee before: HUAWEI TECHNOLOGIES Co.,Ltd. |