哈希表修复方法及装置与流程

文档序号:20018699发布日期:2020-02-25 11:08阅读:484来源:国知局
哈希表修复方法及装置与流程

本申请涉及数据存储技术领域,尤其涉及哈希表修复方法及装置。



背景技术:

元数据(metadata),又称中介数据、中继数据,为描述数据的数据(dataaboutdata),主要是描述数据属性(property)的信息,用来支持如指示存储位置、历史数据、资源查找、文件记录等功能。

当前,在存储设备中,元数据存储在共享内存中。存储设备以哈希表的形式管理各个存储着元数据的内存块的内存地址,以便于查找元数据。由于元数据的更改以及其他原因,存储设备的进程会修改哈希表。而修改哈希表的进程发生故障会导致哈希表的损坏。在哈希表损坏后,存储设备遍历所有存储着元数据的内存块,以修复哈希表。但是,由于存储着元数据的内存块数以亿计,即使采用并发的方式进行处理,存储设备仍然需要较长的时间才能修复哈希表。



技术实现要素:

本申请提供一种哈希表修复方法及装置,用于减少哈希表的修复时间。

为达到上述目的,本申请采用如下技术方案:

第一方面,提供一种哈希表修复方法,包括:在哈希表损坏后,从共享内存中恢复哈希表的结构,哈希表的结构包括哈希表的属性区,哈希表的属性区用于存储链表操作日志,链表操作日志包含哈希桶的标识;从哈希表的属性区获取链表操作日志;根据预设规则,修复目标双向链表,目标双向链表为在哈希表中根据哈希桶的标识确定的双向链表。

在存储设备中,进程修改哈希表,实际上是修改哈希表中的双向链表。因此,进程的故障实际上损坏的是哈希表中该进程正修改的双向链表。因此,在哈希表损坏后,存储设备从共享内存中恢复哈希表的结构,并从哈希表的属性区获取链表操作日志,从而根据链表操作日志包含的哈希桶的标识,确定哈希表中受进程故障而损坏的双向链表(也即目标双向链表)。从而,存储设备修复该目标双向链表,能够完成对哈希表的修复。由于在上述修复过程中,存储设备仅需要修复目标双向链表,因此存储设备至多需要遍历该目标双向链表相关的存储着元数据的内存块(也即目标双向链表的节点),而不需要遍历所有存储着元数据的内存块,从而减少哈希表的修复时间。

一种可能的设计中,上述根据预设规则,修复目标双向链表,包括:从目标双向链表的头节点开始,遍历目标双向链表中的每一个节点;检测节点的后继节点的前向指针域是否存储节点的内存地址;若节点的后继节点的前向指针域未存储节点的内存地址,则在节点的后继节点的前向指针域中存储节点的内存地址。这样一来,存储设备通过遍历一遍目标双向链表的所有节点,能够完成对目标双向链表的修复。

一种可能的设计中,链表操作日志还包含待操作节点的内存地址以及操作类型。上述根据预设规则,修复目标双向链表,包括:根据操作类型对应的规则,修复目标双向链表。这样一来,针对不同的操作类型,存储设备使用不同的规则,以实现对目标双向链表的精准修复。

一种可能的设计中,若操作类型为插入节点操作,则上述根据操作类型对应的规则,修复目标双向链表,包括以下步骤:s701-s710。

s701、检测待操作节点的后向指针域是否存储有内存地址;是,执行步骤s702。

s702、根据待操作节点的后向指针域存储的内存地址,确定待操作节点的后继节点。

s703、检测待操作节点的前向指针域是否存储有内存地址;否,执行步骤s704。

s704、检测待操作节点的后继节点的前向指针域存储的内存地址是否与待操作节点的内存地址相同;是,执行步骤s705和步骤s710;否,执行步骤s706-s710。

s705、从目标双向链表中查找到待操作节点的前驱节点。

s706、根据待操作节点的后继节点的前向指针域存储的内存地址,确定待操作节点的前驱节点。

s707、检测待操作节点的前驱节点的后向指针域存储的内存地址是否与待操作节点的内存地址相同;是,执行步骤s709-s710;否,执行步骤s708-s710。

s708、在待操作节点的前驱节点的后向指针域中存储待操作节点的内存地址。

s709、在待操作节点的后继节点的前向指针域中存储待操作节点的内存地址。

s710、在待操作节点的前向指针域中存储待操作节点的前驱节点的内存地址。

一种可能的设计中,若操作类型为删除节点操作,则上述根据操作类型对应的规则,修复目标双向链表,包括以下步骤:s801-s805。

s801、根据待操作节点的后向指针域存储的内存地址,确定待操作节点的后继节点。

s802、根据待操作节点的前向指针域存储的内存地址,确定待操作节点的前驱节点。

s803、检测待操作节点的前驱节点的后向指针域存储的内存地址是否与待操作节点的后继节点的内存地址相同;是,执行步骤s804。

s804、检测待操作节点的后继节点的前向指针域存储的内存地址是否与待操作节点的前驱节点的内存地址相同;否,执行步骤s805。

s805、在待操作节点的后继节点的前向指针域中存储待操作节点的前驱节点的内存地址。

一种可能的设计中,若操作类型为替换节点操作,则上述根据操作类型对应的规则,修复目标双向链表,包括以下步骤:s901-s910。

s901、检测待操作节点的后向指针域是否存储有内存地址;是,执行步骤s902。

s902、根据待操作节点的后向指针域存储的内存地址,确定待操作节点的后继节点。

s903、检测待操作节点的后继节点的前向指针域存储的内存地址是否与待操作节点的内存地址相同;否,执行步骤s904。

s904、根据待操作节点的后继节点的前向指针域存储的内存地址,确定被替换的节点。

s905、根据被替换的节点的前向指针域存储的内存地址,确定待操作节点的前驱节点。

s906、检测待操作节点的前驱节点的后向指针域存储的内存地址是否与待操作节点的内存地址相同;否,执行步骤s907;是,执行步骤s910。

s907、检测待操作节点的前向指针域是否存储有待操作节点的前驱节点的内存地址;否,执行步骤s908-s910;是,执行步骤s09-s910。

s908、在待操作节点的前向指针域中存储待操作节点的前驱节点的内存地址。

s909、在待操作节点的前驱节点的后向指针域中存储待操作节点的内存地址。

s910、在待操作节点的后继节点的前向指针域中存储待操作节点的内存地址。

一种可能的设计中,在哈希表损坏之前,方法还包括:获取操作指令,操作指令用于指示修改哈希表中的目标双向链表;根据操作指令,生成链表操作日志;根据操作指令对应的预设操作流程,修改目标双向链表。该预设操作流程用于使目标双向链表在修改过程中保持单向连通性。也即,该预设操作流程用于使目标双向链表在修改过程中不会断裂。这样一来,一方面,存储设备在修改哈希表前,按照操作指令,生成链表操作日志,以记录本次的操作,从而在哈希表损坏后,存储设备可以根据链表操作日志,修复哈希表。另一方面,存储设备在修改哈希表时,按照所述操作指令对应的预设操作流程,修改目标双向链表,避免进程的故障导致目标双向链表断裂,从而便于后续对目标双向链表的修复。

一种可能的设计中,若操作指令用于指示在目标双向链表的第一节点之后插入待操作节点,则上述根据操作指令对应的预设操作流程,修改目标双向链表,包括以下步骤:在待操作节点的后向指针域中存储第二节点的内存地址,第二节点为第一节点在目标双向链表中的后继节点;在第一节点的后向指针域中存储待操作节点的内存地址;在第二节点的前向指针域中存储待操作节点的内存地址;在待操作节点的前向指针域中存储第一节点的内存地址。

一种可能的设计中,若操作指令用于指示从目标双向链表中删除待操作节点,则上述根据操作指令对应的预设操作流程,修改目标双向链表,包括以下步骤:在第三节点的后向指针域中存储第四节点的内存地址;其中,第三节点为待操作节点在目标双向链表中的前驱节点;第四节点为待操作节点在目标双向链表中的后继节点;在第四节点的前向指针域中存储第三节点的内存地址。

一种可能的设计中,若操作指令用于指示以待操作节点替换目标双向链表中的第五节点,则上述根据操作指令对应的预设操作流程,修改目标双向链表,包括以下步骤:在待操作节点的后向指针域中存储第七节点的内存地址,第七节点为第五节点在目标双向链表中的后继节点;在待操作节点的前向指针域中存储第六节点的内存地址,第六节点为第五节点在目标双向链表中的前驱节点;在第六节点的后向指针域中存储待操作节点的内存地址;在第七节点的前向指针域中存储待操作节点的内存地址。

第二方面,提供一种存储设备,包括:处理模块,用于在哈希表损坏后,从共享内存中恢复哈希表的结构,哈希表的结构包括哈希表的属性区,哈希表的属性区用于存储链表操作日志,链表操作日志包含哈希桶的标识。获取模块,用于从哈希表的属性区获取链表操作日志。处理模块,还用于根据预设规则,修复目标双向链表,目标双向链表为在哈希表中根据哈希桶的标识确定的双向链表。

一种可能的设计中,处理模块,具体用于从目标双向链表的头节点开始,遍历目标双向链表中的每一个节点;检测节点的后继节点的前向指针域是否存储节点的内存地址;若节点的后继节点的前向指针域未存储节点的内存地址,则在节点的后继节点的前向指针域中存储节点的内存地址。

一种可能的设计中,链表操作日志还包含待操作节点的内存地址以及操作类型。处理模块,具体用于根据操作类型对应的规则,修复目标双向链表。

一种可能的设计中,若操作类型为插入节点操作,则处理模块,具体用于根据操作类型对应的规则,修复目标双向链表,包括以下步骤:s701-s710。

s701、检测待操作节点的后向指针域是否存储有内存地址;是,执行步骤s702。

s702、根据待操作节点的后向指针域存储的内存地址,确定待操作节点的后继节点。

s703、检测待操作节点的前向指针域是否存储有内存地址;否,执行步骤s704。

s704、检测待操作节点的后继节点的前向指针域存储的内存地址是否与待操作节点的内存地址相同;是,执行步骤s705和步骤s710;否,执行步骤s706-s710。

s705、从目标双向链表中查找到待操作节点的前驱节点。

s706、根据待操作节点的后继节点的前向指针域存储的内存地址,确定待操作节点的前驱节点。

s707、检测待操作节点的前驱节点的后向指针域存储的内存地址是否与待操作节点的内存地址相同;是,执行步骤s709-s710;否,执行步骤s708-s710。

s708、在待操作节点的前驱节点的后向指针域中存储待操作节点的内存地址。

s709、在待操作节点的后继节点的前向指针域中存储待操作节点的内存地址。

s710、在待操作节点的前向指针域中存储待操作节点的前驱节点的内存地址。

一种可能的设计中,若操作类型为删除节点操作,则处理模块,具体用于根据操作类型对应的规则,修复目标双向链表,包括以下步骤:s801-s805。

s801、根据待操作节点的后向指针域存储的内存地址,确定待操作节点的后继节点。

s802、根据待操作节点的前向指针域存储的内存地址,确定待操作节点的前驱节点。

s803、检测待操作节点的前驱节点的后向指针域存储的内存地址是否与待操作节点的后继节点的内存地址相同;是,执行步骤s804。

s804、检测待操作节点的后继节点的前向指针域存储的内存地址是否与待操作节点的前驱节点的内存地址相同;否,执行步骤s805。

s805、在待操作节点的后继节点的前向指针域中存储待操作节点的前驱节点的内存地址。

一种可能的设计中,若操作类型为替换节点操作,则处理模块,具体用于根据操作类型对应的规则,修复目标双向链表,包括以下步骤:s901-s910。

s901、检测待操作节点的后向指针域是否存储有内存地址;是,执行步骤s902。

s902、根据待操作节点的后向指针域存储的内存地址,确定待操作节点的后继节点。

s903、检测待操作节点的后继节点的前向指针域存储的内存地址是否与待操作节点的内存地址相同;否,执行步骤s904。

s904、根据待操作节点的后继节点的前向指针域存储的内存地址,确定被替换的节点。

s905、根据被替换的节点的前向指针域存储的内存地址,确定待操作节点的前驱节点。

s906、检测待操作节点的前驱节点的后向指针域存储的内存地址是否与待操作节点的内存地址相同;否,执行步骤s907;是,执行步骤s910。

s907、检测待操作节点的前向指针域是否存储有待操作节点的前驱节点的内存地址;否,执行步骤s908-s910;是,执行步骤s09-s910。

s908、在待操作节点的前向指针域中存储待操作节点的前驱节点的内存地址。

s909、在待操作节点的前驱节点的后向指针域中存储待操作节点的内存地址。

s910、在待操作节点的后继节点的前向指针域中存储待操作节点的内存地址。

一种可能的设计中,获取模块,还用于在哈希表损坏之前,获取操作指令,操作指令用于指示修改哈希表中的目标双向链表。处理模块,还用于根据操作指令,生成链表操作日志。处理模块,还用于根据操作指令对应的预设操作流程,修改目标双向链表。

一种可能的设计中,若操作指令用于指示在目标双向链表的第一节点之后插入待操作节点,则处理模块,用于根据操作指令对应的预设操作流程,修改目标双向链表,包括:在待操作节点的后向指针域中存储第二节点的内存地址,第二节点为第一节点在目标双向链表中的后继节点;在第一节点的后向指针域中存储待操作节点的内存地址;在第二节点的前向指针域中存储待操作节点的内存地址;在待操作节点的前向指针域中存储第一节点的内存地址。

一种可能的设计中,若操作指令用于指示从目标双向链表中删除待操作节点,则处理模块,用于根据操作指令对应的预设操作流程,修改目标双向链表,包括:在第三节点的后向指针域中存储第四节点的内存地址;其中,第三节点为待操作节点在目标双向链表中的前驱节点;第四节点为待操作节点在目标双向链表中的后继节点;在第四节点的前向指针域中存储第三节点的内存地址。

一种可能的设计中,若操作指令用于指示以待操作节点替换目标双向链表中的第五节点,则处理模块,用于根据操作指令对应的预设操作流程,修改目标双向链表,包括:在待操作节点的后向指针域中存储第七节点的内存地址,第七节点为第五节点在目标双向链表中的后继节点;在待操作节点的前向指针域中存储第六节点的内存地址,第六节点为第五节点在目标双向链表中的前驱节点;在第六节点的后向指针域中存储待操作节点的内存地址;在第七节点的前向指针域中存储待操作节点的内存地址。

第三方面,提供一种存储设备,包括:通信接口、处理器和存储器,该存储器用于存储计算机执行指令,当该存储设备运行时,该处理器执行该存储器存储的计算机执行指令,以使得存储设备执行上述第一方面中任一项所述的哈希表修复方法。

第四方面,提供一种计算机可读存储介质,该计算机可读存储介质中存储有指令,当其在计算机运行时,使得计算机可以执行上述第一方面中任一项所述的哈希表修复方法。

第五方面,提供一种包含指令的计算机程序产品,当其在计算机上运行时,使得计算机可以执行上述第一方面中任一项所述的哈希表修复方法。

第六方面,提供一种芯片系统,该芯片系统包括处理器,用于支持存储设备实现上述第一方面中任一项所述的哈希表修复方法的功能。在一种可能的设计中,该芯片系统还包括存储器,该存储器用于保存存储设备必要的程序指令和数据。该芯片系统可以由芯片构成,也可以包含芯片和其他分立器件。

其中,上述第二方面至第六方面中任一种设计方式所带来的技术效果可参见第一方面中不同设计方式所带来的技术效果,在此不再赘述。

附图说明

图1为一种双向链表的插入节点操作的示意图;

图2为本申请实施例提供的一种哈希表修改方法的流程图;

图3为本申请实施例提供的一种双向链表的插入节点操作的示意图;

图4为本申请实施例提供的一种双向链表的删除节点操作的示意图;

图5为本申请实施例提供的一种双向链表的替换节点操作的示意图;

图6为本申请实施例提供的一种哈希表修复方法的流程图;

图7为本申请实施例提供的一种目标双向链表的修复方法的流程图;

图8为本申请实施例提供的另一种目标双向链表的修复方法的流程图;

图9为本申请实施例提供的另一种目标双向链表的修复方法的流程图;

图10为本申请实施例提供的一种存储设备的结构示意图;

图11为本申请实施例提供的另一种存储设备的结构示意图。

具体实施方式

在介绍本申请实施例的技术方案之前,下面先对本申请实施例涉及的一些概念进行简单介绍。

1、哈希表

哈希表,又称为散列表,是根据关键值(keyvalue)而直接进行访问的数据结构。它通过一个关键值的函数(也称为散列函数)将所需的数据映射到表中的位置来访问数据。

但是,不同的关键值可能会映射到同一散列地址上,造成哈希冲突(也称为哈希碰撞)。为了解决哈希冲突,在本申请实施例中,哈希表采用开链法构造。具体的,哈希表包含多个哈希桶。每个哈希桶分别对应一个链表,该链表由映射到同一散列地址上的不同关键值构成。哈希桶存储着对应的链表的头节点的内存地址。

2、双向链表

双向链表是链表的一种。双向链表的每个节点都有两个指针域,分别是前向指针域和后向指针域。节点的前向指针域用于存储节点的前驱节点的内存地址。节点的后向指针域用于存储节点的后继节点的内存地址。

在本申请实施例中,所述双向链表为双向循环链表,也即该双向链表的头节点的前向指针域存储着尾节点的内存地址,尾节点的后向指针域存储着头节点的内存地址。在此统一说明,以下不再赘述。

在本申请实施例中,所述双向链表的节点为存储着元数据的内存块。在此统一说明,以下不再赘述。

本申请中的术语“第一”“第二”等仅是为了区分不同的对象,并不对其顺序进行限定。本申请中术语“和/或”,仅仅是一种描述关联对象的关联关系,表示可以存在三种关系,例如,a和/或b,可以表示:单独存在a,同时存在a和b,单独存在b这三种情况。另外,本申请中字符“/”,一般表示前后关联对象是一种“或”的关系。需要说明的是,本申请中,“示例性的”或者“例如”等词用于表示作例子、例证或说明。本申请中被描述为“示例性的”或者“例如”的任何实施例或设计方案不应被解释为比其他实施例或设计方案更优选或更具优势。确切而言,使用“示例性的”或者“例如”等词旨在以具体方式呈现相关概念。

在存储设备中,进程修改哈希表主要是指进程修改哈希表中的双向链表,包括:在双向链表中插入节点、从双向链表中删除节点以及用一个节点替换双向链表中的另一个节点。当前,进程修改双向链表的操作流程并不规范。不规范的操作流程因进程的故障而中断可能导致双向链表断裂,进而损坏哈希表。示例性的,如图1所示,为进程在双向节点1和节点2之间插入节点3的操作流程。该操作流程包括以下4个步骤:s101、在节点1的后向指针域中存储节点3的内存地址。s102、在节点3的前向指针域中存储节点1的内存地址。s103、在节点2的前向指针域中存储节点3的内存地址。s104、在节点3的后向指针域中存储节点2的内存地址。当进程按照上述操作流程修改双向链表时,若进程在执行步骤s101之后发生故障,导致整个操作流程中断,则由于节点3的后向指针域还未存储节点2的内存地址,节点2的前向指针域也未存储节点3的内存地址,导致双向链表在节点2和节点3之间发生断裂。

为了保证双向链表的修改过程中,双向链表不会断裂,如图2所示,为本申请实施例提供的一种哈希表的修改方法,该方法包括以下步骤:

s201、存储设备获取对哈希表的操作指令。

其中,所述操作指令用于指示修改哈希表中的目标双向链表。可选的,所述操作指令包含:目标双向链表对应的哈希桶的标识、待操作节点的内存地址以及操作类型。所述操作类型包含:插入节点操作、删除节点操作或者替换节点操作。

s202、存储设备根据所述操作指令,生成链表操作日志。

其中,链表操作日志用于记录存储设备对哈希表的操作。所述链表操作日志包含哈希桶的标识。可选的,所述链表操作日志还包含:待操作节点的内存地址以及操作类型。

在本申请实施例中,每次在存储设备在对哈希表进行操作之前,存储设备更新链表操作日志,以记录下接下来对哈希表的操作,以便于在哈希表损坏后,根据该链表操作日志,修复哈希表。

需要说明的是,存储设备将生成的链表操作日志存储于哈希表的属性区。其中,哈希表的属性区用于记录哈希表的属性,例如哈希表的名称等。

s203、存储设备根据所述操作指令对应的预设操作流程,修改哈希表中的目标双向链表。

其中,所述预设操作流程用于使哈希表中的目标双向链表在修改过程中保持单向连通性。所述单向连通性是指从目标双向链表的头节点能够遍历到目标双向链表的尾节点。也即,所述预设操作流程用于使目标双向链表在修改过程中不会断裂。

在本申请实施例,不同操作类型的操作指令对应不同的预设操作流程。下面以示例的方式对不同操作类型的操作指令对应的预设操作流程进行介绍。

一、若所述操作指令的操作类型为插入节点操作,具体的,所述操作指令用于指示在目标双向链表的第一节点之后插入待操作节点,则如图3所示,对应的预设操作流程包括以下步骤:s301-s304。

s301、在待操作节点的后向指针域中存储第二节点的内存地址,第二节点为第一节点在目标双向链表中的后继节点。

s302、在第一节点的后向指针域中存储待操作节点的内存地址。

s303、在第二节点的前向指针域中存储待操作节点的内存地址。

s304、在待操作节点的前向指针域中存储第一节点的内存地址。

基于上述预设操作流程,在进程对双向链表执行插入节点操作时,无论进程在何时故障,均不会导致该双向链表断裂。例如,进程在执行步骤s301之后、s302之前故障,由于第一节点的后向指针域依然还存储着第二节点的内存地址,双向链表未在第一节点和第二节点之间发生断裂。又例如,进程在执行步骤s302之后、步骤s303之前故障,由于第一节点的后向指针域存储着待操作节点的内存地址,待操作节点的后向指针域存储着第二节点的内存地址,因此双向链表并未在待操作节点和第二节点之间断裂,双向链表也未在第一节点和待操作节点之间断裂。

二、若所述操作指令的操作类型为删除节点操作,具体的,所述操作指令用于指示从目标双向链表中删除待操作节点,则如图4所示,对应的预设操作流程包括以下步骤:s401-s402。

s401、在第三节点的后向指针域中存储第四节点的内存地址。其中,所述第三节点为待操作节点在目标双向链表中的前驱节点。所述第四节点为待操作节点在目标双向链表中的后继节点。

s402、在第四节点的前向指针域中存储第三节点的内存地址。

基于上述预设操作流程,在进程对双向链表执行删除节点操作时,无论进程在何时故障,均不会导致该双向链表断裂。例如,在进程执行步骤s401之后、步骤s402之前故障,由于第三节点的后向指针域存储第四节点的内存地址,因此双向链表并未在第三节点和第四节点之间断裂。

三、若所述操作指令的操作类型为替换节点操作,具体的,所述操作指令用于指示以待操作节点替换目标双向链表中的第五节点,则如图5所示,对应的预设操作流程包括以下步骤:s501-s504。

s501、在待操作节点的后向指针域中存储第七节点的内存地址,所述第七节点为第五节点在双向链表中的后继节点。

s502、在待操作节点的前向指针域中存储第六节点的内存地址,所述第六节点为第五节点在双向链表中的前驱节点。

s503、在第六节点的后向指针域中存储待操作节点的内存地址。

s504、在第七节点的前向指针域中存储待操作节点的内存地址。

基于上述预设操作流程,在进程对双向链表执行替换节点操作时,无论进程在何时故障,均不会导致该双向链表断裂。例如,进程在执行步骤s501或者步骤s502之后故障,由于第五节点以及第六节点的后向指针域均未修改,也即第六节点的后向指针域还存储着第五节点的内存地址,第五节点的后向指针域还存储着第七节点的内存地址,因此双向链表并未在第六节点和第五节点之间断裂,双向链表也未在第五节点和第七节点之间断裂。

这样一来,一方面,存储设备在修改哈希表前,按照操作指令,生成链表操作日志,记录本次的操作,从而在哈希表损坏后,存储设备可以根据链表操作日志,修复哈希表。另一方面,存储设备在修改哈希表时,按照所述操作指令对应的预设操作流程,修改目标双向链表,避免进程的故障导致目标双向链表断裂,从而便于后续对目标双向链表的修复。

在图2所示的哈希表修改方法的基础上,如图6所示,为本申请实施例提供的一种哈希表修复方法。该方法包括以下步骤:

s601、存储设备在哈希表损坏之后,从共享内存中恢复哈希表的结构。

其中,所述哈希表的结构包括:哈希表的属性区以及哈希表包含的哈希桶。

一种可选的实现方式中,在修改哈希表的进程发生故障导致哈希表损坏后,存储设备重启发生故障的进程,并以共享内存中存储的数据,恢复哈希表的结构。

s602、存储设备从哈希表的属性区获取链表操作日志。

其中,所述链表操作日志包含哈希桶的标识。可选的,所述链表操作日志还包含:待操作节点的内存地址以及操作类型。

s603、存储设备按照预设规则,修复目标双向链表。

其中,所述目标双向链表为哈希表中所述哈希桶的标识对应的双向链表。

一种可选的实现方式中,当所述链表操作日志仅包含哈希桶的标识时,存储设备按照以下规则一,修复目标双向链表;当所述链表操作日志包含哈希桶的标识、待操作节点的内存地址以及操作类型时,存储设备按照以下规则一或者规则二,修复目标双向链表。

规则一、存储设备从目标双向链表的头节点开始,遍历目标双向链表中的每一个节点。检测节点的后继节点的前向指针域是否存储该节点的内存地址。若该节点的后继节点的前向指针域未存储所述节点的内存地址,则在该节点的后继节点的前向指针域中存储该节点的内存地址。

可选的,存储设备从目标双向链表的头节点开始,遍历目标双向链表中的每一个节点,包括:从目标双向链表的头节点开始,根据节点的后向指针域存储的内存地址,确定该节点的后继节点,直至尾节点。可以理解的是,在遍历双向链表的过程中,当双向链表中一个节点的后向指针域存储的内存地址为头节点的内存地址,可以确定该节点为尾节点。

在本申请实施例中,该节点的后继节点的前向指针域未存储所述节点的内存地址,是指该节点的后继节点的前向指针域存储的内存地址不是所述节点的内存地址。

结合图3对上述规则一进行示例性说明,例如,进程在执行步骤s302之后、步骤s303之前发生故障,则在修复目标双向链表的过程中,存储设备遍历目标双向链表的每一个节点,能够确定待操作节点以及第二节点的前向指针域存储的内存地址是错误的。因此,存储设备在待操作节点的前向指针域中存储第一节点的内存地址,在第二节点的前向指针域中存储待操作节点的内存地址,以修复目标双向链表。

结合图4对上述规则一进行示例性说明,例如,进程在执行步骤s401之后、步骤s402之前发生故障,则在修复目标双向链表的过程中,存储设备遍历目标双向链表的每一个节点,能够确定第四节点的前向指针域存储的内存地址是错误的。因此,存储设备在第四节点的前向指针域中存储第三节点的内存地址,以修复目标双向链表。

结合图5对上述规则一进行示例性说明,例如,进程在执行步骤s103之后、步骤s104之前发生故障,则在修复目标双向链表的过程中,存储设备遍历目标双向链表的每一个节点,能够确定第七节点的前向指针域存储的内存地址是错误的。因此,存储设备在第七节点的前向指针域中存储待操作节点的内存地址。

规则二、存储设备根据所述链表操作日志包含的操作类型对应的规则,修复目标双向链表。下面针对不同操作类型对应的规则进行具体介绍。

一、当所述操作类型为插入节点操作时,如图7所示,存储设备执行以下步骤s701-s710,以修复目标双向链表。

s701、检测待操作节点的后向指针域是否存储有内存地址。

结合图3进行说明,若待操作节点的后向指针域未存储内存地址,说明进程在执行步骤s301之前发生故障,因此,进程还未对目标双向链表中任一节点进行修改。在这种情况下,目标双向链表并未损坏,因此存储设备完成对目标双向链表的修复。若待操作节点的后向指针域存储内存地址,说明进程在执行步骤s301之后发生故障,则存储设备执行下述步骤s702。

s702、根据待操作节点的后向指针域存储的内存地址,确定待操作节点的后继节点。

s703、检测待操作节点的前向指针域是否存储有内存地址。

结合图3进行说明,若待操作节点的前向指针域存储有内存地址,说明进程在执行步骤s304之后发生故障,也即进程已完成对目标双向链表的修改。在这种情况下,目标双向链表不存在问题,因此存储设备完成对目标双向链表的修复。若待操作节点的前向指针域未存储内存地址,说明进程在执行步骤s301之后、步骤s304之前发生故障,则存储设备执行下述步骤s704。

s704、检测待操作节点的后继节点的前向指针域存储的内存地址是否与待操作节点的内存地址相同。

结合图3进行说明,若待操作节点的后继节点的前向指针域存储的内存地址与待操作节点的内存地址相同,则说明进程在执行步骤s303之后、步骤s304之前发生故障,因此存储设备执行下述步骤s705和s710。若待操作节点的后继节点的前向指针域存储的内存地址与待操作节点的内存地址不相同,则说明进程在执行步骤s301之后、步骤s303之前发生故障,存储设备执行下述步骤s706-s710。

s705、从目标双向链表中查找到所述待操作节点的前驱节点。

一种可选的实现方式,存储设备从目标双向链表的头节点开始,逐一查看目标双向链表中节点的后向指针域,直至查找到一个节点的后向指针域存储待操作节点的内存地址。这种情况下,存储设备可以确定该节点为待操作节点的前驱节点。

s706、根据待操作节点的后继节点的前向指针域存储的内存地址,确定待操作节点的前驱节点。

s707、检测待操作节点的前驱节点的后向指针域存储的内存地址是否与待操作节点的内存地址相同。

结合图3进行说明,若待操作节点的前驱节点的后向指针域存储的内存地址与待操作节点的内存地址相同,则说明进程在执行步骤s302之后、步骤s303之前发生故障,存储设备执行下述步骤s709-s710。若待操作节点的前驱节点的后向指针域存储的内存地址与待操作节点的内存地址不相同,则说明进程在执行步骤s301之后、步骤s302之前发生故障,因此存储设备执行下述步骤s708-s710。

s708、在待操作节点的前驱节点的后向指针域中存储待操作节点的内存地址。

s709、在待操作节点的后继节点的前向指针域中存储待操作节点的内存地址。

s710、在待操作节点的前向指针域中存储待操作节点的前驱节点的内存地址。

通过以上步骤s701-s710,存储设备能够修复被损坏的双向链表。

二、当所述链表操作日志包含的操作类型为删除节点操作时,如图8所示,存储设备执行以下步骤s801-s805,以修复目标双向链表。

s801、根据待操作节点的后向指针域存储的内存地址,确定待操作节点的后继节点。

s802、根据待操作节点的前向指针域存储的内存地址,确定待操作节点的前驱节点。

s803、检测待操作节点的前驱节点的后向指针域存储的内存地址是否与待操作节点的后继节点的内存地址相同。

结合图4进行说明,若待操作节点的前驱节点的后向指针域存储的内存地址与待操作节点的后继节点的内存地址不相同,则说明进程在执行步骤s401之前故障,在这种情况下,目标双向链表未损坏,因此存储设备完成对目标双向链表的修复。若待操作节点的前驱节点的后向指针域存储的内存地址与待操作节点的后继节点的内存地址相同,则存储设备执行下述步骤s804。

s804、检测待操作节点的后继节点的前向指针域存储的内存地址是否与待操作节点的前驱节点的内存地址相同。

结合图4进行说明,若待操作节点的后继节点的前向指针域存储的内存地址与待操作节点的前驱节点的内存地址相同,则说明进程在执行步骤s402之后发生故障。在这种情况下,进程已完成对目标双向链表的修改,目标双向链表不存在问题,因此存储设备完成对目标双向链表的修复。若待操作节点的后继节点的前向指针域存储的内存地址与待操作节点的前驱节点的内存地址不相同,则说明进程在执行步骤s401之后、步骤s402之前发生故障,因此存储设备执行下述步骤s805。

s805、在待操作节点的后继节点的前向指针域中存储待操作节点的前驱节点的内存地址。

通过以上步骤s801-s805,存储设备能够修复被损坏的双向链表。

三、当所述链表操作日志包含的操作类型为替换节点操作时,如图9所示,存储设备执行以下步骤s901-s910,以修复目标双向链表。

s901、检测待操作节点的后向指针域是否存储有内存地址。

结合图5进行说明,若待操作节点的后向指针域未存储内存地址,则说明进程在执行步骤s501之前发生故障。在这种情况下,进程还未修改目标双向链表,目标双向链表任保持完好,因此存储设备完成对目标双向链表的修复。若待操作节点的后向指针域存储有内存地址,则说明进程在执行步骤s501之后发生故障,因此存储设备执行下述步骤s902。

s902、根据待操作节点的后向指针域存储的内存地址,确定待操作节点的后继节点。

s903、检测待操作节点的后继节点的前向指针域存储的内存地址是否与待操作节点的内存地址相同。

结合图5进行说明,若待操作节点的后继节点的前向指针域存储的内存地址与待操作节点的内存地址相同,则说明进程在执行步骤s504之后发生故障。在这种情况下,进程已完成对目标双向链表的修改,目标双向链表不存在问题,因此存储设备完成对目标双向链表的修复。若待操作节点的后继节点的前向指针域存储的内存地址与待操作节点的内存地址不相同,则说明进程在执行步骤s501之后、步骤s504之前发生故障,因此存储设备执行下述步骤s904。

s904、根据待操作节点的后继节点的前向指针域存储的内存地址,确定被替换的节点。

s905、根据被替换的节点的前向指针域存储的内存地址,确定待操作节点的前驱节点。

s906、检测待操作节点的前驱节点的后向指针域存储的内存地址是否与待操作节点的内存地址相同。

结合图5进行说明,若待操作节点的前驱节点的后向指针域存储的内存地址与待操作节点的内存地址相同,则说明进程在执行步骤s503之后、步骤s504之前发生故障,因此存储设备执行下述步骤s910。若待操作节点的前驱节点的后向指针域存储的内存地址与待操作节点的内存地址不相同,则说明进程在执行步骤s501之后、步骤s503之前发生故障,因此存储设备执行下述步骤s907。

s907、检测待操作节点的前向指针域是否存储有待操作节点的前驱节点的内存地址。

结合图5进行说明,若待操作节点的前向指针域存储有待操作节点的前驱节点的内存地址,则说明进程在执行步骤s502之后、步骤s503之前发生故障,因此存储设备执行下述步骤s909-s910。若待操作节点的前向指针域未存储有待操作节点的前驱节点的内存地址,则说明进程在执行步骤s501之后、步骤s502之前发生故障,因此存储设备执行下述步骤s908-s910。

s908、在待操作节点的前向指针域中存储待操作节点的前驱节点的内存地址。

s909、在待操作节点的前驱节点的后向指针域中存储待操作节点的内存地址。

s910、在待操作节点的后继节点的前向指针域中存储待操作节点的内存地址。

通过以上步骤s901-s910,存储设备能够修复被损坏的双向链表。

基于上述技术方案,在哈希表损坏后,存储设备从共享内存中恢复哈希表的结构,并从哈希表的属性区获取链表操作日志,从而根据链表操作日志包含的哈希桶的标识,确定哈希表中受进程故障而损坏的双向链表(也即目标双向链表)。从而,存储设备修复该目标双向链表,能够完成对哈希表的修复。由于在上述修复过程中,存储设备仅需要修复目标双向链表,因此存储设备至多需要遍历该目标双向链表相关的存储着元数据的内存块(也即目标双向链表的节点),而不需要遍历所有存储着元数据的内存块,从而减少哈希表的修复时间。

上述主要从存储设备的角度对本申请实施例提供的方案进行了介绍。可以理解的是,上述存储设备为了实现上述功能,其包含了执行各个功能相应的硬件结构或软件模块。因此,结合本文中所公开的实施例描述的各示例的单元及算法步骤,本申请能够以硬件或硬件和计算机软件的结合形式来实现。其中,某个功能究竟以硬件还是计算机软件驱动硬件的方式来执行,取决于技术方案的特定应用和设计约束条件。本领域技术人员可以对每个特定的应用来使用不同方法来实现所描述的功能,但是这种实现不应认为超出本申请的范围。

比如,在采用各个功能划分功能模块的情况下,图10示出一种存储设备的结构示意图。该存储设备包括:处理模块1001和获取模块1002。其中,处理模块1001用于执行图2所示的步骤s202和s203,图3中的步骤s301-s304,图4中的步骤s401-s402,图5中的步骤s501-s504,图6中的步骤s601和s603,图7中的步骤s701-s710,图8中的步骤s801-s805,图9中的步骤s901-s910,和/或本申请实施例涉及的其他过程。获取模块1002用于执行图2所示的步骤s201,图6所示的步骤s602,和/或本申请实施例涉及的其他过程。

其中,上述方法实施例涉及的各步骤的所有相关内容均可以援引到对应功能模块的功能描述中,在此不再赘述。

在采用集成单元的情况下,图11示出一种存储设备的结构示意图。该存储设备1100包括至少一个处理器1101,存储器1102以及至少一个通信接口1103。其中,处理器1101可以实现图10中处理模块1001和获取模块1002的功能。

处理器1101可以是中央处理器(centralprocessingunit,cpu)。

通信接口1103,用于与其他设备或通信网络通信,如以太网,无线局域网(wirelesslocalareanetworks,wlan)等。

存储器1102例如是只读存储器(read-onlymemory,rom),随机存取存储器(randomaccessmemory,ram),电可擦可编程只读存储器(electricallyerasableprogrammableread-onlymemory,eeprom)、光盘、磁盘等。存储器1103可以独立存在,也可以和处理器1101集成在一起。

其中,存储器1102用于存储执行本申请方案的计算机可执行指令。处理器1101用于执行存储器1102中存储的计算机可执行指令,控制通信接口1103实现本申请下述实施例提供的网络接入控制方法。

处理器1101可以包括一个或多个cpu,例如图11中的cpu0和cpu1。存储设备1100可以包括多个处理器,例如图11中的处理器1101和处理器1106。这些处理器中的每一个可以是一个单核处理器,也可以是一个多核处理器。

存储设备1100还可以包括输出设备1104和输入设备1105。例如,输出设备1104可以是液晶显示器(liquidcrystaldisplay,lcd),阴极射线管(cathoderaytube,crt)显示器,或投影仪(projector)等。例如,输入设备1105可以是鼠标、键盘、触摸屏设备或传感设备等。

可选的,本申请实施例还提供一种计算机可读存储介质,所述计算机可读存储介质中存储有指令;当所述计算机可读存储介质在存储设备上运行时,使得存储设备执行图2至图9所示的方法。

可选的,本申请实施例还提供一种包含计算机指令的计算机程序产品,当其在计算机上运行时,使得计算机可以执行上述图2至图9所示的方法。

可选的,本申请实施例还提供一种芯片系统,该芯片系统包括处理器,用于支持存储设备执行图2至图9所示的方法。在一种可能的设计中,该芯片系统还包括存储器。该存储器,用于保存接收机必要的程序指令和数据。当然,存储器也可以不在芯片系统中。该芯片系统,可以由芯片构成,也可以包含芯片和其他分立器件,本申请实施例对此不作具体限定。

上述本申请实施例提供的存储设备、计算机存储介质以及计算机程序产品均用于执行上文所提供的对应的方法,因此,其所能达到的有益效果可参考上文所提供的对应的方法中的有益效果,在此不再赘述。

在上述实施例中,可以全部或部分地通过软件、硬件、固件或者其任意组合来实现。当使用软件程序实现时,可以全部或部分地以计算机程序产品的形式来实现。该计算机程序产品包括一个或多个计算机指令。在计算机上加载和执行计算机程序指令时,全部或部分地产生按照本申请实施例所述的流程或功能。所述计算机可以是通用计算机、专用计算机、计算机网络、或者其他可编程装置。所述计算机指令可以存储在计算机可读存储介质中,或者从一个计算机可读存储介质向另一个计算机可读存储介质传输,例如,所述计算机指令可以从一个网站站点、计算机、服务器或者数据中心通过有线(例如同轴电缆、光纤、数字用户线(digitalsubscriberline,dsl))或无线(例如红外、无线、微波等)方式向另一个网站站点、计算机、服务器或数据中心进行传输。所述计算机可读存储介质可以是计算机能够存取的任何可用介质或者是包含一个或多个可以用介质集成的服务器、数据中心等数据存储设备。所述可用介质可以是磁性介质(例如,软盘、硬盘、磁带),光介质(例如,dvd)、或者半导体介质(例如固态硬盘(solidstatedisk,ssd))等。

尽管在此结合各实施例对本申请进行了描述,然而,在实施所要求保护的本申请过程中,本领域技术人员通过查看所述附图、公开内容、以及所附权利要求书,可理解并实现所述公开实施例的其他变化。单个处理器或其他单元可以实现权利要求中列举的若干项功能。相互不同的从属权利要求中记载了某些措施,但这并不表示这些措施不能组合起来产生良好的效果。

当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1