一种数据存储方法及装置的制造方法

文档序号:10724917阅读:328来源:国知局
一种数据存储方法及装置的制造方法
【专利摘要】本发明实施例公开了一种数据存储方法及装置,针对待存储数据,构建至少两级链表,该待存储数据存储在底层链表中,在底层链表包含的存储数据全部相同时,删除该底层链表,并更新该底层链表在上一级链表中的状态。一方面,将包含的存储数据全部相同的底层链表删除,节省了内存空间的占用;另一方面,当数据量很大、构建了多个底层链表时,如果出现数据变化的情况,仅需修改该数据对应的底层链表及该底层链表在上一级链表中的状态,不需要将全部链表进行解压?修改?压缩的处理,提高了执行效率。
【专利说明】
一种数据存储方法及装置
技术领域
[0001 ]本发明涉及计算机技术领域,特别涉及一种数据存储方法及装置。
【背景技术】
[0002] 随着科学技术的发展,计算机已深入人们的生活,并带来了巨大的便利。目前,利 用计算机存储数据已十分普遍。比如,公司记录员工的考勤数据,一般都采用计算机来存 储。
[0003] 例如,公司A需要记录8个员工的考勤信息,传统的记录方案是在计算机中存储每 一天正常考勤员工的ID列表,比如:2016-2-15:[1,2,3,4,5,6,7,8]。假如员工ID采用的数 据类型是CHAR型(占用1个BYTE),则在没有员工缺勤的情况下,存储当天的考勤记录需要8 个BYTE(内存占用总数=员工个数*员工ID数据类型占用内存数)。当该公司的规模再扩大, 比如扩大到100000个员工时,那么员工ID的数据类型就不能使用CHAR型,因为CHAR型数据 只能表示0~127,员工ID的类型必须使用INT型(占用4个BYTE),则在没有员工缺勤的情况 下,存储当天的考勤记录需要400,000(即100000*4)个BYTE。
[0004] -种更优的方案是构造一个BIT-MAP(位图文件),用于存储每一个员工的考勤信 息,如果某员工当前的考勤正常,则将该员工对应的位置设置成1,否则设置成0。
[0005] 以上述例子进行说明,当公司A中存在8个员工时,将这些员工映射到一个8个BIT 的数组中,假设2016-2-16这天员工4和员工7考勤不正常时,其所对应的BIT-MAP如图1所 示。由此可以看出,仅需8个比特位(即1个BYTE)便可存储所有员工的考勤信息,所占用的计 算机的内存为传统方案的1/8。当该公司的规模再扩大,比如扩大到100000个员工时,需要 申请一个12500 (即100000/8)个BYTE的CHAR型数组arrayA,其中:arrayA[0 ]对应十进制数0 ~7,arrayA[l ]对应十进制数8~15,arrayA[2]对应十进制数16~23......以此类推。因此, 采用构造 BIT-MAP的方案,占用的计算机的内存仅为传统方案的1/32( 即12500/400000)。
[0006] 综上所述,当记录的数据中最大的数为N时,所需要消耗的内存最多为(1+N/8)个 BYTE,通过采用构造 BIT-MAP的方案能够很大程度上节省计算机内存。
[0007] 但是在很多的使用场景中,BIT-MAP数据结构中的比特位为0或者比特位为1都是 连续的,如上面例子中的员工考勤,对于工作日,绝大部分员工所对应的比特位都是1(即考 勤正常),因此该BIT-MAP数据结构仍然可以进行压缩和优化,进一步的节省内存。
[0008] 针对BIT-MAP数据结构中的比特位为0或者比特位为1都是连续的这一特点,通常 使用的方案是引入字符串压缩技术,比如对BIT-MAP字符串采用RLE (run-length encoding,游程编码)编码方法进行压缩。如图2的BIT-MAP为例:可以将图2中的BIT-MAP编 码为0,7,2,9,1,10,3。其意思是:第一位为0,连续有7个,接下来是2个1,9个0,1个1,10个0, 最后是3个1(这里只是对RLE编码基本原理的解释,实际中的编码可能会存在差异)。
[0009] 对于一个数据量很大的BIT-MAP,如果里面的数据分布存在大片连续的0或者大片 连续的1,采用RLE编码方法将其进行压缩,会节省很多内存的占用。
[0010]但是,采用RLE编码方法,如果BIT-MAP中的某一个比特位发生变化,需要向将压缩 的RLE编码解压成原始的BIT-MAP数据,将原始的BIT-MAP数据修改之后,再将修改后的BITMAP 压缩成 RLE 编码格式。
[0011 ]因此,对于数据频繁变化的情况,采用RLE编码方法压缩BIT-MAP数据,执行效率很 低。

【发明内容】

[0012] 本发明实施例的目的在于提供一种数据存储方法及装置,在节省计算机内存的基 础上,针对数据频繁变化的情况,提高执行效率。
[0013] 为达到上述目的,本发明实施例公开了一种数据存储方法,包括:
[0014] 获得待存储数据,并确定所述待存储数据对应的目标链表以及所述待存储数据在 所述目标链表的存储位置;
[0015] 将所述待存储数据存储至所述存储位置;
[0016] 在所述目标链表包含的所述数据全部相同时,删除所述目标链表,并更新所述目 标链表在上一级链表中的状态。
[0017] 为达到上述目的,本发明实施例还公开了一种数据存储装置,包括:
[0018] 获得确定模块,用于获得待存储数据,并确定所述待存储数据对应的目标链表以 及所述待存储数据在所述目标链表的存储位置;
[0019] 存储模块,用于将所述待存储数据存储至所述存储位置;
[0020] 删除更新模块,用于在所述目标链表包含的所述数据全部相同时,删除所述目标 链表,并更新所述目标链表在上一级链表中的状态。
[0021 ]由上述技术方案可见,应用本发明所示实施例,针对待存储数据,构建至少两级链 表,该待存储数据存储在底层链表中,在底层链表包含的存储数据全部相同时,删除该底层 链表,并更新该底层链表在上一级链表中的状态。一方面,将包含的存储数据全部相同的底 层链表删除,节省了内存空间的占用;另一方面,当数据量很大、构建了多个底层链表时,如 果出现数据变化的情况,仅需修改该数据对应的底层链表及该底层链表在上一级链表中的 状态,不需要将全部链表进行解压-修改-压缩的处理,提高了执行效率。
[0022] 当然,实施本发明的任一产品或方法必不一定需要同时达到以上所述的所有优 点。
【附图说明】
[0023] 为了更清楚地说明本发明实施例或现有技术中的技术方案,下面将对实施例或现 有技术描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本 发明的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以 根据这些附图获得其他的附图。
[0024] 图1为【背景技术】所举实例中对应的一个BIT-MAP;
[0025] 图2为【背景技术】所举实例中对应的另一个BIT-MAP;
[0026] 图3为本发明实施例提供的一种数据存储方法的流程示意图;
[0027] 图4为本发明实施例提供的一种数据结构;
[0028] 图5为本发明实施例提供的另一种数据结构;
[0029] 图6为本发明实施例提供的一种数据存储装置的结构示意图。
【具体实施方式】
[0030] 下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完 整地描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。基于 本发明中的实施例,本领域普通技术人员在没有作出创造性劳动前提下所获得的所有其他 实施例,都属于本发明保护的范围。
[0031] 为了解决现有技术问题,本发明实施例提供了一种数据存储方法及装置。下面首 先对本发明实施例提供的一种数据存储方法进行详细说明。
[0032] 图3为本发明实施例提供的一种数据存储方法的流程示意图,包括:
[0033] S101:获得待存储数据,并确定待存储数据对应的目标链表以及待存储数据在目 标链表的存储位置。
[0034]需要说明的是,以链表形式存储数据,可以以多级链表的形式对数据进行存储,本 发明实施例中所述目标链表指的是多级链表中最底层的链表。
[0035] 在本发明所示实施例中,链表中可以以位图形式存储数据。
[0036] 作为本发明的一种实施方式,可以预先建立待存储数据与底层链表的对应关系、 及待存储数据与其对应的底层链表的存储位置的对应关系。根据建立的对应关系,确定待 存储数据对应的目标链表以及待存储数据在目标链表的存储位置。
[0037] 假设待存储数据为A公司的考勤数据,A公司有120个员工,针对A公司的考勤数据 构建了两级链表,每个底层链表能容纳40条数据,则需构建3个底层链表。
[0038] 可以根据员工ID号或名称等,建立员工考勤数据与底层链表及底层链表的位图中 的存储位置的对应关系,比如,ID号为1-40的员工考勤数据对应第一个底层链表,ID号为 41-80的员工考勤数据对应第二个底层链表,ID号为81-120的员工考勤数据对应第三个底 层链表;ID号为1的员工对应第一个底层链表的位图中的编号为0的比特位,ID号为2的员工 对应第一个底层链表中的编号为1的比特位等等。
[0039]将考勤数据以位图形式存储在底层链表中,考勤数据可以有两种取值,比如用0表 示缺勤,用1表示考勤正常。
[0040] 假设获取了一条待存储数据:ID号为7的员工于2016年4月13日的考勤正常(即该 待存储数据为1 ),确定该待存储数据对应的目标链表为第一个底层链表,确定该待存储数 据在第一个底层链表的存储位置为编号为6的比特位。
[0041] 在本发明所示实施例中,可以预设X级链表,所述X为大于1的整数。确定的目标链 表为底层链表,即第X级链表。确定的待存储数据的存储位置为:在第X级链表的存储位置。 确定目标链表之前,可以依次确定所述待存储数据对应的第一级链表至第x-1级链表。
[0042] 在上述实施例中,链表的级别与数量均可以设定很多,链表结构比较复杂,因而, 建立待存储数据与底层链表的对应关系、及待存储数据与其对应的底层链表的存储位置的 对应关系,可以采用确定编号的方式。
[0043] 作为本发明的一种实施方式,确定待存储数据对应的第一级链表至第x-1级链表 的编号为:[(i%pi%P2% …%pj-1)/Pj],1彡 j彡X-1;
[0044] 确定待存储数据对应的第X级链表的编号为:[(i%Pl%P2%· · . %ργ··%Ρχ-0/ Ρχ];
[0045]所述i为待存储数据的编号,i为非负整数;
[0046]所述Pj为第j级链表对应的待存储数据的个数,p j = wx*wx-,所述Wj为预设 的第j级链表存储的状态的个数,w j = y j / o j,所述y j为预设的第j级链表的容量,单位为比 特,所述W为预设的第j+Ι级链表的状态在第j级链表中占用的比特位数;
[0047] 所述px为第X级链表存储的所述待存储数据的个数,?\ = ?^ = 7/〇\,所述7\为预设 的第X级链表的容量,单位为比特,所述〇x为预设的待存储数据在第X级链表中占用的比特 位数。
[0048] 在上述实施方式中,待存储数据在第X级链表的存储位置为一个比特位组,所述比 特位组包括:从编号为(i % ρχ)*〇χ的比特位到编号为(i % Ρχ) *〇χ+〇χ-1的比特位。
[0049] 下面对上述实施方式进行详细说明:
[0050] 预设X级链表,对于第j (j的范围是1~X)级链表来说,预设第j级链表的容量为yj 比特,位图中的比特位从0开始编号。其中,j越大表示该链表越低级。
[0051 ] j为X时,为第X级链表,第X级链表为最底层的链表,第X级链表所包含的位图用来 存储上述待存储数据,预设的待存储数据在第X级链表的位图中占用的比特位数为〇x比特; [0052] j不为X时,第j级链表所包含的位图用于存储第j+Ι级列表的状态,预设第j+Ι级列 表的状态在第j级链表的位图中占用的比特位数为W比特;
[0053] 预设的链表编号规则为:第一级链表从0开始编号,每个第一级链表下的第二级链 表从〇开始编号,每个第二级链表下的第三级链表从〇开始编号,以此类推,每个第x-1级链 表下的第X级链表从〇开始编号。
[0054] 贝1J:
[0055 ]第X级链表存储的数据个数为:px=wx = yx/ox
[0056] ···
[0057] 第 j 级链表存储的数据个数为:pj = wx*wx-= (yx/ox)*(yx-i/ox-i)*'"*(yj/ 〇j)
[0058] ···
[0059] 第一级链表存储的数据个数为:
[0060] pfwJwx-(yx/ox)*(yx-i/〇x-i)*."*(yj/〇j)*."*(yi/oi) 〇
[0061 ]对于待存储数据i(i的范围为0~n)来说,
[0062] 对应的第一链表的编号为:[i/Pl];
[0063] ···
[0064] 对应的第j级链表的编号为:[(i%Pl%p2% . · · %Pj-d/pj];
[0065] ···
[0066] 对应的第x级链表的编号为:[(i%Pl%p2%…%pj··· %px-0/px];
[0067] 在第x级链表的位图的存储位置:从(i % px)*〇x比特到(i % ρχ)*〇χ+〇χ-1比特。
[0068]下面以两级链表为例进行说明:
[0069]假设第二级链表的容量72为6比特,待存储数据在第二级链表中占用的比特位数〇2 为2比特,第二级链表存储的数据个数:P2 = y2/〇2 = 6/2 = 3。
[0070]假设第一级链表的容量71为12比特,第二级链表的状态在第一级链表中占用的比 特位数〇1为2比特,则第一级链表对应6个第二级链表,第一级链表对应的待存储数据的个 数:pl = (y2/〇2)*(yi/oi) = (6/2)*(12/2) = 18〇 [0071]对于数据i = 0来说:
[0072] 对应的第一级链表的编号为:[i/Pl] = [0/18] =0;
[0073] 对应的第二级链表的编号为:[(i%Pl)/p2] = [(0% 18)/3] = [0/3] =0。
[0074] 在第二级链表的位图的存储位置:
[0075] (i%p2)*〇2= (0%3)*2 = 0; (i%p2)*〇2+〇2-l = (0%3)*2+2_1 = 1,
[0076] 即编号为0和1的比特位用来存储数据i = 0。
[0077] 对于任意的数据i = 42来说:
[0078] 对应的第一级链表的编号为:[i/Pl] = [42/18] = 2;
[0079] 对应的第二级链表的编号为:[(i%Pl)/p2] = [(42% 18)/3] = [6/3] =2
[0080] 在第二级链表的位图的存储位置:
[0081] (i%p2)*〇2= (42%3)*2 = 0
[0082] (i %ρ2)*〇2+〇2~1 =42% 3)*2+2-1 = 1
[0083] 即编号为0和1的比特位用来存储数据i = 42。
[0084]下面以三级链表为例进行说明:
[0085]第三级链表存储的数据个数:p3 = y3/〇3 = 6/3 = 2;
[0086] 第二级链表对应的数据个数:p2=(y3/〇3)*(y2/〇2 ) = (6/3 Μ12/2 ) = 12
[0087] 第一级链表对应的数据个数:
[0088] p1= (yg/ogXyVc^Xyi/c^) = (6/3)*(12/2)*(8/1) = 96。
[0089] 对于数据;[ = 99来说:
[0090] 对应的第一级链表的编号为:[i/Pl] = [99/96] = 1;
[0091 ]对应的第二级链表的编号为:[(i%Pl)/p2] = [(99%96)/12] = [3/12] =0 [0092]在第三级链表的位图的存储位置:
[0093] (i%p3)*〇3= (99%2)*3 = 3
[0094] (i%p3)*o3+〇3-l = (99%2)*3+3-l = 5
[0095] 即编号为3、4、5的比特位用来存储数据。
[0096] S102:将待存储数据存储至所述存储位置。
[0097] 假设待存储数据考勤正常,该待存储数据的存储位置为第一个底层链表的编号为 6的比特位,将该待存储数据存储至该存储位置,即表示第一个底层链表的编号为6的比特 位的位图信息为1。
[0098] S103:在目标链表包含的所述数据全部相同时,删除目标链表,并更新目标链表在 上一级链表中的状态。
[0099] 在上述实施例中,待存储数据在底层链表的存储位置为一个比特位组,因此,目标 链表包含的所述数据全部相同,也就是说目标链表包含的每个比特位组的值全部相同,这 种情况下,删除该目标链表,并在目标链表的上一级链表中将目标链表的状态更新为对应 的第一预设值。
[0100] 仍以待存储数据为考勤数据为例进行说明,用0表示缺勤,用1表示考勤正常,则一 个比特位组中包括一个比特位。
[0101 ]目标链表在上一级链表中的状态可以包含三种状态:所有比特位全部为〇,所有比 特位全部为1,所有比特位既不全为0也不全为1。可以在目标链表的上一级链表中以两位比 特位来表示目标链表的状态(因为两位比特位可以表示四种状态),比如,用01表示目标链 表的所有比特位全部为1,10表示目标链表的所有比特位全部为0,00表示目标链表的所有 比特位既不全为0也不全为1,当然也可以用其他方式表示底层链表的位图的状态信息,在 此不做限制。
[0102] 在实际应用中,可以根据有几种状态,确定上一级链表中以几位比特位来表示目 标链表的状态。
[0103] 当目标链表中每一比特位全为1时,在上一级链表中将目标链表的状态更新为01; 当目标链表中每一比特位全为0时,在上一级链表中将目标链表的状态更新为10。
[0104] 应用本发明所示实施例,在目标链表包含的存储数据全部相同时,删除了该目标 链表,如果后来目标链表中的存储数据发生了改变,需要根据上一级链表中目标链表的状 态,重新创建该目标链表。
[0105] 在本发明所示实施例中,如果待存储数据为目标链表的第一条存储数据,则确定 所述目标链表不存在,需要创建目标链表,并在上一级链表中将目标链表的状态设置为对 应的初始值。在上述例子中,上一级链表中针对目标链表的初始值应该为10,表示目标链表 的所有比特位全部为0。
[0106] 在本发明所示实施例中,在所述目标链表包含的所述数据不全部相同时,在上一 级链表中将目标链表的状态更新为对应的第二预设值。在上述例子中,在目标链表包含的 所述数据不全部相同时(既包括0,又包括1),在上一级链表中将目标链表的状态更新为对 应的第二预设值(00)。
[0107] 在上述实施方式中,当预设了X级链表时,如果第j级链表包含的状态全部相同,则 删除该第j级链表,并更新该第j级链表在第j-i级链表中的状态。
[0108] 假设预设了三级链表,第三级链表中存储的是考勤数据,第三级链表存储的待存 储数据的个数为2,第二级链表对应的所述待存储数据的个数为12,第一级链表对应的所述 待存储数据的个数为96。也就是说第二级链表中包含了 6个第三级链表,第一级链表中包含 了 8个第二级链表。
[0109] 假设某个第三级链表中的存储的2个数据相同,都为1,则删除该第三级链表,将该 第三级链表的上一级链表中的状态更新为10。假设该第三级链表的上一级链表(即第二级 链表)包含的6个第三级链表中的存储的2个数据均相同,都为1,则删除这6个第三级链表, 且该第二级链表中包含的状态全部相同,均为10,这种情况下,删除该第二级链表,并更新 第二级链表在上一级链表中的状态。
[0110]应用本发明所示实施例,针对待存储数据,构建至少两级链表,该待存储数据存储 在底层链表中,在底层链表包含的存储数据全部相同时,删除该底层链表,并更新该底层链 表在上一级链表中的状态。一方面,将包含的存储数据全部相同的底层链表删除,节省了内 存空间的占用;另一方面,当数据量很大、构建了多个底层链表时,如果出现数据变化的情 况,仅需修改该数据对应的底层链表及该底层链表在上一级链表中的状态,不需要将全部 链表进行解压-修改-压缩的处理,提高了执行效率。
[0111]下面以C语言为例来描述本发明多级链表的数据结构,需要说明的是,本发明的多 级链表数据结构能够基于多种编程语言来实现,例如Python或者Java等。
[0112]作为本发明的一种实施方式,底层链表的数据结构如下:
[0114] 其中,pstNextSecondBitMap表示指向下一个底层链表的指针,当已经是最后一个 底层链表时,该指针为空;int类型数据iSecondBitMap表示底层链表的各个存储位置的值; 每一个底层链表表示的数据范围由上一级链表中的iBeginID和该底层链表对应上一级链 表的位置决定。
[0115]上一级链表的数据结构如下:
[0118] 其中,pstNextFirstBitMap表示指向下一个同一级链表的指针,当该链表已经是 同一级中最后一个链表时,该指针为空;int类型数据iBeginID表示该链表的第一个比特位 表示的值,可以是1024的整数倍,如0、1024、2048等;long long型数据llFirstBitMap: long long类型的数据一共64个比特位,本实施例中,用上一级链表中的每两位比特位表示一个 底层链表的状态,llFirstBitMap可以表示32个底层链表的状态:当这两个比特位中左边的 比特位为1时,表示对应的底层链表的所有比特位为0,当这两个比特位中右边的比特位为1 时,表示对应的底层链表的所有比特位为1,当这两个比特位全为0时,表示对应的底层链表 的所有比特位既不全为1,也不全为〇 ;链表的头结点pstSecondBitMap用于指向下一级链 表。
[0119] 假设目标链表的上一级链表的iBeginID为2048,该上一级链表对应了 32个底层链 表的状态,举例说明该32个底层链表中每一个底层链表表示的数据范围:上一级链表中编 号为8和9的比特位对应的底层链表表示的最小值为2048+8/2*32 = 2176,其中,8/2表示在 编号为8和9的比特位对应的底层链表之前有4个底层链表,一共占用了 8/2*32个比特位,加 上初始的2048,编号为8和9的比特位对应的底层链表的数据最小值为2048+8/2*32 = 2176; 每个底层链表占用32个比特位,编号为8和9的比特位对应的底层链表的数据最大值为2176 +32-1 = 2207。
[0120] 整体的数据结构可以如图4所示:上一级链表通过指针pstNextFirstBitMap串联 成一个单链表,每一个上一级链表还记录有其对应的底层链表的链表头结点,底层链表通 过pstNextSecondBitMap串联成一个单链表。
[0121] 假设Z公司有2048个员工,员工ID从0到2047,在某一天有3个员工的考勤为缺勤, 他们的ID分别是100、328和1530,如果采用传统的方式来记录,需要2048/8 = 256个BYTE的 字符串来记录这一信息,在这天的考勤记录中,只需要将这个字符串的第100个、第328个和 第1530个比特位全部置为0,其余位置为1即可。
[0122] 采用本发明所示实施例,其处理步骤如下:
[0123] (1)获得ID为0的员工的考勤信息,该员工的考勤正常,对应的比特位应该为1。记 录ID为0的员工的考勤信息时,先构建底层链表(二级结构)的上一级链表(一级结构), iBeginID的值为0,llFirstBitMap的初始值为 1010101010101010101010101010101010101010101010101010101010101010(此时尚没有员 工信息,全部比特位都认为是0,因此左边的比特位全部设置成1)。
[0124] ( 2 )构建底层链表,并将底层链表的指针指向构建的上一级链表中。 iSecondBitMap 的初始值为00000000000000000000000000000000。
[0125] (3)ID为0的员工考勤正常,将iSecondBitMap中的编号为0的比特位设置成1,此时 iSecondBitMap 的值为 10000000000000000000000000000000, iSecondBitMap 的值既不是全 1也不是全0,因此11卩化8七8汍]\^口值修改成00101010101010101010101010101010 10101010101010101010101010101010, ID 为 0 的员工考勤记录完毕。
[0126] (4)在本实施例中,一个底层链表能表示32个员工的考勤信息,一个上一级链表能 表示1024个员工的信息,因此需要2个上一级链表。
[0127] 可以采用上述公式,确定待存储数据对应的第一级链表至第x-1级链表:确定的所 述第一级链表至第x-1级链表的编号为:[(i%pi%P2%…%pj-i)/pj],1彡j彡x-1;确定的 第X级链表的编号为:[(i%pi%p 2% · · · %Pj. · · %px-0/px]。
[0128] 对于ID为0的员工来说,i = 0,对应的第二级链表的编号为:[i/Pl] = [0/32] =0;
[0129] 对应的第一级链表的编号为:[(i%Pl)/p2] = [ (0%32)/32] = [0/32] =0。
[0130] 在第二级链表的存储位置:
[0131 ] (i%p2)*〇2= (0%32)*2 = 0; (i%p2)*〇2+〇2-l = (0%32)*2+2_1 = 1,
[0132] 即编号为0和1的比特位用来存储ID为0的员工的考勤数据。
[0133] (5)第一个底层链表对应于llFirstBitMap中的编号为0和1的比特位, llFirstBitMap中编号为0和1的比特位的值为00,表示第一个底层链表的所有比特位既不 全为0也不全为1。
[0134] (6)获得ID为1的员工的考勤信息,该员工的考勤正常,对应的比特位应该为1。将 iSecondBitMap 的值修改为 11000000000000000000000000000000, iSecondBitMap 仍旧既不 全为0也不全为1,因此不用修改。
[0135] ID从2到30的员工的处理过程与ID为1的员工的处理过程相同,经过处理完这些员 工之后,iSecondBitMap 变为111 111 111 111 111 111 111 111 111 111 10。
[0136] (7)记录ID为31的员工的考勤,ID为31的员工仍对应编号为0的底层链表。将编号 为 31 的比特位置为 1,iSecondBitMap 的值变为11111111111111111111111111111111,可以 看到此时iSecondBitMap所有比特位已经全部成了 1,因此删除该底层链表,同时将 llFirstBitMap 值修改成 01101010101010101010101010101010101010101010101010101010 10101010。
[0137] (8)记录ID32-63员工的考勤信息,确定ID32-63员工对应的第二级链表的编号为: [i/ Pl] = [32/32] = 1;对应的第一级链表的编号为:[(i%Pl)/p2] = [(32%32)/32] = [l/ 32] =0。在编号为1的底层链表中记录ID32-63员工的考勤信息,其过程与记录ID0-31员工 的考勤信息相同,记录完ID32-63员工的考勤信息后,llFirstBitMap值修改成 0101101010101010101010101010101010101010101010101010101010101010ο
[0138] 为了简化描述,ID从32到99的员工的记录过程不再赘述,直接看第一个考勤异常 的员工的处理方法。记录完ID为99的员工后,llFirstBitMap值为 0101010010101010101010101010101010101010101010101010101010101010, iSecondBitMap 值为 11110000000000000000000000000000 〇
[0139] (9)确定ID为100的员工对应的第二级链表的编号为:[i/pl ] = [ 100/32] = 3;对应 的第一级链表的编号为:[(1^1)/^2] = [(100%32)/32] = [3/32]=0。在第二级链表的存 储位置:(1%口2)*〇2 = (100%32)*2 = 6;(1%口2)*〇2+〇2-1 = (100%32)*2+2-1 = 7。可知,10 为100的员工对应编号为3的底层链表,在编号为3的底层链表中,以编号为6和7的比特位用 来存储ID为100的员工的考勤数据。编号为3的底层链表中存储ID为100的员工的存储位置 处的位图信息本身为0,不需要进行任何操作。
[0140] (10)记录完ID为100的员工之后,继续记录后续员工,当记录完ID96-127的员工之 后,此时因为员工100对应的比特位是0,员工96、97、98等对应的比特位是1,因此该编号为3 的底层链表中包含的存储数据不全部相同,不删除该底层链表。记录完ID为127的员工后, llFirstBitMap 值为 010101001010101010101010101010101010101010101010101010101010 1010, iSecondBitMap 值为 11110111111111111111111111111111。
[0141] (11)后续员工的处理过程相同,此处不再赘述,最终,我们得到数据结构如图5所 示,存储数据全部相同的底层链表已被压缩,只显示了存储数据不全部相同的三个底层链 表。
[0142] 通过上述步骤可知,应用上述实施例,一共使用了两个上一级链表(一级结构)和 三个底层链表(二级结构)。在32位系统中,一个上一级链表的大小为(4+4+8+4) = 20BYTE, 一个底层链表的大小为(4+4) = 8BYTE,一共占用的内存为(2*20+3*8) = 64BYTE。相对于原 来的 256BYTE,节省了( 256-64) /256 = 75 % 的内存。
[0143] 作为本发明的另一种实施方式,上述方案还可以应用在BGP(Border Gateway Protocol,边界网关协议)中。在BGP应用中,需要记录每个BGP邻居是否发送过更新或者撤 销的信息,以避免重复发送。
[0144]假设需要记录1000个BGP邻居是否发送过更新或者撤销的信息,针对每个邻居,有 一个唯一的编号,1000个邻居的编号可以为0-999。与上述考勤数据类似,如果对于某条更 新或者撤销的信息,该邻居发送过,则该邻居的存储数据为1,如果没发送过,该邻居的存储 数据为0。
[0145] 假设编号为100、328和930的邻居没有发送过该信息,如果采用传统的方式来记 录,需要1000/8 = 125个BYTE的字符串来记录这一信息。在针对该信息的记录中,只需要将 这个字符串的编号为1〇〇、328、930的比特位全部置为0,其余位置为1即可。
[0146] 采用本发明所示实施例,应用图4中的数据结构,其处理步骤如下:
[0147] (1)获得编号为0的邻居的存储数据,该邻居发送过该信息,对应的比特位的值应 该为1。记录编号为〇的邻居的存储数据时,先构建底层链表(二级结构)的上一级链表(一级 结构),iBeginID 的值为 0,llFirstBitMap 的初始值为 10101010101010101010101010101010 10101010101010101010101010101010(此时尚没有存储数据,全部比特位都认为是0,因此 左边的比特位全部设置成1)。
[0148] ( 2 )构建底层链表,并将底层链表的指针指向构建的上一级链表中。 iSecondBitMap 的初始值为00000000000000000000000000000000。
[0149] (3)编号为0的邻居发送过该信息,将iSecondBitMap中的编号为0的比特位设置成 1,此时 iSecondBitMap 的值为 10000000000000000000000000000000, iSecondBitMap 的值既 不是全 1 也不是全0,因此llFirstBitMap值修改成00101010101010101010101010101010 10101010101010101010101010101010,编号为 0 的邻居记录完毕。
[0150] (4)在本实施例中,一个底层链表能表示32个邻居的存储数据,一个上一级链表能 表示1024个邻居的存储数据,因此需要1个上一级链表。
[0151] 可以采用上述公式,确定待存储数据对应的第一级链表至第x-1级链表:确定的所 述第一级链表至第x-1级链表的编号为:[(i%pi%P2%…%pj-i)/pj],1彡j彡x-1;确定的 第X级链表的编号为:[(i%pi%p 2% · · · %Pj. · · %px-0/px]。
[0152] 对于编号为0的邻居来说,i=0,对应的第二级链表的编号为:[i/Pl] = [0/32] = 〇;
[0153] 对应的第一级链表的编号为:[(i%Pl)/p2] = [(0%32)/32] = [0/32] =0。
[0154] 在第二级链表的存储位置:
[0155] (i%p2)*〇2= (0%32)*2 = 0; (i%p2)*〇2+〇2-l = (0%32)*2+2_1 = 1,
[0156] 即编号为0和1的比特位用来存储编号为0的邻居的存储数据。
[0157] (5)第一个底层链表对应于llFirstBitMap中的编号为0和1的比特位, llFirstBitMap中编号为0和1的比特位的值为00,表示第一个底层链表的所有比特位既不 全为0也不全为1。
[0158] (6)获得编号为1的邻居的存储数据,该邻居发送过该信息,对应的比特位应该为 1〇 将iSecondBitMap 的值修改为 11000000000000000000000000000000, iSecondBitMap 仍旧 既不全为〇也不全为1,因此不用修改。
[0159] 编号从2到30的邻居的处理过程与编号为1的员工的处理过程相同,经过处理完这 些员工之后,iSecondBitMap 变为11111111111111111111111111111110。
[0160] (7)记录编号为31的邻居的存储数据,编号为31的邻居仍对应编号为0的底层链 表。将编号为 31的比特位置为1,iSecondBitMap的值变为11111111111111111111111111111 111,可以看到此时iSecondBitMap所有比特位已经全部成了 1,因此删除该底层链表,同时 将 llFirstBitMap 值修改成 011010101010101010101010101010101010101010101010101010 1010101010。
[0161] (8)记录编号为32-63邻居的存储数据,确定编号为32-63的邻居对应的第二级链 表的编号为:[i/pi] = [32/32] = 1;对应的第一级链表的编号为:[(i%Pl)/p2] = [(32% 32)/32] = [1/32]=0。在编号为1的底层链表中记录编号为32-63的邻居的存储数据,其过 程与记录编号为32-63的邻居的存储数据相同,记录完编号为32-63的邻居的存储数据后, llFirstBitMap 值修改成 01011010101010101010101010101010101010101010101010101010 10101010。
[0162] 为了简化描述,编号从32到99的邻居的记录过程不再赘述,直接看第一个异常的 邻居的处理方法。记录完编号为99的邻居后,llFirstBitMap值为0101010010101010101010 101010101010101010101010101010101010101010,iSecondBitMap 值为 11110000000000000 000000000000000〇
[0163] (9)确定编号为100的邻居对应的第二级链表的编号为:[i/pl] = [100/32]=3;对 应的第一级链表的编号为:[(1%口1)/^] = [(100%32)/32] = [3/32]=0。在第二级链表的 存储位置:(i%P2)*〇2=(100%32)*2 = 6;(i%p2)*〇2+〇2-l = (100%32)*2+2-l = 7。可知,编 号为100的员工对应编号为3的底层链表,在编号为3的底层链表中,以编号为6和7的比特位 用来存储编号为100的邻居的存储数据。编号为3的底层链表中编号为100的邻居的存储位 置处的位图信息本身为0,不需要进行任何操作。
[0164] (10)记录完编号为100的邻居之后,继续记录后续邻居,当记录完编号96-127的邻 居之后,此时因为编号为100的邻居对应的比特位是0,编号为96、97、98等邻居对应的比特 位是1,因此该编号为3的底层链表中包含的存储数据不全部相同,不删除该底层链表。记录 完编号为 127 的邻居后,llFirstBitMap 值 010101001010101010101010101010101010101010 1010101010101010101010,iSecondBitMap 值为 11110111111111111111111111111111。
[0165] (11)后续邻居的处理过程相同,此处不再赘述,最终存储数据全部相同的底层链 表已被删除,只保留了存储数据不全部相同的三个底层链表(编号为编号为1〇〇、328和930 的邻居对应的底层链表)。
[0166] 通过上述步骤可知,应用上述实施例,一共使用了一个上一级链表(一级结构)和 三个底层链表(二级结构)。在32位系统中,一个上一级链表的大小为(4+4+8+4) = 20BYTE, 一个底层链表的大小为(4+4) = 8BYTE,一共占用的内存为(20+3*8) = 44BYTE。相对于原来 的 125BYTE,节省了(125-44)/125 = 64.8% 的内存。
[0167] 与上述的方法实施例相对应,本发明实施例还提供一种数据存储装置。
[0168] 图6为本发明实施例提供的一种数据存储装置的结构示意图,包括:
[0169] 获得确定模块201,用于获得待存储数据,并确定所述待存储数据对应的目标链表 以及所述待存储数据在所述目标链表的存储位置;
[0170]存储模块202,用于将所述待存储数据存储至所述存储位置;
[0171 ]删除更新模块203,用于在所述目标链表包含的所述数据全部相同时,删除所述目 标链表,并更新所述目标链表在上一级链表中的状态。
[0172]在本发明所示实施例中,获得确定模块201,还可以用于预设X级链表,所述X为大 于1的整数,设定所述目标链表为第X级链表;以及依次确定所述待存储数据对应的第一级 链表至第x-1级链表。
[0173] 在本发明所示实施例中,获得确定模块201,还可以用于确定的所述第一级链表至 第x-1级链表的编号为:[(i%pi%P2%…%pj-i)/pj],K j彡x-1;以及确定的第X级链表的 编号为:[(i%pi%P2% · · · %Pj. · · %Ρχ-ι)/ρχ];
[0174] 其中,所述i为待存储数据的编号,i为非负整数;
[0175]所述Pj为第j级链表对应的所述待存储数据的个数,pj=Wx*Wx-所述Wj为 预设的第j级链表存储的状态的个数,^ = ^/〇』,所述为预设的第j级链表的容量,单位为 比特,所述W为预设的第j+Ι级链表的状态在第j级链表中占用的比特位数;
[0176] 所述px为第X级链表存储的所述待存储数据的个数,口\ = ?^ = 7/〇\,所述7\为预设 的第X级链表的容量,单位为比特,所述〇x为预设的待存储数据在第X级链表中占用的比特 位数。
[0177] 在本发明所示实施例中,所述待存储数据在所述第X级链表的存储位置为一个比 特位组,所述比特位组包括:从编号为(i%px)* 〇x的比特位到编号为(i%px)*〇x+〇x-l的比特 位。
[0178] 在本发明所示实施例中,删除更新模块203,还可以用于在所述目标链表包含的所 述数据全部相同时,在所述上一级链表中将目标链表的状态更新为对应的第一预设值;以 及在所述目标链表包含的所述数据不全部相同时,在所述上一级链表中将目标链表的状态 更新为对应的第二预设值;
[0179]获得确定模块201,还可以用于确定所述目标链表不存在时,创建目标链表,并在 所述上一级链表中将目标链表的状态设置为对应的初始值。
[0180]在本发明所示实施例中,删除更新模块203,还可以用于当第j级链表包含的状态 全部相同时,删除所述第j级链表,并更新所述第j级链表在第j-i级链表中的状态。
[0181 ]应用本发明图6所示实施例,针对待存储数据,构建至少两级链表,该待存储数据 存储在底层链表中,在底层链表包含的存储数据全部相同时,删除该底层链表,并更新该底 层链表在上一级链表中的状态。一方面,将包含的存储数据全部相同的底层链表删除,节省 了内存空间的占用;另一方面,当数据量很大、构建了多个底层链表时,如果出现数据变化 的情况,仅需修改该数据对应的底层链表及该底层链表在上一级链表中的状态,不需要将 全部链表进行解压-修改-压缩的处理,提高了执行效率。
[0182] 需要说明的是,在本文中,诸如第一和第二等之类的关系术语仅仅用来将一个实 体或者操作与另一个实体或操作区分开来,而不一定要求或者暗示这些实体或操作之间存 在任何这种实际的关系或者顺序。而且,术语"包括"、"包含"或者其任何其他变体意在涵盖 非排他性的包含,从而使得包括一系列要素的过程、方法、物品或者设备不仅包括那些要 素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、物品或者设备 所固有的要素。在没有更多限制的情况下,由语句"包括一个……"限定的要素,并不排除在 包括所述要素的过程、方法、物品或者设备中还存在另外的相同要素。
[0183] 本说明书中的各个实施例均采用相关的方式描述,各个实施例之间相同相似的部 分互相参见即可,每个实施例重点说明的都是与其他实施例的不同之处。尤其,对于装置实 施例而言,由于其基本相似于方法实施例,所以描述的比较简单,相关之处参见方法实施例 的部分说明即可。
[0184] 本领域普通技术人员可以理解实现上述方法实施方式中的全部或部分步骤是可 以通过程序来指令相关的硬件来完成,所述的程序可以存储于计算机可读取存储介质中, 这里所称得的存储介质,如:ROM/RAM、磁碟、光盘等。
[0185]以上所述仅为本发明的较佳实施例而已,并非用于限定本发明的保护范围。凡在 本发明的精神和原则之内所作的任何修改、等同替换、改进等,均包含在本发明的保护范围 内。
【主权项】
1. 一种数据存储方法,其特征在于,包括: 获得待存储数据,并确定所述待存储数据对应的目标链表以及所述待存储数据在所述 目标链表的存储位置; 将所述待存储数据存储至所述存储位置; 在所述目标链表包含的所述数据全部相同时,删除所述目标链表,并更新所述目标链 表在上一级链表中的状态。2. 根据权利要求1所述的方法,其特征在于, 预设X级链表,所述X为大于1的整数,则所述确定的目标链表为第X级链表,确定的所述 存储位置为:在所述第X级链表的存储位置; 确定所述目标链表之前,该方法还包括:依次确定所述待存储数据对应的第一级链表 至第χ-1级链表。3. 根据权利要求2所述的方法,其特征在于, 确定的所述第一级链表至第χ-1级链表的编号为:[(i%pi%P2% . · · %pj-i)/pj],1彡j ^χ-1 ; 确定的第χ级链表的编号为:[(i%Pl%P2%…%ΡΓ··%Ρχ-ι)/ρχ]; 所述i为待存储数据的编号,i为非负整数; 所述Pj为第j级链表对应的所述待存储数据的个数,Pj =WX*WX-,所述Wj = yj/〇j, 所述n为预设的第j级链表的容量,单位为比特,所述~为预设的第j+1级链表的状态在第j 级链表中占用的比特位数; 所述Px为第X级链表存储的所述待存储数据的个数,px=wx = yx/ox,所述yx为预设的第X 级链表的容量,单位为比特,所述〇x为预设的待存储数据在第X级链表中占用的比特位数。4. 根据权利要求3所述的方法,其特征在于,所述待存储数据在所述第X级链表的存储 位置为一个比特位组,所述比特位组包括:从编号为(i%p x)*〇x的比特位到编号为(i%px)* 〇χ+〇χ-1的比特位。5. 根据权利要求4所述的方法,其特征在于, 在所述目标链表包含的所述数据全部相同时,所述更新所述目标链表在上一级链表中 的状态,包括:在所述目标链表包含的每个比特位组的值全部相同时,在所述上一级链表中 将目标链表的状态更新为对应的第一预设值; 确定所述目标链表不存在时,该方法还包括:创建目标链表,并在所述上一级链表中将 目标链表的状态设置为对应的初始值; 在所述目标链表包含的所述数据不全部相同时,该方法还包括:在所述上一级链表中 将目标链表的状态更新为对应的第二预设值。6. 根据权利要求3所述的方法,其特征在于,该方法还包括:当第j级链表包含的状态全 部相同时,删除所述第j级链表,并更新所述第j级链表在第j-Ι级链表中的状态。7. -种数据存储装置,其特征在于,包括: 获得确定模块,用于获得待存储数据,并确定所述待存储数据对应的目标链表以及所 述待存储数据在所述目标链表的存储位置; 存储模块,用于将所述待存储数据存储至所述存储位置; 删除更新模块,用于在所述目标链表包含的所述数据全部相同时,删除所述目标链表, 并更新所述目标链表在上一级链表中的状态。8. 根据权利要求7所述的装置,其特征在于, 所述获得确定模块,还用于预设X级链表,所述X为大于1的整数,设定所述目标链表为 第X级链表;以及依次确定所述待存储数据对应的第一级链表至第χ-1级链表。9. 根据权利要求8所述的装置,其特征在于, 所述获得确定模块,还用于确定的所述第一级链表至第χ-1级链表的编号为:[(i%ρι% P2% · · · %pj-i)/pj],1彡j彡χ-1;以及确定的第χ级链表的编号为:[(i %P1%P2% · · · % Pj---%Px-i)/px]; 其中,所述i为待存储数据的编号,i为非负整数; 所述Pj为第j级链表对应的所述待存储数据的个数,P j =WX*WX-,所述Wj = yj/〇j, 所述n为预设的第j级链表的容量,单位为比特,所述~为预设的第j+1级链表的状态在第j 级链表中占用的比特位数; 所述Px为第X级链表存储的所述待存储数据的个数,px=wx = yx/ox,所述yx为预设的第X 级链表的容量,单位为比特,所述〇x为预设的待存储数据在第X级链表中占用的比特位数。 10 .根据权利要求9所述的装置,其特征在于,所述待存储数据在所述第X级链表的存储 位置为一个比特位组,所述比特位组包括:从编号为(i%px)*〇x的比特位到编号为(i%p x)* 〇χ+〇χ-1的比特位。11. 根据权利要求10所述的装置,其特征在于, 所述删除更新模块,还用于在所述目标链表包含的所述数据全部相同时,在所述上一 级链表中将目标链表的状态更新为对应的第一预设值;以及在所述目标链表包含的所述数 据不全部相同时,在所述上一级链表中将目标链表的状态更新为对应的第二预设值; 所述获得确定模块,还用于确定所述目标链表不存在时,创建目标链表,并在所述上一 级链表中将目标链表的状态设置为对应的初始值。12. 根据权利要求9所述的装置,其特征在于, 所述删除更新模块,还用于当第j级链表包含的状态全部相同时,删除所述第j级链表, 并更新所述第j级链表在第j-Ι级链表中的状态。
【文档编号】G06F17/30GK106095788SQ201610367629
【公开日】2016年11月9日
【申请日】2016年5月27日
【发明人】余清炎
【申请人】杭州华三通信技术有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1