用于支持分层数据对象的高效路径导航的与分层数据对象的二进制编码相关的技术的制作方法

文档序号:14203858阅读:203来源:国知局
用于支持分层数据对象的高效路径导航的与分层数据对象的二进制编码相关的技术的制作方法

实施例涉及信息检索技术,并且更具体而言涉及分层数据对象的高效存储和导航。



背景技术:

本节中描述的方法是可以追求的方法,但不一定是先前已经构想或追求的方法。因此,除非另有说明,否则不应当假定本节中描述的任何方法仅仅因为它们被纳入本节中就被当作现有技术。

诸如javascriptobjectnotation(json)文档之类的分层数据对象正在成为用于传输和存储数据的越来越流行的工具。然而,查询分层数据对象在计算上会是昂贵的,特别是当分层数据对象存储不断增加的数据量时。用于降低执行查询的算法复杂性的方法可以涉及分层数据对象的二进制编码。然而,这种方法可能引入管理中央字典或模式(schema)的开销和复杂性。另一种方法可以涉及压缩数据,以利用较小的存储器占用空间。然而,压缩方案通常要求在具体数据可以被访问之前解压所有数据。还有另一种方法可以涉及允许跳过与查询不相关的数据的树形结构化数据。然而,由于缺少孩子节点的可预测的次序,树形结构化数据可能仍然需要对任意给定级别处的所有孩子节点的线性扫描。因此,需要一种在时间和空间两方面有效地降低算法复杂性的全面的方法。

附图说明

在附图中:

图1绘出示例分层数据对象。

图2绘出用于紧凑地表示字段名称的示例字段。

图3绘出通过缩写的标识符引用字段名称的示例方法。

图4绘出节点的示例分层树。

图5绘出示例非叶子节点。

图6绘出示例叶子节点和示例字段值汇集(collection)。

图7是绘出用于编码分层数据对象以支持高效导航的方法的流程图。

图8是绘出用于对分层数据对象执行查询的方法的流程图。

图9绘出可以在其上实现实施例的计算机系统。

具体实施方式

在下面的描述中,出于解释的目的,阐述了许多具体细节,以提供对本公开的透彻理解。然而,将清楚的是,本公开可以在没有这些具体细节的情况下实践。在其它情况下,公知的结构和设备以框图形式示出,以避免不必要地模糊本公开。诸如“第一”、“第二”和“第三”之类的修饰词可以用于区分元素,但是修饰词不一定指示任何特定的次序。例如,第一映射可以这样命名,但实际上它可以是第二、第三和/或第四映射。为了清楚和容易理解,二进制数字可以在附图中和下面的示例中表示为十六进制数字。本公开假设大端(big-endian)平台,但是下面的描述可以容易地适用于小端平台。

一般概述

在实施例中,分层数据对象的高效存储和导航可以基于对能够跳过不相关的孩子节点的树节点结构进行编码来实现。每个父节点可以包括指示用于其每个孩子节点的字节偏移的第一映射。如果父节点具有各自与字段名称对应的一个或多个孩子节点,那么父节点还可以包括将字段名称映射到父节点的每个孩子节点的第二映射。因此,如果路径表达式包括特定的字段名称,那么可以在不扫描与路径表达式不相关的任何树节点的情况下识别与该特定字段名称对应的树节点。

可以基于字段名称标识符来实现分层数据对象的存储和导航中的进一步效率,该字段名称标识符数字地表示字段名称,以便使得能够在第二映射上针对特定字段名称执行二分搜索。当字段名称标识符是二进制数字时,可以实现甚至进一步的效率。可以使用第三映射来存储字段名称和字段名称标识符之间的关系。

导航分层数据对象的算法复杂性也可以通过整合重复的字段名称来降低。散列函数可以被用于向每个唯一的字段名称指派散列代码。基于存储散列代码与字段名称标识符之间的关系的第四映射,每个散列代码可以与第三映射中的字段名称相关联。

示例分层数据对象

图1绘出示例分层数据对象。在图1的示例中,分层数据对象100是json文档。然而,在实施例中,分层数据对象100可以是json文档内的json对象、二进制json(bson)文档、bson文档内的bson对象和/或数据的可串行化层次结构的任何其它实例。例如,在图1中,json对象可以用由大括号“{”和“}”括起来的数据表示。因此,json对象可以是图1中描述的人和/或位置。

分层数据对象100可以包括与字段值相关联的字段名称。在图1的示例中,字段名称包括“person”(“人”)、“id”(“身份”)、“birthdate”(“生日”)、“friends”(“朋友”)、“location”(“位置”)、“city”(“城市”)和“zip”(“邮政编码”)。对于json对象,字段名称可以在名称-值对中的冒号之前。在图1的示例中,字段值包括‘123’、‘john’、‘1970-01-02’、‘456’、‘mary’、‘1968-04-03’、‘789’、‘henry’、‘1972-03-03’、‘oakland’和‘94403’。对于json对象,字段值可以是除字段名称或者名称-值对中的冒号后面的分组符号之外的任何值。字段值可以包括空值、布尔值、字符串值、数字值、浮点值、双精度值、日期值、时间戳值、具有时区的时间戳值、年-月间隔、日-秒间隔、带符号的二进制整数和/或任何其它数据类型。每个字段名称可以与分层数据对象100中的一个或多个字段值相关联。例如,“person”可以与‘456’、‘mary’和‘1968-04-03’相关联。

示例根头部片段

为了启用对分层数据对象100的高效存储和导航,分层数据对象100可以以二进制表示进行编码,该二进制表示使得能够基于字节偏移进行跳过,并且通过消除重复的字段名称来减少数字存储器使用。在实施例中,二进制表示包括可以作为级联(concatenation)被存储和/或传输的多个片段。受限于存储器约束,可以针对该多个片段中的每个片段使用不同的懒惰加载策略将多个片段分别加载到数字存储器中。根头部片段可以是级联的第一片段。除此之外,根头部片段可以提供级联的后续片段的尺寸信息。

根头部片段的第一个字节可以被保留用于格式标识符。格式标识符可以识别特定的编码、文件格式和/或协议。例如,“0xff”可以指示级联采用使得能够高效导航分层数据对象100的二进制编码。

根头部片段的第二个字节可以被保留用于版本号。例如,“0x1”可以指示级联是使用使得能够高效导航分层数据对象100的二进制编码的“版本1”进行编码的。

根头部片段的下两个字节可以用作标志字段。每个位可以指示用于存储特定信息的字节数。例如,标志字段的第一位可以指示图2中描述的字段名称标识符在图5中描述的字段名称标识符到孩子的映射中是否被排序。因此,“10000000”可以指示字段名称标识符到孩子的映射是未排序的。

标志字段的第三位可以指示用于存储图6中所描述的字段值汇集的总尺寸的字节数。例如,翻转的位可以指示使用四个字节来存储字段值汇集的堆尺寸,而未翻转的位可以指示使用两个字节。

标志字段的第四位可以指示用于存储图4中描述的分层节点树的总尺寸的字节数。例如,翻转的位可以指示使用四个字节来存储分层节点树的堆尺寸,而未翻转的位可以指示使用两个字节。

标志字段的第五位可以指示用于存储图3中描述的字段名称汇集的总尺寸的字节数。例如,翻转的位可以指示使用四个字节来存储字段名称汇集的堆尺寸,而未翻转的位可以指示使用两个字节。

标志字段的第六位可以指示用于存储唯一字段名称的总数的字节数。例如,翻转的位可以指示使用两个字节来存储唯一字段名称的总数,而未翻转的位可以指示使用一个字节。

标志字段的第七位和第八位可以指示用于存储图2中所述的散列代码的字节数。例如,如果第七位被翻转,那么存储两个字节的散列代码。如果第八位被翻转,那么存储一个字节的散列代码。

取决于标志字段的第六位,根头部片段的下一个或两个字节可以存储唯一字段名称的总数。例如,如果第六位被设置为“1”,那么唯一字段名称的总数可以被存储为两字节的量。

取决于标志字段的第五位,根头部片段的下两个或四个字节可以存储字段名称汇集的总尺寸。例如,如果第五位被设置为“1”,那么字段名称汇集的堆尺寸可以被存储为四字节的量。

取决于标志字段的第四位,根头部片段的下两个或四个字节可以存储分层节点树的总尺寸。例如,如果第四位被设置为“1”,那么分层节点树的堆尺寸可以被存储为四字节的量。

取决于标志字段的第三位,根头部片段的下两个或四个字节可以存储字段值汇集的总尺寸。例如,如果第三位被设置为“1”,那么字段值汇集的堆尺寸可以被存储为四字节的量。

因此,对于图1中的分层数据对象100,根头部片段可以是“0xff01010008003300650047”。换句话说,级联使用二进制编码的“版本1”,使用一个字节的散列代码,具有八个唯一字段名称,使用五十一个字节的存储器来存储字段名称,使用101个字节的存储器来存储分层节点树,并使用七十一个字节的存储器来存储字段值。

用于紧凑表示字段名称的方法

分层数据对象100的高效存储和导航可以通过存储字段名称的紧凑表示来实现。紧凑表示可以消除重复的字段名称和/或通过缩写的标识符来引用每个字段名称。图2绘出用于图示紧凑表示字段名称的示例字段。参考图2,表200绘出字段名称标识符202、字段名称204和散列代码206之间的关系。基于表200中所绘出的关系生成散列代码映射208。

字段名称204包括分层数据对象100内的每个唯一字段名称。字段名称204中的每个字段名称被指派字段标识符202中的字段标识符。例如,字段名称标识符“0x1”被指派给“id”,并且字段名称标识符“0x2”被指派给“person”。

散列代码206中的每一个与字段名称204中的字段名称对应。通过将散列函数应用于字段名称204,生成散列代码206。如将被更详细地解释的,散列代码206被用于高效地执行字段名称标识符解析。字段名称标识符解析是指将字段名称标识符202解析为字段名称204和/或反过来的操作。

散列函数可以将字段名称204中的每一个作为输入,并且可以输出一个或多个散列代码206。例如,散列函数可以将“id”作为输入并输出十进制数“678385920”的32位二进制表示。

散列代码206中的每一个可以与字段名称标识符202中的一个对应。该对应关系可以基于散列代码206和字段名称标识符202的次序。散列代码206和字段名称标识符202在表200中依次示出。第一散列代码“0x286f5900”与第一字段名称标识符“0x1”对应,第二散列代码“0x30ace070”与第二字段名称标识符“0x2”对应,依此类推。字段名称标识符202和散列代码206之间的对应关系可以通过对散列代码206进行排序、然后将每个散列代码按排序次序映射到与排序次序对应的相应字段名称标识符来生成。

如稍后将更详细解释的,基于排序将散列代码206映射到字段名称标识符202使得能够高效地解析哪个字段名称标识符与特定的字段名称对应。

散列代码206的二进制表示可以按递增或递减次序排序。例如,由十进制数“1951507059”和“-1743783776”表示的散列代码206可以分别与二进制表示“01110100010100011010001001110011”和“10011000000011111111100010100000”对应。对于递增排序次序,“1951507059”将在“-1743783776”之前,因为正十进制数的二进制表示小于负十进制数的二进制表示。

当散列函数将不同的字段名称作为输入并输出相同的散列代码时,会发生冲突。然而,可以基于不同字段名称的相应长度和/或不同字段名称中每个字符的比较来解决冲突。长度信息和/或字符信息可以被存储在图3中描述的字段名称汇集中。例如,如果不同的字段名称“book”和“store”都与相同的散列代码对应,那么可以使用四个字节和五个字节的相应长度来区分不同的字段名称。在另一个示例中,如果不同的字段名称“book”和“idea”都与相同的散列代码对应,那么不同字段名称的相应长度可能不能解决冲突。因此,可以使用不同字段名称中每个字符字节的比较来区分“book”和“idea”。无论不同的字段名称如何被区别,相同的散列代码可以被指派给不同的字段名称标识符,以保持不同字段名称之间的区别。

特定的散列代码可以唯一地识别具有偶然冲突的特定字段名称。然而,特定散列代码的一部分可以唯一地识别特定字段名称,其中冲突数量的差异可以忽略不计。因此,特定散列代码的该部分可以被视为特定散列代码的等同物。特定散列代码的该部分可以是特定散列代码的相对独特的部分。在图2的示例中,特定散列代码的相对独特部分是最高有效字节。然而,在实施例中,特定散列代码的相对独特部分可以是最低有效字节。存储特定散列代码的该部分而不是存储整个特定散列代码可以降低存储需求和/或以其它方式减少计算开销。

散列代码映射208可以基于表200中所绘出的关系来生成。散列代码映射208可以是散列代码206的部分的序列,其中序列内的次序基于散列代码206的次序。在图2的示例中,“0x28”与“0x286f5900”的最高有效字节对应,“0x30”与“0x30ace070”的最高有效字节对应,依此类推。要注意的是,散列代码映射208的每个元素和散列代码206中的每个散列代码遵循字段名称标识符202的次序。换句话说,字段名称标识符202可以由散列代码映射208中散列代码206的序号位置来推断。因此,逻辑上暗示而不是物理地存储字段名称标识符202可以减少存储器使用。

在下文中,散列代码206可以指散列代码206的部分和/或散列代码206的整体。为了节省存储空间,使用特定散列代码的一部分作为特定散列代码的等同物,来代替特定散列代码。

用于字段名称标识符解析的方法

可以使用图2描述的映射以及图3中描述的数据结构来高效地执行字段名称标识符解析。根据实施例,可以通过散列代码映射208来减少用于字段名称标识符解析的存储需求和/或计算开销。

参考图3,字段名称204作为字段名称汇集300被连续地存储在存储器地址空间内。在图3的示例中,为了清楚起见,将字段名称204用引号封装起来。然而,在实施例中,一对引号之间的每个字符可以与字节对应。例如,“person”可以被存储为六个字节“0x706572736f6e”。此外,存储在字段名称汇集300中的字段名称204中的每一个可以与指示相应字段名称的长度的长度字节相邻。例如,“person”可以在“0x6”之后,使得字段名称汇集300的与“person”对应的一部分可以是七个字节“0x06706572736f6e”。可以使用长度字节而不是空字节,并且长度字节可以指示字段名称204之间的边界。要注意的是,使用单个字节来指示每个字段名称204的长度可以对每个字段名称204施加255字节的最大长度。然而,在实施例中,如果字段名称204中的至少一个长度超过255个字节,那么一个或多个附加字节可以扩充(augment)该单个字节。

字段名称映射302可以基于字段名称204的相应字段名称标识符202将字段名称204映射到字段名称汇集300内的偏移。该偏移可以是从字段名称汇集300的开头起计数的字节偏移。例如,在图3中,“0x0007”是字段名称映射302的第一个元素,其与字段名称标识符“0x1”和字段名称“id”对应。偏移“0x0007”引用字节数7,这是字段名称汇集300的与“id”对应的部分的相对偏移。

用于存储每个相对偏移的字节数可以基于字段名称汇集300的总长度来确定。在图3的示例中,每个相对偏移是两个字节,因为字段名称汇集300的总尺寸可以用两个字节或更少字节来表示。每个唯一字段名称可以被存储一次,以减少存储需求。字段名称204可以以通用字符集转换格式-8位(utf-8)编码和/或任何其它字符编码来存储。

字段名称映射302可以展示与散列代码映射208的一一对应关系。字段名称映射302和散列代码映射208一起可以提供散列代码206与用于由散列代码206表示的唯一字段名称的偏移信息之间的映射。在图2和图3的示例中,散列代码206与偏移信息之间的一一对应关系可以由字段名称标识符202来维护。例如,“0x28”和“0x0007”分别是散列代码映射208和字段名称映射302的第一个元素。因此,“0x28”和“0x0007”二者都与字段名称标识符“0x1”对应。在实施例中,在图4中描述的分层节点树中,使用字段名称标识符202来引用字段名称204。

用作为缩写的标识符的字段名称标识符202中的一个来替换字段名称204中的每一个可以导致实质性的空间节省。此外,如果每个字段名称标识符202是数字标识符,那么可以通过在图5中描述的字段名称标识符到孩子的映射上启用二分搜索,来减少针对字段名称标识符202以及(因此地)字段名称204的查找时间。

在实施例中,可以在导航图4中描述的分层节点树之前执行字段名称标识符解析。例如,查询可以包括路径表达式“$.person.location.city”。响应于该查询,数据源可以将散列函数应用于路径表达式中的每个字段名称204,以产生散列代码206的串行化,诸如“$.0x30.0x98.0x62”。基于散列代码映射208,散列代码206的串行化可以被转换成字段名称标识符202的串行化,诸如“$.0x2.0x5.0x3”。例如,可以针对散列代码206的串行化中的每个散列代码在散列代码映射208上执行二分搜索。在图2的示例中,散列代码映射208可以是散列代码206的阵列,其隐含地将字段名称标识符202存储为与阵列的元素对应的位置。因此,当散列代码位于散列代码映射208中时,散列代码的位置指示该散列代码的对应字段名称标识符。例如,“0x28”是图2中散列代码映射208的第一个元素。2,因此“0x28”与字段名称标识符“0x1”对应。

应用散列函数可以涉及基于散列代码映射208、字段名称映射302和/或字段名称汇集300来解决冲突。当在散列代码映射208上执行的二分搜索在散列代码映射208的多个位置中定位了特定散列代码时,这多个位置可以指示多个字段名称标识符202与该特定散列代码相关联。例如,如果“0x62”被定位于散列代码映射208中的第三位置和第四位置二者,那么将存在“city”是与字段名称标识符“0x3”还是字段名称标识符“0x4”对应的不明确性。可以使用字段名称映射302和/或字段名称汇集300来消除多个字段名称标识符202中的哪一个与特定散列代码对应的不明确性。例如,基于字段名称映射302,字段名称标识符“0x3”和字段名称标识符“0x4”分别与偏移“0x002a”和偏移“0x000f”对应。基于字段名称汇集300,偏移“0x002a”和偏移“0x000f”分别与“0x4’city”和“0x9’birthdate”对应。因此,基于长度字节“0x4”和/或“city”的字符串比较,可以确定散列代码“0x62”与字段名称标识符“0x3”对应。

节点的示例分层树

解析路径表达可以涉及导航分层数据对象100。分层数据对象100的加速导航可以通过将分层数据对象100组织为分层节点树400来实现。图4绘出节点的示例分层树。在图4的示例中,分层节点树400包括节点402-438。叶子节点包括节点406、408、416、418、412和428-438。非叶子节点包括节点402、404、410、414和420-426。

分层节点树400可以是以使数据之间的关系可以被图形地表示为树的方式来组织的数据的汇集。数据可以被组织到包括叶子节点和非叶子节点的节点中。树的每个级别可以与路径表达式的至少一部分对应。例如,路径表达式“$.person.friends[*]”可以指至少三个树级别。在图4的示例中,“person”可以与包括节点402的第一树级别对应,“friends”可以与包括节点404的第二树级别对应,并且至少开放的括号“[”可以与包括节点406-414的第三树级别对应。由节点420和422表示的子树可以与该路径表达式整体对应。

节点402-438可以作为分层节点树400被连续地存储在存储器地址空间内。节点之间的边界可以由图5中描述的头部数据维护。与叶子节点不同,非叶子节点可以具有一个或多个孩子节点。孩子节点可以直接与父节点相关。在图4的示例中,节点404是具有孩子节点406-414的非叶子节点。每个孩子节点可以是叶子节点或非叶子节点。非叶子节点可以是多种节点类型中的一种,诸如对象类型节点或数组类型节点。对象类型节点可以表示一个或多个字段名称204。在图4的示例中,节点402可以表示“person”,并且节点404可以表示“id”、“birthdate”、“location”、“name”和“friends”。数组类型节点可以引入一组对象类型节点。例如,节点414可以表示分层数据对象100中紧接在位于“friends”之后的冒号的开放括号“[”。

可以根据由路径表达式表示的查询来导航非叶子节点。路径表达式可以包括字段名称204的串行化。例如,路径表达式“$..friends[0].name”可以对应于对“friends”数组中第一个元素的名称的查询,其中该“friends”数组与任意的初始字段名称相关联。数据源(诸如数据库)可以接收该查询并将散列函数应用于路径表达式,以获得散列代码206的串行化,诸如“$..0xe4[0].0xa2”。应用散列函数可以涉及计算字段名称204的长度,以解决冲突。基于散列代码映射208,散列代码206的串行化可以被变换成字段名称标识符202的串行化,诸如“$..0x7[0].0x6”。基于图5中描述的孩子节点映射和字段名称标识符到孩子的映射,字段名称标识符202的串行化可以被变换成节点的序列,诸如“节点402.节点404.节点414.节点420.节点424.节点432”。

叶子节点可以表示与一个或多个字段名称204对应的字段值。因此,一个或多个叶子节点可以与路径表达式整体对应。在前面的示例中,节点432是表示字段值“mary”并且与路径表达式“$..friends[0].name”对应的叶子节点。在另一个示例中,节点432和节点438可以与路径表达式“$.person.friends[*].name”对应。

示例非叶子节点

图5绘出示例非叶子节点。在图5的示例中,节点404包括头部数据500、孩子节点的数量502、字段名称标识符到孩子的映射504以及孩子节点映射506。

头部数据500可以是指示关于分层节点树400的特定节点的信息的标志字段。在实施例中,头部数据500可以是在特定节点的开头处的单个字节。两个最高有效位可以指示节点类型。例如,“10”可以指示对象类型节点,“11”可以指示数组类型节点,并且“00”或“01”可以指示叶子节点类型。第三最高有效位可以指示用于在特定节点中存储偏移信息的字节数。例如,“1”可以指示每个偏移信息以四个字节被存储,并且“0”可以指示每个偏移信息以两个字节被存储。如果特定节点是对象类型节点或者数组类型节点,那么第四和第五最高有效位可以指示用于存储该特定节点的孩子节点的总数的字节数。例如,“00”、“01”和“10”可以指示孩子节点的总数分别以一个、两个和四个字节被存储。在图5的示例中,头部数据500是“10000000”,其可以指示节点404是对象类型节点,节点404以两个字节存储偏移信息,并且孩子节点的总数以一个字节被存储。

孩子节点的数量502可以指示特定非叶子节点的孩子节点的总数。在图5的示例中,如“0x5”所指示的,节点404具有五个孩子节点。在特定非叶子节点中存储的一个或多个映射中提供关于特定非叶子节点的孩子节点的进一步信息。

如果特定非叶子节点是对象类型节点,那么该特定非叶子节点可以包括字段名称标识符到孩子的映射504。字段名称标识符到孩子的映射504可以作为一个或多个字段名称标识符202与特定非叶子节点的一个或多个孩子节点之间的映射被存储在该特定非叶子节点中。在图5的示例中,字段名称标识符到孩子的映射504可以是将字段名称标识符202存储为元素的数组。数组中的每个位置可以与特定的孩子节点对应。例如,在图5中,字段名称标识符到孩子的映射504中的第一个元素是字段名称标识符“0x1”,并且字段名称标识符到孩子的映射504中的第一个位置与节点406对应。因此“0x1”与节点406对应。

在将字段名称标识符202存储在字段名称标识符到孩子的映射504中之前对字段名称标识符202进行排序使得能够在字段名称标识符到孩子的映射504上执行对于特定的字段名称标识符的二分搜索。例如,如果字段名称“id”是正被解析的路径表达式的一部分,那么“id”可以与字段名称标识符“0x1”相关联。在实施例中,散列函数可以将字段名称“id”与散列代码“0x28”相关联,然后该散列代码与字段名称标识符“0x1”相关联。散列代码可以在路径编译期间预先计算。如果与散列代码相关联的字段名称标识符不存在于存储器高速缓存中,那么可以基于散列代码映射208的二分搜索来获得字段名称标识符。字段名称映射302和字段名称汇集300可以用于检查冲突。存储器高速缓存可以存储字段名称标识符“0x1”与字段名称“id”之间的关联。在字段名称标识符到孩子的映射504上针对“0x1”执行的二分搜索可以比较“0x1”与“0x5”,其中“0x5”被确定为字段名称标识符到孩子的映射504的中点。由于“0x1”小于“0x5”,因此二分搜索可以在字段名称标识符到孩子的映射504的前半部分继续。二分搜索可以重复地将字段名称标识符到孩子的映射504划分为相继的一半,直到二分搜索定位与节点406对应的第一位置中的“0x1”。

孩子节点映射506可以被存储在特定非叶子节点中,作为树偏移信息与该特定非叶子节点的一个或多个孩子节点之间的映射。该特定非叶子节点可以是对象类型节点或数组类型节点。

树偏移信息可以是分层节点树400中的相对偏移。该相对偏移可以是从分层节点树400的开头起计数的字节偏移。在图5的示例中,孩子节点映射506可以是将树偏移信息存储为元素的数组。数组中的每个位置可以与特定的孩子节点对应。例如,在图5中,“0x0016”是孩子节点映射506中的第一个元素,并且孩子节点映射506中的第一个位置与节点406对应。因此,节点406可以被定位在分层节点树400中的相对偏移“0x0016”处。

对于图1中的分层数据对象100,下表提供分层节点树400中的每个节点的树偏移信息。“节点”列可以绘出作为节点的数组被连续地存储在存储器地址空间内的分层节点树400。

孩子节点映射506可以展示与字段名称标识符到孩子的映射504的一一对应关系。孩子节点映射506和字段名称标识符到孩子的映射504一起可以提供字段名称标识符202与孩子节点的树偏移信息之间的映射。在图5的示例中,字段名称标识符202与树偏移信息之间的一一对应关系可以由各自与孩子节点对应的位置来维护。例如,“0x1”和“0x0016”分别是字段名称标识符到孩子的映射504和孩子节点映射506的第一个元素。因此,“0x1”和“0x0016”二者都与孩子节点(即,节点406)对应。

树偏移信息可以使得能够直接“跳转”到与该树偏移信息对应的特定子节点。在实施例中,可以以常量时间o(1)执行直接“跳转”。因此,解析路径表达式可以与在对象类型节点的字段名称标识符到孩子的映射上执行二分搜索以寻找特定字段名称标识符一样慢。要注意的是,数组类型节点可以与字段名称标识符202无关,并且可以简单地基于路径表达式中指示的数组元素编号来提供树偏移信息。

示例叶子节点和示例字段值汇集

图6绘出示例叶子节点和示例字段值汇集。在图6的示例中,节点408包括头部数据500和字段值位置600。字段值位置600可以与字段值汇集602的一部分对应。

用于叶子节点的头部数据500可以在最后五位中不同于用于非叶子节点的头部数据500。对于叶子节点,最后五位可以指示数据类型。例如,“00000”、“00001”和“00010”可以分别指示空值、布尔真值和布尔假值。“00011”、“00100”和“00101”可以分别指示具有让字符串值以一个、两个和四个字节被存储的长度信息的字符串值。“00110”可以指示具有让数字值以一个字节被存储的长度信息的数字值。“00111”和“01000”可以分别指示浮点值和双精度值。“01001”、“01010”和“01011”可以分别指示日期值、时间戳值和具有时区的时间戳值。“01100”和“01101”可以分别指示年-月间隔和天-秒间隔。“01110”、“01111”和“10000”可以分别指示长度为2个、4个和8个字节的大端带符号二进制整数。在图6的示例中,节点408具有头部数据500“01001001”,其可以指示节点408是叶子节点、节点408以两个字节存储偏移信息、并且字段值位置600引用日期值。

字段值位置600可以是字段值汇集602中的相对偏移。该相对偏移可以是从字段值汇集602的开头起计数的字节偏移。相对偏移可以是引用字段值汇集602的与特定字段值对应的一部分的指针。在实施例中,用于存储相对偏移的字节数可以取决于相对偏移在字段值汇集602中指向哪里而变化。例如,如果字段值汇集602的总尺寸超过65535个字节,那么指向字段值汇集602的前65535个字节内的相对偏移可以各自以两个字节被存储,并且指向前65535个字节之外的相对偏移可以各自以四个字节被存储。

在图6的示例中,“0x0004”是引用字段值汇集602中的第四个字节的字段值位置600。该第四个字节与字段值汇集602中对应于字段值“1970-01-02”的一部分的起始字节对应。在实施例中,叶子节点可以包括至多一个字段值位置600。例如,某些数据类型的值(诸如空值、布尔真值和布尔假值)可以固有地被编码在头部数据500中。因此,将某些数据类型的值存储在字段值汇集602中可能是不必要的,由此使得对应的字段值位置是不必要的。

字段值可以作为字段值汇集602被连续地存储在存储器地址空间内。每个唯一字段值可以被存储一次,以减少存储需求。字段值可以以utf-8编码和/或任何其它字符编码来存储。附加地或替代地,字段值可以以表示整数的编码二进制值、二进制浮点数、十进制数、日期/时间值和/或其它数据类型来存储。字段值可以展现固定长度和/或可变长度。展现出可变长度的字段值可以与指示对应字段值的长度的长度字节相邻地存储。例如,“mary”可以是展现可变长度的字符串值,因此“mary”可以被存储在长度字节“0x4”之后。因此,字段值汇集602的与“mary”对应的一部分可以是五个字节“0x044d617279”。长度字节可以指示用于对应字段值的边界。

字段值汇集602可以是包括根头部片段、散列代码映射208、字段名称映射302、字段名称汇集300和/或分层节点树400的级联中的最后一个片段。字段值汇集602可以在分层节点树400之后,以便在字段值汇集602生长的情况下避免分层节点树400的移位。

用于对分层数据对象进行编码的方法

图7是绘出用于对分层数据对象进行编码以支持高效导航的方法的流程图。在框700处,生成多个散列代码206。多个散列代码206中的每个散列代码可以对应于与分层数据对象100中的一个或多个字段值相关联的相应字段名称。可以基于标准散列函数来生成每个散列代码。

在框702处,生成散列代码映射208。散列代码映射208可以将多个散列代码206中的每个散列代码映射到多个字段名称标识符202中的相应字段名称标识符。在实施例中,散列代码映射208可以存储每个散列代码的相对独特部分,以减少存储需求。

在框704处,生成字段名称映射302。字段名称映射302可以将每个字段名称映射到多个字段名称标识符202中的相应字段名称标识符。附加地或替代地,字段名称映射302可以将用于每个字段名称的偏移信息映射到相应的字段名称标识符。用于特定字段名称的偏移信息可以是指向字段名称汇集300中与特定字段名称对应的一部分的指针。

在框706处,生成分层节点树400。分层节点树400可以包括叶子节点和非叶子节点。特定非叶子节点可以包括孩子节点映射506,其将该特定非叶子节点映射到该特定非叶子节点的一个或多个孩子节点。例如,孩子节点映射506中的每个位置可以与存储孩子节点映射506的特定非叶子节点的相应孩子节点对应,由此将该特定非叶子节点映射到相应的孩子节点。此外,特定非叶子节点可以包括字段名称标识符到孩子的映射504,其将多个字段名称标识符202中的相应字段名称标识符映射到该特定非叶子节点的一个或多个孩子节点中的每一个孩子节点。例如,字段名称标识符到孩子的映射504中的每个位置可以与相应的孩子节点对应,并且字段名称标识符到孩子的映射504中的每个位置可以存储相应的字段名称标识符。

在框708处,散列代码映射208、字段名称映射302以及用于特定非叶子节点的孩子节点映射506和字段名称标识符到孩子的映射504被存储在表示分层数据对象100的记录中。例如,散列代码映射208、字段名称映射302、孩子节点映射506和字段名称标识符到孩子的映射504可以被存储在级联中,该级联还可以包括根头部片段、字段名称汇集300、分层节点树400和/或字段值汇集602。可以将该级联存储在数据库的二进制大对象(blob)字段、平面文件和/或经由标准块设备接口可访问(例如,打开、关闭、搜寻、读取、写入)的任何其它字节序列中。附加地或替代地,级联可以作为标准网络协议(诸如超文本传输协议(http))的一部分被传输。

示例路径表达式

可以响应于查询来导航分层数据对象。查询可以包括路径表达式。路径表达式可以包括由分隔符(诸如“.”或“/”)分隔的“路径步骤”的序列。路径步骤可以与分层数据对象100中的一个或多个字段名称对应。路径步骤的序列可以与分层数据对象100中的一个或多个字段值对应。

例如,“$.person.name”可以是应用在图1中的分层数据对象100上的路径表达式。“$”指定路径表达式的上下文,其缺省地是路径表达式正在其上被解析的分层数据对象100。路径步骤“person”指定与字段名称“person”相关联的父节点。路径步骤“name”指定与字段名称“name”相关联的孩子节点。在图1的示例中,基于使用路径步骤来导航分层数据对象100,路径表达式可以被解析为字段值“john”。

路径表达式还可以指定用于路径步骤的谓词或标准。例如,“$.person.friends[*].birthdate>to_date('1970-01-01','yyyy-mm-dd')”可以是包括谓词的路径表达式,其中该谓词指定大于日期值“1970-01-01”的一个或多个字段值。在图1的示例中,路径表达式可以被解析为字段值“1972-03-03”。

用于在分层数据对象上执行查询的方法

图8是绘出用于在分层数据对象上执行查询的方法的流程图。在框800处,生成步骤-散列代码的序列。步骤-散列代码可以是与路径表达式中的路径步骤对应的散列代码206中的一个。可以基于将散列函数应用于路径表达式中的每个不同字段名称来生成步骤-散列代码的序列。例如,路径表达式“$..friends[*].id”可以被变换成步骤-散列代码的序列“$..0xe4[*].0x28”。

在框802处,将步骤-散列代码的序列变换成步骤-字段名称标识符的序列。步骤-字段名称标识符可以是与路径表达式中的路径步骤对应的字段名称标识符202中的一个。可以基于用于分层数据对象100的散列代码映射208将步骤-散列代码的序列变换成步骤-字段名称标识符的序列。可以在散列代码映射208上执行对特定的步骤-散列代码的二分搜索,以便找到对应的步骤-字段名称标识符。例如,图2中的散列代码映射208指示步骤-散列代码“0xe4”是第七个元素,其与步骤-字段名称标识符“0x7”对应,并且步骤-散列代码“0x28”是第一个元素,其与步骤-字段名称标识符“0x1”对应。因此,步骤-散列代码的序列“$..0xe4[*].0x28”被变换成步骤-字段名称标识符的序列“$..0x7[*].0x1”。

在框804处,基于步骤-字段名称标识符的序列来导航用于分层数据对象100的分层节点树400。例如,步骤-字段名称标识符的序列“$..0x7[*].x1”指示分层节点树400的任何节点可以是起始节点。在图4的示例中,节点402是唯一可能的选择,但是如果存在多个根节点,那么导航可以从每个根节点继续进行。导航可以从多个根节点中的特定根节点继续进行,直到确定进一步导航该特定根节点对于解析路径表达式是不必要的。这种确定可以基于不存在作为根节点的后代并且与路径表达式的特定路径步骤对应的特定节点。

导航分层节点树400可以涉及基于当前节点的字段名称标识符到孩子的映射504来确定一个或多个直接后续节点(例如,孩子节点)。例如,可以针对步骤-字段名称标识符“0x7”来搜索节点404的字段名称标识符到孩子的映射504。搜索特定的步骤-字段名称标识符可以涉及在字段名称标识符到孩子的映射504上执行二分搜索。在图5的示例中,步骤-字段名称标识符“0x7”被识别为字段名称标识符到孩子的映射504的最后一个元素。基于孩子节点映射506,字段名称标识符到孩子的映射504的最后一个元素子与偏移“0x002d”对应,该偏移指代用于节点414的存储器位置。

在框806处,确定是否已经找到分层节点树400的叶子节点。如果已找到叶子节点,那么框806前进到框808。否则,框806前进到框804以进一步导航。例如,节点414不是图4中的叶子节点,因此导航沿着节点420和节点424继续,直到找到作为叶子节点的节点428。

在框808处,确定与叶子节点对应的字段值。确定用于特定叶子节点的对应字段值可以基于该特定叶子节点的字段值位置600。例如,节点428的字段值位置600可以指示偏移“0x20”,该偏移与图6中的字段值汇集602的字节编号32对应。这个偏移与字段值“456”相关联。

在框810处,字段值被包括在用于路径表达式的解集中。如果多于一个的解是可能的,那么框810可以前进到框804以进一步导航。否则,解集可以作为查询结果被返回。例如,字段值“456”可以被包括在用于路径表达式“$..friends[*].id”的解集中。然而,路径表达式中的通配符符号指示多于一个解是可能的,因此通过沿着节点402、节点404、节点414、节点422、节点426和节点434导航找到第二个解“789”。当确定没有其它解是可能的时,可以响应于查询而返回解集“{456,789}”。

示例存储器中(in-memory)优化

在以上描述中,散列代码映射208、字段名称映射302、字段名称汇集300、分层节点树400、字段名称标识符到孩子的映射504、孩子节点映射506和/或字段值汇集602被描述为堆的一个或多个部分、一个或多个存储器块,和/或一个或多个可运输并用于生成一个或多个存储器中表示的数据结构。因此,紧凑表示可以使得能够进行高速缓存和/或预加载存储器高速缓存以进一步优化。例如,取决于分层数据对象100的总尺寸,可以使用用于对分层节点树400进行懒惰加载的不同策略。对于小到中等尺寸的分层数据对象100,分层节点树400整体可以被预加载到存储器中。对于大的分层数据对象100,可以在“根据需要”的基础上将分层节点树400的一个或多个部分加载到存储器中。

然而,在存储器中优化中,可以牺牲可运输性来生成一个或多个存储器中数据流,这些存储器中数据流包括散列代码映射208、字段名称映射302、字段名称汇集300、分层节点树400、字段名称标识符到孩子的映射504、孩子节点映射506和/或字段值汇集602。可以使用实际的存储器地址来代替偏移,以确保平台无关性。

涉及多个分层数据对象的示例优化

当在多个分层数据对象上执行查询时,高效查询处理可以基于针对多个分层数据对象中的每一个减少重复计算。在实施例中,重复计算可以包括重新计算步骤-散列代码。例如,当在多个分层数据对象上应用路径表达式时,可以基于预先计算步骤-散列代码使得为多个分层数据对象中的每个分层数据对象100重新计算步骤-散列代码变得不必要。预先计算步骤-散列代码可以涉及在用于路径表达式的运行时之前(例如,在编译时期间)为路径表达式中的不同的字段名称计算步骤-散列代码。因此,可以为多个分层数据对象中的每一个同时地生成表示路径表达式的步骤-散列代码的序列。

同质(homogeneous)分层数据对象可以是共享结构的分层数据对象。例如,多个同质分层数据对象中的每一个可以表示人、共享相同的数据类型,和/或表示相同种类的对象。因此,散列代码映射208、字段名称映射302和/或字段名称汇集300可以对于多个同质分层数据对象中的每一个是相似的(如果不相同的话)。

在实施例中,可以利用同质分层数据对象的相似性,以基于减少重复计算来支持高效的查询处理。例如,可以避免为第一分层数据对象计算一个或多个步骤-散列代码和/或一个或多个步骤-字段名称标识符。这可以基于共享第二分层数据对象的字段名称映射302来完成。换句话说,当在第一分层数据对象上解析路径表达式时,可以基于检查第二分层数据对象的字段名称映射302而将路径表达式的一个或多个路径步骤直接变换成字段名称标识符的序列。可以检查字段名称映射302以获得一个或多个步骤-字段名称标识符,其中,当之前在第二分层数据对象上解析路径表达式或不同的路径表达式时已经为一个或多个路径步骤计算出该一个或多个步骤-字段名称标识符。例如,可以对一个或多个步骤-字段名称标识符与一个或多个路径步骤之间的映射进行高速缓存。如果一个或多个步骤-字段名称标识符引用字段名称汇集300中的与一个或多个路径步骤对应的一个或多个字段名称204,那么可以确定这一个或多个步骤-字段名称标识符与这一个或多个路径步骤对应。

示例的面向集合的优化

与单个分层数据对象100一样,分层数据对象的集合可以在被持久化到盘和/或作为存储器中辅助结构被加载之前以上面提到的方式被编码。然而,对于在线分析处理(olap)数据仓库应用,基于集合的编码可以展现出更好的压缩性并可以支持向量化的查询处理。同质分层数据对象常常被存储为分层数据对象的集合。因此,一些字段名称和/或字段值对于多个分层数据对象可以是公共的。通过消除重复的字段名称和/或字段值,字段名称和/或字段值信息的集合级整合可以进一步减少数据存储需求并降低输入/输出成本。例如,集合级压缩可以获得对多个分层数据对象的快速扫描,并且所得到的空间节省可以启用适合于单指令多数据(simd)操作的存储器中表示。

分层数据对象的集合中的每个分层数据对象100可以具有其自己的分层节点树400。然而,分层数据对象的集合可以共享公共的散列代码映射、公共的字段名称映射,以及/或公共的字段名称汇集。例如,可以通过整合分层数据对象的集合中的每个分层数据对象100的相应散列代码映射来获得公共的散列代码映射,由此实现散列代码的集合级压缩。附加地或替代地,分层数据对象的集合可以共享公共的字段值汇集。

然而,在实施例中,分层数据对象的集合也可以共享公共的分层节点树。分层数据对象的集合中的每个分层数据对象100可以被指派实例标识符,诸如序号。可以将分层数据对象的集合中的每个分层数据对象100的相应的分层节点树合并到超级分层节点树中。超级分层节点树中的每个节点可以存储经压缩的位图。特定节点的经压缩的位图可以存储共享该特定节点的每个分层数据对象100的相应实例标识符。超级分层节点树中的叶子节点可以包括经压缩的位图的数组。数组中的每个经压缩的位图可以与不同的字段值标识符对应,并且可以存储共享与不同字段值标识符对应的特定字段值的每个分层数据对象100的相应实例标识符。因此,可以针对分层数据对象的集合中的每个分层数据对象100并发地执行对分层数据对象的集合的导航。

对于在线交易处理(oltp)应用,将经编码的分层数据对象存储到blob字段中可以提供最佳性能,并且维护基于集合的表示可以在计算上是昂贵的。因此,主存储格式可以是单个经编码的分层数据对象100。可以为衍生的盘上结构或存储器中结构保留集合级编码。例如,盘上结构可以被脱机加载(off-load)以在盘单元服务器上进行基于向量的扫描。

硬件概述

根据一个实施例,本文描述的技术由一个或多个专用计算设备实现。专用计算设备可以是硬连线的以执行所述技术,或者可以包括诸如被永久性地编程以执行所述技术的一个或多个专用集成电路(asic)或现场可编程门阵列(fpga)的数字电子设备,或者可以包括编程为按照固件、存储器、其它存储装置或者其组合中的程序指令执行所述技术的一个或多个通用硬件处理器。这种专用计算设备还可以将定制的硬连线逻辑、asic或fpga与定制的编程组合来实现所述技术。专用计算设备可以是台式计算机系统、便携式计算机系统、手持式设备、联网设备或者结合硬连线和/或程序逻辑来实现所述技术的任何其它设备。

例如,图9是绘出可以在其上实现本发明的实施例的计算机系统900的框图。计算机系统900包括用于传送信息的总线902或其它通信机制,以及与总线902耦合的用于处理信息的硬件处理器904。硬件处理器904可以是例如通用微处理器。

计算机系统900还包括耦合到总线902的用于存储信息和要由处理器904执行的指令的主存储器906,诸如随机存取存储器(ram)或其它动态存储设备。主存储器906也可以用于在要由处理器904执行的指令的执行期间存储临时变量或其它中间信息。当这些指令被存储在处理器904可访问的非瞬态存储介质中时,它们使计算机系统900成为被定制为执行指令中指定的操作的专用机器。

计算机系统900还包括耦合到总线902的用于存储静态信息和用于处理器904的指令的只读存储器(rom)908或其它静态存储设备。提供了诸如磁盘或光盘的存储设备910,并且存储设备910被耦合到总线902以用于存储信息和指令。

计算机系统900可以经由总线902耦合到显示器912(诸如阴极射线管(crt)),以用于向计算机用户显示信息。包括字母数字键和其它键的输入设备914耦合到总线902,以用于向处理器904传送信息和命令选择。另一种类型的用户输入设备是光标控件916,诸如鼠标、轨迹球或光标方向键,用于向处理器904传送方向信息和命令选择并且用于控制显示器912上的光标移动。这种输入设备通常具有在两个轴(第一轴(例如,x)和第二轴(例如,y))上的两个自由度,这允许设备指定平面中的位置。

计算机系统900可以使用定制的硬连线逻辑、一个或多个asic或fpga、固件和/或程序逻辑来实现本文描述的技术,这些定制的硬连线逻辑、一个或多个asic或fpga、固件和/或程序逻辑与计算机系统组合使计算机系统900成为或将计算机系统900编程为专用机器。根据一个实施例,本文的技术由计算机系统900响应于处理器904执行包含在主存储器906中的一个或多个指令的一个或多个序列而执行。这些指令可以从另一个存储介质(诸如存储设备910)读取到主存储器906中。包含在主存储器906中的指令序列的执行使处理器904执行本文描述的处理步骤。在替代实施例中,可以使用硬连线电路系统代替软件指令或与软件指令组合使用。

如本文使用的术语“存储介质”是指存储使机器以特定方式操作的数据和/或指令的任何非瞬态介质。这种存储介质可以包括非易失性介质和/或易失性介质。非易失性介质包括例如光盘或磁盘,诸如存储设备910。易失性介质包括动态存储器,诸如主存储器906。存储介质的常见形式包括例如软盘、柔性盘、硬盘、固态驱动器、磁带或任何其它磁性数据存储介质、cd-rom、任何其它光学数据存储介质、具有孔图案的任何物理介质、ram、prom和eprom、flash-eprom、nvram、任何其它存储芯片或盒带。

存储介质与传输介质不同,但可以与传输介质结合使用。传输介质参与在存储介质之间传输信息。例如,传输介质包括同轴线缆、铜线和光纤,包括包含总线902的线。传输介质还可以采取声波或光波的形式,诸如在无线电波和红外数据通信期间生成的那些波。

将一个或多个指令的一个或多个序列携带到处理器904以供执行可能涉及各种形式的介质。例如,指令初始地可以被携带在远程计算机的磁盘或固态驱动器上。远程计算机可以将指令加载到其动态存储器中并且使用调制解调器经电话线发送指令。计算机系统900本地的调制解调器可以在电话线上接收数据并使用红外发射器将数据转换为红外信号。红外检测器可以接收红外信号中携带的数据,并且适当的电路系统可以将数据放置在总线902上。总线902将数据携带到主存储器906,处理器904从主存储器906取回并执行指令。由主存储器906接收到的指令可以可选地在被处理器904执行之前或之后存储在存储设备910上。

计算机系统900还包括耦合到总线902的通信接口918。通信接口918提供耦合到网络链路920的双向数据通信,其中网络链路920连接到本地网络922。例如,通信接口918可以是向对应类型的电话线提供数据通信连接的综合业务数字网(isdn)卡、线缆调制解调器、卫星调制解调器或调制解调器。作为另一个示例,通信接口918可以是提供到兼容的局域网(lan)的数据通信连接的lan卡。也可以实现无线链路。在任何这样的实现方式中,通信接口918发送和接收携带表示各种类型信息的数字数据流的电信号、电磁信号或光学信号。

网络链路920通常通过一个或多个网络向其它数据设备提供数据通信。例如,网络链路920可以通过本地网络922提供到主机计算机924或到由互联网服务提供商(isp)926运营的数据装备的连接。isp926继而通过现在通常称为“互联网”928的全球范围的分组数据通信网络提供数据通信服务。本地网络922和互联网928二者使用携带数字数据流的电信号、电磁信号或光学信号。通过各种网络的信号以及在网络链路920上并且通过通信接口918的信号是传输介质的示例形式,其中信号将数字数据携带到计算机系统900和携带来自计算机系统900的数字数据。

计算机系统900可以通过(一个或多个)网络、网络链路920和通信接口918发送消息和接收数据,包括程序代码。在互联网示例中,服务器930可以通过互联网928、isp926、本地网络922和通信接口918传输对应用程序的请求代码。

接收到的代码可以在其被接收到时由处理器904执行,和/或存储在存储设备910或其它非易失性存储器中以供以后执行。

在前面的说明书中,已经参考许多具体细节描述了实施例,这些具体细节可以因实现方式而异。因此,说明书和附图应当在说明性而不是限制性的意义上加以考虑。本公开范围的唯一且排他指示,以及申请人预期要作为本公开范围的是由本申请发布的权利要求集合的字面范围和等效范围,这是以这些权利要求产生的具体形式,包括任何后续的校正。

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