本发明涉及数据存储领域,尤其涉及一种前缀树存储方法、装置、存储介质和计算机设备。
背景技术:
现有的树型数据结构一般都以方便使用为第一目的,而忽略了在使用中付出的成本问题。而像树型数据结构这样的基本的数据结构在平时的项目中使用频率会比较高,占用的存储空间较大,导致日常使用树型数据结构成本过高,成本的积累就会成为整个项目的短板。
技术实现要素:
本发明旨在解决上面描述的问题。
根据本发明的第一方面,提供了一种前缀树存储方法,包括:
将前缀树中的每个原始前缀树节点均拆分为多个第一级容量大小的前缀树节点,为每个前缀树节点分配一个第一存储单元,所述第一存储单元存储所述前缀树节点的子节点情况;
为每个前缀树节点分配一个第二存储单元,所述第二存储单元存储所述前缀树节点的第一个子节点的编号;
创建第三存储单元存储所述前缀树节点间裁剪掉的节点的数量。
优选的,所述第一级容量的大小为nbit,所述第一级存储单元的大小为2nbit,所述第二级存储单元和所述第三级存储单元的大小均为为log2(2*n)bit,其中n为叶子节点数量。
优选的,所述第一级容量的大小为4bit,n为2^15,所述第一存储单元、所述第二存储单元及所述第三存储单元的大小均为2byte。
优选的,为每个前缀树节点分配一个第二存储单元的步骤之前,还包括:
从所述前缀树的根节点开始,为所述前缀树中的各个前缀树节点进行广度遍历编号。
优选的,每个前缀树节点的第一存储单元、第二存储单元和第三存储单元构成一个元素,所述前缀树的全部前缀树节点的元素构成中间节点存储数组,通过所述中间节点存储数据存储所述前缀树的中间节点信息。
根据本发明的又一方面,提供了一种前缀树存储装置,包括:
第一存储单元管理模块,用于将前缀树中的每个原始前缀树节点均拆分为多个第一级容量大小的前缀树节点,为每个前缀树节点分配一个第一存储单元,所述第一存储单元存储所述前缀树节点的子节点情况;
第二存储单元管理模块,用于为每个前缀树节点分配一个第二存储单元,所述第二存储单元存储所述前缀树节点的第一个子节点的编号;
第三存储单元管理模块,用于创建第三存储单元存储前缀树节点间裁剪掉的节点的数量。
优选的,该装置还包括:
编号模块,用于从所述前缀树的根节点开始,为所述前缀树中的各个前缀树节点进行广度遍历编号。
优选的,所述第一级容量的大小为nbit,所述第一级存储单元的大小为2nbit,所述第二级存储单元和所述第三级存储单元的大小均为log2(2*n)bit,其中n为叶子节点数量,该装置还包括:
内存占用管理模块,用于使用每个前缀树节点的第一存储单元、第二存储单元和第三存储单元构成一个元素,将所述前缀树的全部前缀树节点的元素构成中间节点存储数组,通过所述中间节点存储数据存储所述前缀树的中间节点信息。
根据本发明的又一方面,还提供了一种存储介质,该存储介质上存储有计算机程序,所述计算机程序被执行时实现上述前缀树存储方法的步骤。
根据本发明的又一方面,还提供了一种计算机设备,包括处理器和存储器,所述存储器上存储有计算机程序,所述程序被所述处理器执行时实现上述前缀树存储方法的步骤。
本发明提供了一种前缀树存储方法、装置、存储介质和计算机设备,将前缀树中的每个原始前缀树节点均拆分为多个第一级容量大小的前缀树节点,为每个前缀树节点分配一个第一存储单元,所述第一存储单元存储所述前缀树节点的子节点情况,为每个前缀树节点分配一个第二存储单元,所述第二存储单元存储所述前缀树节点的第一个子节点的编号,创建第三存储单元存储所述前缀树节点裁剪的子节点的数量。使用内存空间布局的全新设计,极大压缩了前缀树占用的存储空间,改善了前缀树内存占用较高的劣势。降低了基础数据结构前缀树的内存成本,解决了前缀树占用存储空间大的问题,前缀树的内存占用得以减小,进而能够解放使用它的项目的成本。
参照附图来阅读对于示例性实施例的以下描述,本发明的其他特性特征和优点将变得清晰。
附图说明
并入到说明书中并且构成说明书的一部分的附图示出了本发明的实施例,并且与描述一起用于解释本发明的原理。在这些附图中,类似的附图标记用于表示类似的要素。下面描述中的附图是本发明的一些实施例,而不是全部实施例。对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,可以根据这些附图获得其他的附图。
图1示例性地示出了本发明的一实施例提供的一种前缀树存储方法的流程;
图2示例性地示出了本发明的一实施例中的前缀树结构;
图3示例性地示出了对图2中的前缀树进行拆分后绘制的前缀树;
图4示例性地示出了普遍的前缀树实现方案内存空间布局;
图5示例性地示出了本发明的一实施例提供的一种前缀树存储方法占用内存空间布局;
图6示例性地示出了本发明的一实施例提供的一种前缀树存储装置。
具体实施方式
为使本发明实施例的目的、技术方案和优点更加清楚,下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。需要说明的是,在不冲突的情况下,本申请中的实施例及实施例中的特征可以相互任意组合。
现有的树型数据结构一般都以方便使用为第一目的,而忽略了在使用中付出的成本问题。而像树型数据结构这样的基本的数据结构在平时的项目中使用频率会比较高,占用的存储空间较大,导致日常使用树型数据结构成本过高。
为了解决上述问题,本发明的实施例提供了一种前缀树存储方法、装置、存储介质和计算机设备。重新考虑基本的前缀树数据结构的实现方案,改善了前缀树实现的内存空间布局,有效压缩了使用成本。
本发明的一实施例提供了一种前缀树存储方法,通过改进存储前缀树的数据结构,节省了前缀树的存储空间开销。
该方法的实现流程如图1所示,包括:
步骤101、对前缀树进行裁剪。
由于前缀树中有一些无用的中间节点,例如只有一个子节点的中间节点。对该部分中间节点可以进行裁剪,完成压缩边处理。通过压缩边,最终变成一个除叶子节点外,其他节点必有多于2个子节点的树形结构。
本步骤为可选步骤,可根据实际应用情况选择是否对前缀树进行裁剪,以进一步压缩前缀树占用的存储空间。
步骤102、将前缀树中的每个原始前缀树节点均拆分为多个第一级容量大小的前缀树节点,为每个前缀树节点分配一个第一存储单元,所述第一存储单元存储所述前缀树节点的子节点情况。
本步骤中,将前缀树中的前缀树节点值超过第一级容量大小的每个原始前缀树节点,拆分成多个第一级容量大小为xbit的前缀树节点。优选的,该第一级容量为4bit。例如,1个1byte的原始前缀树节点,可拆分成2个4bit的前缀树节点(以1byte=8bit为例,>1byte的节点也可以拆分成k个4bit)。通过拆分,每个节点的子节点数目被压缩为2^4=16个,则可以用2个byte的空间存储一个节点的子节点情况,该空间即为第一存储单元。
步骤103、从所述前缀树的根节点开始,为所述前缀树中的各个前缀树节点进行广度遍历编号。
本步骤中,将每个前缀树节点用一个编号代替,从根节点(编号0)开始广度遍历编号,依次增加。一个前缀树在经步骤101的合理裁剪之后,总节点数应该小于2n-1,其中,n是叶子节点的数目(节点最多的情况是满二叉树的情况)。如果限制n的数量,也就是创建前缀树的总条目数,就能限制存储一个节点信息的所占的空间。本发明实施例中,使用2byte=16bit大小的第一存储单元存储一个节点的信息,则2^16>=2n-1,最大条目数为2^16/2=32768。实际使用时,条目数超过此数字,可以通过分层建立前缀树来解决。
步骤104、为每个前缀树节点分配一个第二存储单元,所述第二存储单元存储所述前缀树节点的第一个子节点的编号。
本步骤中,对于前缀树的一个中间节点,还需要保存它的分支结构,使用2^xbit大小的第二存储单元存储前缀树节点的第一个子节点的编号。根据步骤102,一个uint16的bitmap(即第一存储单元)可以表示一个节点有哪些子节点。本步骤中,使用2byte大小的第二存储单元存储前缀树节点第一个子节点的编号,一个编号即一个uint16的数字。由于步骤103中对节点进行了遍历编号,任何一个作为中间节点的前缀树节点的子节点编号是连续的,因此本步骤中只记录第一个子节点的编号即可。
步骤105、创建第三存储单元存储所述前缀树节点间裁剪掉的节点的数量。
本步骤中,还需要一个uint16的第三存储单元记录该前缀树节点在步骤101中压缩掉的节点数目,即所述前缀树节点裁剪的子节点的数量。第三级存储单元的大小与整个前缀树的叶子节点数相关,如果叶子节点数是n,则第三级存储单元的大小是:log2(2*n)个bit。
每个前缀树节点的第一存储单元、第二存储单元和第三存储单元构成一个元素,所述前缀树的全部前缀树节点的元素构成中间节点存储数组,通过所述中间节点存储数组存储所述前缀树的中间节点信息。以每个前缀树节点的第三存储单元为元素构建裁剪信息存储数据。对于叶子节点,则只需要保存value即可,例如,通过叶子节点存储数组存储。所述第一级容量的大小为nbit,所述第一级存储单元的大小为2^nbit,所述第二级存储单元和所述第三级存储单元的大小均为log2(2*n)bit,其中n为叶子节点数量。
优选的,所述第一级容量的大小为4bit,n为2^15,所述第一存储单元、所述第二存储单元及所述第三存储单元的大小均为2byte。这样,一个作为中间节点的前缀树节点总共使用6byte即可存储。相较于现有的实现中使用指针,一个中间节点至少需要8byte的指针和8byte的节点信息的存储方式,大大节约了存储空间。
本发明的一实施例还提供了一种前缀树存储方法,以如图2所示的前缀树为例进行说明。
在对图2所示的前缀树中的原始前缀树节点进行拆分后,对该前缀树的描述如下:
abb--0x060x01,0x060x02,0x060x02
abc--0x060x01,0x060x02,0x060x03
ace--0x060x01,0x060x03,0x060x05
acf--0x060x01,0x060x03,0x060x06
b1--0x060x02,0x030x01
b2--0x060x03,0x030x02
如图3所示,为根据上述信息绘制的前缀树。
最终的存储结构为:
^//id:00children:01bitmap:0x0007step:1
0x01//id:0lchildren:04bitmap:0x0006step:1
0x02//id:02children:$bitmap:0x0000step:2
0x03//id:03children:$bitmap:0x0000step:2
0x02//id:04children:06bitmap:0x0006step:1
0x03//id:05children:08bitmap:0x0030step:1
0x02//id:06children:$bitmap:0x0000step:0
0x03//id:07children:$bitmap:0x0000step:0
0x05//id:08children:$bitmap:0x0000step:0
0x06//id:09children:$bitmap:0x0000step:0
普遍的前缀树实现方案内存空间布局如图4所示,中间节点的每个子节点均对应8byte的子节点指针。
使用本发明的实施例提供的前缀树存储方法存储前缀树时占用内存空间布局如图5所示。
由图4和图5对比能够看出,本发明的实施例提供的技术方案有很大的空间节约。
本发明的一实施例还提供了一种前缀树存储装置,其结构如图6所示,包括:
第一存储单元管理模块601,用于将前缀树中的每个原始前缀树节点均拆分为多个第一级容量大小的前缀树节点,为每个前缀树节点分配一个第一存储单元,所述第一存储单元存储所述前缀树节点的子节点情况;
第二存储单元管理模块602,用于为每个前缀树节点分配一个第二存储单元,所述第二存储单元存储所述前缀树节点的第一个子节点的编号;
第三存储单元管理模块603,用于创建第三存储单元存储前缀树节点间裁剪掉的节点的数量。
优选的,该装置还包括:
编号模块604,用于从所述前缀树的根节点开始,为所述前缀树中的各个前缀树节点进行广度遍历编号。
优选的,所述第一存储单元、所述第二存储单元及所述第三存储单元的大小均为2byte,该装置还包括:
内存占用管理模块605,用于使用每个前缀树节点的第一存储单元、第二存储单元和第三存储单元构成一个元素,将所述前缀树的全部前缀树节点的元素构成中间节点存储数组,通过所述中间节点存储数据存储所述前缀树的中间节点信息。
本发明的一实施例还提供了一种存储介质,该存储介质上存储有计算机程序,所述计算机程序被执行时实现本发明的实施例提供的前缀树存储方法的步骤。
本发明的一实施例还提供了一种计算机设备,包括处理器和存储器,所述存储器上存储有计算机程序,所述程序被所述处理器执行时实现本发明的实施例提供的前缀树存储方法的步骤。
本发明的实施例提供了一种前缀树存储方法、装置、存储介质和计算机设备,将前缀树中的每个原始前缀树节点均拆分为多个第一级容量大小的前缀树节点,为每个前缀树节点分配一个第一存储单元,所述第一存储单元存储所述前缀树节点的子节点情况,为每个前缀树节点分配一个第二存储单元,所述第二存储单元存储所述前缀树节点的第一个子节点的编号,创建第三存储单元存储前缀树节点间裁剪掉的节点的数量。使用内存空间布局的全新设计,极大压缩了前缀树占用的存储空间,改善了前缀树内存占用较高的劣势。降低了基础数据结构前缀树的内存成本,解决了前缀树占用存储空间大的问题,前缀树的内存占用得以减小,进而能够解放使用它的项目的成本。
上面描述的内容可以单独地或者以各种方式组合起来实施,而这些变型方式都在本发明的保护范围之内。
最后应说明的是:以上实施例仅用以说明本发明的技术方案,而非对其限制。尽管参照前述实施例对本发明进行了详细的说明,本领域的普通技术人员应当理解:其依然可以对前述各实施例所记载的技术方案进行修改,或者对其中部分技术特征进行等同替换;而这些修改或者替换,并不使相应技术方案的本质脱离本发明各实施例技术方案的精神和范围。