专利名称::确定底层数据改变如何影响高速缓存对象的制作方法
技术领域:
:本发明与Challenger等的题为“维护和一致性更新高速缓冲存储器的可剪裁方法”(USPNo.08/905,225)的待决美国专利申请S/N(待定)(与本申请同日受理)有关。该专利申请与本发明一起赋予国际商用机器公司(IBM),Armonk,纽约。这里把该专利申请全文引用作为参考。本发明涉及一种改进的数据处理系统。各具体方面与万维网(worldwideweb)、数据库及事务处理系统有关。更具体地说,涉及万维网上动态资料的高速缓冲存储。从万维网上提取资料所能达到的速度是万维网在传送信息和支持电子商务方面可用性如何的重要因素之一。万维网服务器必须能快速地把内容提供给用户。由万维网服务器发送的数据可分为两类(1)静态数据。这类数据是从计算机上存储的文件中得到的。静态数据能被较快地提供给用户。在计算机上运行的高性能服务器(如单个RS/6000590节点)通常每秒能发送数百个文件。(2)动态数据。这类数据是通过发出请求时执行程序得到的。通常建立动态数据是花费很大的。在许多情况下,得到动态数据的花费比得到静态数据的花费要高一至二个数量级。对于含有的动态数据占很高百分比的万维网站点,动态数据性能会成为瓶颈。含有高百分比动态数据的站点实例包括使用IBM网商务软件的电子商务站点。如LLBean万维网站点(www.llbean.com)和IBM1996奥林匹克万维网站点。减小动态数据总开销的一种方法是在由程序建立起动态页之后把这些动态页存储在高速缓冲存储器中(见Y.H.Liu,P.Dantzig,C.E.Wu,J.Challenger,L.M.Ni的“多平台上的分布式万维网服务器及其性能分析”,分布式计算系统国际会议文集,1996年5月)。这样,其后需要访问这些页的请求可以访问高速缓冲存储器中的副本。一页只需由程序计算一次。于是减少或消除了为响应多次请求而多次重新计算同一页所需的开销。高速缓存不能应用于所有的动态万维网页。某些动态页会引起状态变化,这些状态变化必须在这些页面被请求时发生。这种页面不能被高速缓存。对于能被高速缓存的页面,仍需要一种方法,用于当可能影响一个或几个万维网页之值的底层数据发生变化时去更新高速缓冲存储器。例如,往往由数据库来建造动态万维网页。当数据库改变时,可能会特别难于确定由于数据库的改变使哪些高速缓存对象已成为过时的。本发明为这一问题提供了一种解决方案。这种解决方案是相当通用的,能被用于需要知道底层数据变化如何影响对象值的其他场合。另一个问题是当底层数据源和高速缓冲存储器在地理上分离时如何保持一个或多个高速缓冲存储器能被更新。本发明有一个对此问题的解决方案,它与动态和静态两类数据的代理高速缓存有关。第三个问题是如何使对一个或多个高速缓冲存储器的更新保持前后一致性,从而使所有更新立即完成,而且由系统收到的请求所看到的关于更新的系统内容不会是比后来收到的请求所看到的系统内容更迟。本发明对于与静态和动态数据两者的代理高速缓存有关的一致性问题有一个解决方案。它也与事务处理系统有关,这些系统不一定涉及高速缓冲存储器。在技术上已知有应用程序去管理为建立计算机程序所必须的文件之间的依赖关系。例如,单个程序可能由多个源文件和目标文件构成。已经研制出了管理源文件、目标文件及可执行文件之间依赖关系的工具。用于管理这种依赖关系的最有名的实用程序之一是Unix的make命令(例如参见IBMAIX第4版在线手册页)。如make这类实用程序需要用户在一个称作makefile的特殊文件中指定各文件之间的依赖关系。例如,可把如下关于文件依赖关系的说明放在一个makefile文件中foo:foo.hfoo.ccc-ofoofoo.c以指出“foo”依赖于“foo.h”和“foo.c”。当下一次发出“makefoo”命令时,对“foo.h”或“foo.c”的任何改变都会造成利用命令“cc-ofoofoo.c”对“foo”的重新编译。如makefile之类实用程序有若干限制,包括(1)makfile只允许被指定的文件之间的依赖关系。指定一个文件和不是文件的某种东西之间的依赖关系是不可能的。需要一种方法,它允许指定能存储在高速缓冲存储器中的对象与不能被高速缓存的图对象(它包括底层数据)之间的依赖关系。(2)利用makefile方法时,每当被“make”命令发现文件过时时,所有过时文件都被更新而不管文件可能会是怎样过时的。也需要一种方法,它不要求过时的对象总是被更新;于是,例如一个稍许过时的过时文件可以被保留在高速缓冲存储器中。(3)makefile方法还只允许在文件系统中一个时候只存在文件的一个版本。需要一种方法允许在同一高速缓冲存储器中同时存在同一对象的多个版本。(4)还需要一种方法能提供确定对象过时程度的定量方法,这是makefile之类工具所没有提供的。(5)需要一种定量方法来确定同一对象两个版本的相似程度,这也是makefile之类工具所没有提供的。(6)还需要一种方法来保持一组具有一致性的可能过时的对象,这也是makefile之类工具所没有提供的。(7)需要一种方法精确地指定称作关系对象的对象(它们可能是关系数据库的一部分)之间的依赖关系,这是makefile之类工具所没有提供的。本发明致力满足这些需要。在许多情况中,对象的值依赖于底层数据。本发明的目标是确定底层数据的变化如何影响对象的值。作为一例,考虑一个万维网站点,它的页面是由数据库动态建立的。在这种场合,动态万维网页面是对象而底层数据包括数据库。在一些情况下,一个万维网页可能依赖于一个类似的网页,而这后一个网页又依赖于一个数据库。有可能建立一个完整的依赖关系结构,其中一些对象依赖于其他对象,而这其他对象又依赖于另一些对象。也有可能建立一组对象之间的共同依赖关系,其中对这一组对象中任何一个对象的更新影响到该组中所有其他对象的值。本发明另一方面的目标是提供一种方法来指定对象和底层数据之间的依赖关系,它允许底层数据变化后由计算机系统把更新内容传播到系统中的所有对象。该方法包括如下的一个或多个特点1.能以层次结构形式指定依赖关系,这里一些对象可能依赖于另一些对象,而这另一些对象又依赖于另一些对象,如此等等。2.多组对象能有共同依赖关系。例如,两个对象彼此之间有这样的关系,它们指明每当其中一个对象的值变化时另一个对象的值便发生变化。3.一种方法,能保证每当一个对象所依赖的底层数据变化时该对象便被更新(或被令其无效)。4.一种定量方法,用于确定一个对象的过时版本与当前版本有多大不同。5.一种方法,能保证当一个对象与当前版本有足够大差异时被更新或被令其无效。当总是保持一个对象为当前版本会造成太大开销时,这种方法是有用的。6.每当一个对象的值被重新计算时便产生该对象的一个新版本。能保持同一对象的多个版本。对于同一对象的两个副本,能确定(a)是否这两个对象对应于同一版本因而它们完全相同;(b)如果对(a)的回答为“否”,那么哪个版本较新(即建立得较迟);以及(c)如果对(a)的回答为“否”,则定量指出这两个对象的差异程度。7.一种方法,用于保持一组对象之间的一致性,而不需要所有对象都是当前的。当要求所有对象为当前对象以保证其一致性会造成太大开销时,这种方法是有用的。8.一种方法,用于管理关系对象,借以能由对象管理器自动添加关系对象之间的隐含数据依赖关系。本发明的应用例包括如下场合1.高速缓存动态万维网页。2.客户机-服务器应用在许多客户机一服务器应用中,服务器将向多个客户机发送对象。这些对象总是在改变。根据何时对象被请求,同一对象的不同版本会被送到不同的客户机。该服务器需要某种方法来保持跟踪哪些版本被送到哪些客户机以及这些版本的过时程度如何。3.需要满足下述要求的任何场合维持对象的若干版本,唯一地识别它们,如果它们变得太过时便更新它们,定量评估同一对象的两个版本差异程度,和/或保持一组对象之间的一致性。一个最佳实施例利用了一个被定向图,称作对象依赖关系图(G),它代表了对象间的数据依赖关系。从对象o1到另一对象o2的边缘表明o2依赖于o1。对o1的任何更新也改变o2的当前值。在另一个实施例中,每个边缘能带有一个非负数,称为权,它代表该数据依赖关系的重要性。例如,大数能代表重要的依赖关系,而小的数代表不重要的依赖关系。对象还能带有一个值,称作权阈值。每当那些对应于当前的输入数据依赖关系的权之和低于权阈值时,该对象被认为是高度过时的。对于那些需要对象近期版本的应用,这类对象应被更新。每个对象最好有一个object_id(对象标识)字段和一个version_number(版本号)字段。对象标识字段对应于应用程序用来识别该对象的某种标记(例如URL),而版本号字段允许保持和唯一识别有相同对象标识的多个对象。更具体地说,称作对象管理器的一个过程保持数据依赖关系信息。每当新对象被创建或数据依赖关系变化,该对象管理器负责更新适当的信息。每当一个对象被更新,对象管理器利用对象依赖关系图中的信息把其他的更新内容传播给被数据依赖关系迫使的系统。每个对象o1还可以有一个一致性列表,它包含那些必须与o1保持一致性的对象的清单。如果满足下列条件中的任何一个,则两个对象o1和o2是一致的(1)两个对象都是当前的;或(2)在过去的某个时候,这两个对象曾是当前的。对o1的更新还会迫使对o1的一致性列表上的其他对象进行更新。有可能把一个对象与一个或多个属于关系(这类似于关系数据库中的关系)的记录关联起来。这个对象称作关系对象。本发明还具有在关系对象之间自动增加依赖关系的特点。从下文中的详细描述及附图,将更清楚地看出这些和其他特点和优点,这些图件是图1a描述了具有本发明特征的系统的一例;图1b描述了具有本发明特征的对象依赖关系图的一例;图1c描述了具有本发明特征的系统的一例;图2描述了根据本发明所使用的高速缓冲存储器的一例;图3描述了根据本发明所使用的对象信息块(OIB)的一例;图4描述了根据本发明的API函数的一例;图5描述了实现图4的API函数的一种方法的方框图;图6描述了把一个对象加到一个高速缓冲存储器中的API函数的方框图;图7描述了用于在一个高速缓冲存储器中寻找一个对象的API函数的方框图;图8描述了用于从一个高速缓冲存储器中删除一个对象的API函数的方框图;图9描述了用于添加一个从记录到对象的依赖关系的API函数的方框图;图10描述了用于删除一个从记录到对象的依赖关系的API函数的方框图;图11描述了当一个记录改变时被调用的一个API函数的方框图;图12a描述了具有本发明特点的系统的另一例;图12b描述了具有本发明特点的对象依赖关系图的另一例;图12c描述了图12a的对象管理器的一例;图12d是具有本发明特点的一个对象依赖关系图的另一描述;图13描述了根据本发明的一个实施例所使用的高速缓冲存储器的一例;图14描述了根据本发明而使用的目标信息块的一例;图15描述了根据本发明而使用的依赖关系列表的一例;图16描述了根据本发明而使用的依赖关系信息块(DIB)的一例;图17描述了根据本发明的API函数的另一例;图18描述了为实现图17的API函数所用方法的方框图;图19描述了把一个对象的最近版本添加到一个高速缓冲存储器中的一个高速缓冲存储器API函数的方框图;图20描述了试图把一个对象的一个版本从一个高速缓冲存储器中复制到另一个中的API函数的方框图;图21描述了当底层数据变化时可能被调用的一个API函数的方框图;图22描述了响应底层数据变化通过对象依赖关系图传播变化所用方法的一部分的方框图;图23描述了响应底层数据变化以“深度”优先(depth-first)方式通过对象依赖关系图传播变化所用方法一部分的方框图;图24描述了响应底层数据变化向一特定图对象传播变化所用方法一部分的方框图;图25描述了响应底层数据变化更新一个对象的被高速缓存版本或使其无效所用方法一部分的方框图;图26描述了当响应底层数据变化而把一个或多个对象添加到一个或多个高速缓冲存储器中时为了保持一致性所用方法一部分的方框图;图27描述了为创建对应于单一记录对象(SRO)的图节点所用高速缓冲存储器API函数的方框图;图28描述了为创建对应于多重记录对象(MRO)的图节点所用高速缓冲存储器API函数的方框图;图29a描述当记录变化时可能被调用的一个API函数的方框图;图29b描述了一个对象依赖关系图的另一例以及它怎样能被用于向图对象传播变化;图30a描述用于可剪裁维护和一致性更新高速缓冲存储器的具有本发明特点的系统的方框图举例;图30b描述了图30a的触发监视器的更详细的举例,作为一个主触发监视器来举例说明;图30c描述了触发监视器一例,作为一个从属触发监视器来举例说明;图30d描述了图30b的send_trigger(发送触发器)API的一例;图30e描述了根据本发明的事务类型举例;图31描述了图30b的对象配置块(ODB)的一例;图32描述了图31的高速缓冲存储器标识(ID)的一例;图33描述了触发监视器驱动器和分布管理器的高级组织和通信路径的一例;图34描述了图33的接收线程逻辑的一例;图35描述了图33的输入任务分发器线程逻辑的一例;图36描述了图33的高速缓存管理器通信线程逻辑的一例;图37描述了图33的对象发生器线程逻辑的一例;图38描述了图33的分布管理器线程逻辑的一例;图39描述了图33的出界(outbound)事务线程逻辑的一例;图40描述了用于分析和解释触发器事件的各种扩展和变体的举例;图41描述了一致性地建立对具有一个或多个高速缓冲存储器的系统的一组请求所用的逻辑的一例;以及图42描述了如果接收请求的一组高速缓冲存储器有多个成员而用于确定最后锁住时间(lastlocktime)的逻辑的一例。确定底层数据变化如何影响被高速缓存对象的方法的详细描述术语表尽管这里所用术语也包含了字典中的意义,但下述一些术语的术语表可能是有用的一个高速缓冲存储器(cache)是一个存储区域。它可以在内存储器中,在磁盘上,或者部分在内存储器中部分在磁盘上。对应于高速缓冲存储器的物理地址或虚拟地址可以是固定的。或者,它们可以随时变化。对高速缓冲存储器的定义包括(但不限于)-用于万维网资料的高速缓冲存储器,如IBM因特网连接服务器中的代理高速缓冲存储器或网景导航者(NetscapeNavigator)中的浏览器高速缓冲存储器;-数据库高速缓冲存储器,如在IBM的DB2数据库中的高速缓冲存储器;-处理器高速缓冲存储器,如在IBM的RS/6000计算机线中的高速缓冲存储器;以及-在高级程序语言中被写入数据的存储仓库,这里对于至少是一部分数据,存储仓库程序没有对于存储数据区域的虚拟或物理地址的显示式控制。高速缓存组合(cacheunion)是系统中所有高速缓冲存储器的组合。对象(obiject)是能被存储在一个或多个高速缓冲存储器中的数据。多版本高速缓存(multipleversioncache)是被允许包括同一对象多个版本的高速缓冲存储器。单版本高速缓存(singleversioncache)是只被允许包括同一对象的一个版本的高速缓冲存储器。当前版本高速缓存(currentversioncache)是一个单版本高速缓存,其中任何被高速缓存的对象的版本必须是当前版本。底层数据(underlyingdata)包括系统中可能影响一个或多个对象之值的所有数据。底层数据是系统中所有对象的超级集合。复杂对象(complexobject)是具有对底层数据的一个或多个依赖关系的对象。对象管理器(objectmanager)是一个程序,它确定底层数据的变化如何影响对象之值。图G=(V,E)(graphG=(V,E))由有限和非空的顶点V(也称作节点)集合以及由“顶点对”构成的边缘E的集合构成。如果边缘是顶点(ν,w)的有序对,则称该图是以ν为边缘的源而以w为边缘的靶标的被定向图。多重图(multigraph)与图类似。其关键性差别在于在多重图中的“顶点对”之间可能存在多个边缘。多重图是图的超级集合。加权图(weightedgraph)或加权多重图(weightedmultigraph)是其中每个边缘可能会带有一个称作权的数的图或多重图。对象依赖关系图(objectdependencegraph)是一个被定向多重图。对象依赖关系图的顶点称作图对象(graphobject)。图对象是对象的超级集合,可能包括(1)对象;(2)不是对象的底层数据;以及(3)虚拟对象。这些图对象不对应于实际数据。使用它们是为了便于对数据依赖关系编程。虚拟对象不象(1)和(2)那样被频繁使用。从图对象o1到o2的边缘指示从o1到o2的一个数据依赖关系(也称作依赖关系或依赖性)。这意味着对o1的改变也会改变o2。依赖关系是传递性的。这样,如果a有对b的数据依赖关系,b有对c的数据依赖关系,则a有对c的依赖关系。图对象也可以是关系对象(RO)。RO有附属的关系分类符。RO的两个例子是1.单记录对象(SRO);关系分类符代表单个记录;2.多记录对象(MRO);关系分类符代表多重记录。如果由ROr2代表的所有记录也由ROr1代表,则称ROr1包含(包括)ROr2。节点ν的出发毗邻列表(outgoingadjacencylist)是含有其边缘(ν,w)被包含在E中的全部节点w的列表。叶节点(leafnode)是这样一个节点,它不是任何边缘的靶标。正常叶节点(properleafnode)是这样一个叶节点,它是至少一个边缘的源。最高节点(maximalnode)是这样一个节点,它不是任何边缘的源。正常最高节点(propermaximalnode)是这样一个最高节点,它是至少一个边缘的靶标。简单依赖关系图(simpledependencegraph)是这样一个被定向图,其中每个节点为叶节点或最高节点。两个对象o1和o2是一致的,如果它们满足下列条件之一(1)两个对象都是当前的;或者(2)在过去的某个时候t,这两个对象曾是当前的。版本号(versionnumber)是允许同一对象的不同版本被唯一识别所用的数据。一个实现方式是使用整数作为版本号,而且对新创建的当前版本赋予的版本号是前一个版本的版本号加1。然而,其他实现方式也是可能的,而且版本号不一定必须为数字。例如,文字串也能用来实现版本号。对象的最新近的版本称作当前版本。现在参考图件,图1a描述了具有本发明特点的客户机-服务器结构的一例。如图所示,客户机90通过网络95向服务器100发出请求。服务器100维持一个或更多的高速缓冲存储器2。如传统作法那样,服务器100使用高速缓存2以改善性能和减小为满足客户机90的请求所用的CPU时间。虽然图1a所示高速缓存2与单个服务器关联,但高速缓存2也能保持为跨越多个服务器。本行专家也能容易地使本发明适应于不是基于客户机-服务器结构的其他应用。在服务器100上运行的一个应用程序97创建对象,然后把这些对象(例如那些在受到请求时不会引起状态改变的动态页)存储在一个或多个高速缓冲存储器2中。服务器100也能是一个代理服务器,这里在数据库99中的底层数据源和高速缓存2在地理上是分离的。在本实施例中,对象是能被存储在一个或多个高速缓存2中的数据。这些对象能由存储在数据库99上的底层数据构成。底层数据包括系统中可能影响存储在高速缓存2中的一个或多个对象之值的所有数据。底层数据是系统中全部对象的超级集合。一个复杂对象是对底层数据有一个或多个依赖关系的对象。再有,让高速缓存组合中的高速缓存2全部是当前版本高速缓存。请回想一下,当前版本高速缓存是这样一个单一版本高速缓存,其中任何被高速缓存的对象的版本都必须是当前的,而且单一版本高速缓存是只被允许包括同一对象的一个版本的高速缓存。根据本发明,高速缓存管理器1(它是对象管理器的一例)确定底层数据的变化如何影响对象之值。虽然图1a所示高速缓存管理器1驻留在单个服务器上,但它也能被分布在多个服务器上。高速缓存管理器1最好是具体实现为计算机可执行代码,明确地实现在一个程序存储器装置上供计算机(如服务器100或客户机90)执行。本行专家将会理解,根据本发明,高速缓存2、高速缓存管理器1及数据库99能以类似的方式与客户机90关连。高速缓存管理器1提供API(图4)用于指定一个被高速缓存的对象依赖于什么底层数据,例如数据库记录。高速缓存管理器1跟踪这些依赖关系。每当一个过程修改一个状态,而此状态会影响高速缓存中一复杂对象之值时,该过程便指定它正在更新的底层数据。于是高速缓存管理器1使依赖于正被更新的底层数据的所有被高速缓存的对象变为无效。图1b描述了具有本发明特点的对象依赖关系图(G)121’。请注意在本实施例中的对象依赖关系图(G)121’不如另一实施例(图12b)中的那么复杂。这里,对象依赖关系图121’是一个简单依赖关系图,即这样一个被定向图,其中每个节点是叶节点r1…r3或最高节点co1,co2。请回想,叶节点是不为任何边缘靶标的节点,而最高节点是不为任何边缘之源的节点。还请注意,每个路径的长度为1,故不需为边缘指定权。再有,每个正常最高节点(为至少一个边缘之靶标的最高节点)co1、co2是对象;而G中的每个正常叶节点r1…r4(一个叶节点是至少一个边缘之源)代表不是对象的底层数据。由每个正常叶节点r1…r4所代表的底层数据最好是记录(这些记录与第二实施例中所用记录是不同义的)。由正常最高节点co1、co2代表的对象是复杂对象。高速缓存管理器1保持一个代表对象依赖关系图121’的底层数据结构(见图2-3)。应用程序97通过一组高速缓存API(见图4)把对象依赖关系图的结构通知给高速缓存管理器1。该应用程序还利用API向对象管理器1通告已经改变的记录r1…r4。当高速缓存管理器1被通告对记录r1…r4的改变时,它必须识别哪些复杂对象co1、co2已被影响并使被识别出的复杂对象从包含它们的任何高速缓存2中删除(或更新)。高速缓存管理器1能通过检验G中的边缘(见图11)来确定哪些复杂对象已经改变。例如,假定高速缓存管理器1被通告r1已经改变。G121’意味着co1也已改变。高速缓存管理器1必须确保co1从任何包含它的高速缓存2中删除(或更新)。作为另一个例子,假定r2已经改变。G121’意味着co1和co2也已受影响。这里,高速缓存管理器1必须确保co1和co2都从任何包含它们的高速缓存2中删除(或更新)。换句话说,基本步骤是在应用级构建复杂对象,从而使它们依赖于一组记录。该应用程序必须能指出复杂对象co1、co2依赖于哪些记录r1…r4。对于修改状态的方式会影响被高速缓存的复杂对象之值的每个过程,应用程序必须能指出哪些记录受到影响。这类复杂对象被称作处于正常形式。许多前已存在的万维网应用程序创建的可高速缓存的复杂对象已经是正常形式的。为了在这些应用中使用高速缓存,只需要识别出复杂对象底层的记录并通过所提供的API建立应用和高速缓存之间的接口。最好是,高速缓存管理器1是对一个或多个高速缓存2管理其存储的一个长运行过程。然而,本行专家会容易地使本发明适应于下列之一的高速缓存管理器1.多个分立过程,其中没有任何过程在时间上重叠;2.多个分立过程,其中有一些可能在时间上重叠。这包括如此设计的多重并发高速缓存管理器以改善高速缓存系统的吞吐能力。图1c描述了根据本发明的用于高速缓存动态万维网页的系统的一例。如所描述的那样,考虑一个传统的万维网站点100,这里页面(页1,…,页5)是动态地从一个或多个数据库99创建的,并存储在一个或多个高速缓存2中。适于本发明的数据库99和数据库管理系统的一例是由IBM公司以商标DB2销售的那种。这里,动态万维网页(页1,…页9)是对象,而底层数据(表/记录)包括数据库99的一些部分。根据本发明,高速缓存管理器1提供API(图4),这些API允许应用程序97指定被高速缓存的对象所依赖的记录。高速缓存管理器1跟踪这些依赖关系。每当一应用程序97修改记录或得知会影响高速缓存中的复杂对象之值的记录发生变化,应用程序97便把已被更新的记录通告给高速缓存管理器1。于是,高速缓存管理器1使依赖于已经改变的记录的所有被高速缓存的对象无效或使其更新。例如,考虑图1C中描述的HTML页(页1…页5)。这些HTML页是复杂对象,它们是由数据库99构建的并存储于高速缓存3。每个HTML页可能对一个或多个记录有依赖关系,而这些记录是数据库的若干部分,表示为表1、表2、…表6。这些表和页之间的对应关系能由散列表(hashtable)和记录列表19来维持。例如,如果高速缓存管理器1被告知表1的变化T1,它会使页1无效(或更新)。类似地,如果高速缓存管理器1被告知表2的变化T2,它会使页1、页2、页3无效(或更新)。图2描述了高速缓存2的一例。如所描述的那样,每个高速缓存2最好有4个存储区一个目录3保持关于被高速缓存对象的信息;一个对象存储器4用于存储若干对象6;辅助状态信息5,它包括其他状态信息(如由高速缓存维持的统计信息);以及散列表19,它把关于记录的信息存储在散列表条目25中。在一个最佳实施例中,散列表条目25包含记录标识(ID)12和对象列表8,它包括对象列表,即对象标识(id)9,其值依赖的记录可能是数据库99的一部分。然而,本发明还允许其他类型信息存储到散列表条目中。散列表的目的是提供一种有效的方法来找出关于特定表/记录的信息。最好是散列表中以记录ID12作为关键字。散列表在技术上是公知的(例如参见“计算机算法的设计和分析”,Aho,Hopcroft,Ullman,Addison-Wesley,1974)。散列表为本发明提供了一种有效的数据结构。然而,本发明与广泛的其他数据结构兼容,并不限于使用散列表。目录3包括存储在高速缓存中的每个对象6的对象信息块(OIB)10。OIB10的组份之一是记录列表11(图3),它用于存储标识记录r1…r4的记录ID12,这些记录r1…r4是与复杂对象co1、co2相关联的。这里,复杂对象是存储在高速缓存2中的动态万维网页(页1…页5),而记录可以是数据库99的一部分。虽然该最佳实施例使用文字串作为记录ID,其他方法也是兼容的。应用程序通过一组API函数与高速缓存管理器1通信。根据本发明的API举例示于图4。对于本行专家,能在本发明的精神和范围内以直接的方式实现添加许多API。如所描述的那样,举例的API是cache_object(object_id,object,cache_id)(高速缓存对象(对象标识,对象,高速缓存标识))410在关键字otject_id9下把由cache_id标识的对象6存储在由cache_id标识的高速缓存2中(图2);重写有相同关键字的任何先前的对象6。本发明与object_id,object及cache_id的广泛多样的类型兼容。在此最佳实施例中,对象6可以有若干类型,object_id是字节串,cache_id是字符串。这里,虽然最好不允许具有同一关键字的多个项同时存在于同一高速缓存,然而,本行专家不难把本发明用于在同一高速缓存中能同时存在具有同一关键字的多个项的场合。lookup_object(object_id,cache_id)(查寻对象(对象标识,高速缓存标识))415以关键字object_id9查寻高速缓存2中由cache_id标识的对象6。如果存在任何这种对象,则把它返回给应用程序。delete_obiect(object_id,cache_id)(删除对象(对象标识,高速缓存标识))420以关键字object_id9查寻高速缓存中由cache_id标识的对象6。如果存在任何这种对象,则删除它。add_dependency(object_id,cache_id,record_id)(添加依赖关系(对象标识,高速缓存标识,记录标识))430以关键字object_id9在由cache_id标识的高速缓存2中查找对象6。如果存在任何这类对象6,而且在对象6和与这个record_id相关联的由record_id12标识的记录之间没有依赖关系,则添加这个依赖关系。delete-dependency(object_id,cache_id,record_id)(删除依赖关系(对象标识,高速缓存标识,记录标识))440以关键字object_id9在由cache_id标识的高速缓存中查寻对象6。如果存在任何这类对象6,而且在对象6和由record_id12标识的记录之间存在一个依赖关系,则删除这个依赖关系。invalidate_record(cache_id,record_id)(使记录无效(高速缓存标识,记录标识))450从由cache_id标识的高速缓存2中删除依赖于由record_id标识的记录的所有高速缓存对象。show_dependent_objects(cache_id,record_id)(显示依赖对象(高速缓存标识,记录标识))460对于由cache_id标识的高速缓存2中依赖于由record_id标识的记录的所有对象返回一个object_id9的列表,这个函数可以通过返回散列表条目25的对象列表8来实现,这个散列表条目25是对应于由record_id标识的记录的。也能返回一个状态变量来指出是否没有发现高速缓存2或散列表条目25。show_associated_records(cache_id,object_id)(显示相关记录(高速缓存标识,对象标识))470对于对象6(在由cache_id标识的高速缓存2中的由object_id标识的对象)所依赖的所有记录返回一个记录标识12的列表。这个函数能通过返回记录列表11(图3)来实现,该记录列表11是为cache_id标识的高速缓存2中由object_id标识的对象6建立的。也能返回一个状态变量来指出是否没有发现高速缓存或对象6。图5描述了高速缓存管理器1逻辑一例。如所描述的那样,在步骤1010,高速缓存管理器收到一个来自应用程序的命令(图4)。在步骤1020,高速缓存管理器读出这个命令(图4)。并根据这个命令调用下文描述的不同逻辑1100…1600。图6描述了对于cache_object(object_id,object,cache_id)410命令的高速缓存管理器逻辑1200。如所描述的那样,在步骤1200,高速缓存管理器1确定该cache_id参数是否指定一个有效的高速缓存2。如果不是,则在步骤1245设置适当的状态变量以回送给应用程序。如果cache_id指定了一个有效的高速缓存2,则最好是把高速缓存2锁住,以避免多个过程并发访问该高速缓存。以这种方案来保持其一致性。专门专家将会理解,其他锁住方式可以使用,以提供更高级别的并发性。除了在最佳实施例中所用的例子外,本发明与广泛多样的传统锁住方案兼容。在步骤1205,高速缓存管理器1通过检验目录3(图2)来查寻对象6。如果找到了对象6的先前副本,则在步骤1215对象6的OIB10被更新,而且在对象存储器4中的对象6的老版本被新版本替代并适当设置状态变量。如果在步骤1205中未发现对象6的一个先前副本,则在步骤1210为对象6建立新的OIB10,初始化,并存储在目录3中。高速缓存管理器1还把对象6存储在对象存储器4中并适当改变状态变量。在步骤1230,高速缓存被解锁从而允许其他过程对其更新。在步骤1240,指示命令结果的状态变量被回送到应用程序。于是过程返回步骤1010(图5)。图7描述了lookup_object(object_id,cache_id)415命令的逻辑的举例。如所描述的那样,在步骤1600,高速缓存管理器1确定cache_id参数是否指定了一个有效的高速缓存2。如果不是,则在步骤1640设置适当的状态变量并在步骤1680回送给应用程序。如果cache_id指定了一个有效的高速缓存,则在步骤1610使高速缓存2被锁住。在步骤1620,高速缓存管理器1通过检验目录3(图2)来查寻对应于object_id参数的对象6。如果未找到对象6,则在步骤1650对高速缓存2解锁;在步骤1670设置状态变量并在步骤1680返回应用程序。如果在步骤1620找到了对象6,则在步骤1630对高速缓存2解锁;并在步骤1660把对象6回送给应用程序。图8描述了delete_object(object_id,cache_id)420命令。如所描述的那样,在步骤1100,高速缓存管理器1确定对应于cache_id参数的高速缓存2是否有效。如果无效,则在步骤1103适当设置状态变量并在步骤1150将状态变量回送给应用程序。如果在步骤1100,cache_id指定的高速缓存是有效的,则在步骤1105使高速缓存被锁住。在步骤1107,高速缓存管理器1通过检验目录3(图2)来查寻对应于object_id参数的对象6。如果对象6未被找到,则在步骤1108使高速缓存解锁;在步骤1109设置状态变量;并在步骤1150把状态参数回送给应用程序。如果在步骤1107找到了对象6,则在步骤1110由高速缓存管理器1删除该对象所关联的记录列表11(图3)并更新相应的对象列表8(图2)。高速缓存管理器1扫描对应于对象6的记录列表11(图3)的每个记录ID12。请注意,在记录列表11上的每个记录ID12有一个相应的对象列表8(图2)。对应于被删除对象6的指向对象id(对象标识)9(图2)的指针均被从所有这类对象列表8中去掉。如果这样做的结果造成任何对象列表8变空,则相应的散列表条目25也被删除。在记录列表11中的每个元素被检验过之后,它可被删除。在步骤1120,对象6被从对象存储器4中删除。在步骤1130,相应的OIB10被删除。请注意,步骤1120能与步骤1110和1130并发完成或在步骤1110及1130之前完成。在步骤1140,高速缓存被解锁,并在1150把状态变量回送给应用程序。图9描述了add_dependency(object_id,cache_id,record_id)430命令的逻辑的举例。如所描述的那样,在步骤1300,高速缓存管理器1检验cache-id参数是否指定了一个有效的高速缓存2。如果不是,则在步骤1302设置适当的状态参数并在步骤1360回送给应用程序。如果在步骤1300确认cache_id指定了一个有效的高速缓存,则在步骤1305使高速缓存2被锁住。在步骤1310,高速缓存管理器1通过检验目录3(图2)来查寻对应于object_id的对象6。如果在步骤1310未找到对象6,则在步骤1315高速缓存2被解锁;在步骤1317设置状态变量,并在步骤1360把适当的状态变量回送给应用程序。如果在步骤1310找到了对象6,则在步骤1320高速缓存管理器1检验记录列表11(图3),看对象6和由record_id指定的记录之间是否已经存在关联(即依赖关系信息)。另一作法是,能确定对应于record_id的记录是否有一个散列表条目25,如果有此条目,则在对象列表8上查寻object_id9。如果在步骤1320,存在对对象的依赖关系,则在步骤1325使高速缓存2被解锁;在步骤1327设置适当的状态变量;并在步骤1360将适当的状态变量回送给应用程序。如果在步骤1320没有找到对对象的依赖关系,则在步骤1330把一个object_id9添加到对该记录的对象列表8。如果需要,则为该记录创建新的散列表条目25及对象列表8。请注意,步骤1340能与步骤1330并发执行或在步骤1330之前执行。在步骤1350使高速缓存解锁,并在步骤1360将状态变量回送给应用程序。图10描述了delete_dependency(object_id,cache_id,record-id)440命令。如所描述的那样,在步骤1400,高速缓存管理器1确定由cache_id指定的高速缓存2是否有效。如果无效,则在步骤1402设置适当的状态变量并在步骤1460将状态变量回送给应用程序。在步骤1400,如果确认cache_id指定了一个有效的高速缓存,则在步骤1405使该高速缓存被锁住。在步骤1410,高速缓存管理器1通过检验目录3(图2)来查寻对应于object_id的对象6。如果在步骤1410未找到对象6,则在步骤1412使高速缓存2解锁;在步骤1415设置状态变量并在步骤1460将状态变量回送给应用程序。如果在步骤1410找到了对象6,则在步骤1420高速缓存管理器1检验记录到表11(图3),看对象6和由record_id指定的记录之间是否已经存在关联(即依赖关系信息)。另一种作法是,能确定对应于record_id的记录是否有散列表条目25,如果有,则在对象列表8上查寻object_id9。如果在步骤1420未找到依赖关系,则在步骤1422使高速缓存2解锁;在步骤1425设置适当的状态变量;并在步骤1460把适当的状态变量回送给应用程序。如果在步骤1420找到了对该对象的一个依赖关系,则在步骤1430对该记录从对象列表8中删除object_id9。如果这样做使得对象列表变为空表,则删除对于该记录的散列表条目25。在步骤1440,对于对象6,从记录列表11(图3)中删除record_id12。请注意,步骤1440能与步骤1430并发执行或在步骤1430之前执行。在步骤1450使高速缓存解锁并在步骤1460把状态变量回送给应用程序。图11描述了invalidate_record(cache_id,record_id)450命令的逻辑的一例。如所描述的那样,在步骤1500,高速缓存管理器1确定cache_id参数指定的高速缓存2是否有效。如果高速缓存无效,则在步骤1502设置适当的状态变量并在步骤1550将状态变量回送给应用程序。如果在步骤1500,高速缓存管理器1确定由cache_id参数指定的高速缓存是有效的,则在步骤1505使高速缓存2被锁住。在步骤1510,高速缓存管理器通过检查与record_id关联的记录是否有散列表条目25(图2)来确定是否有任何对象6的值依赖于该记录。如果对于该记录未找到散列表条目25,则在步骤1515使高速缓存解锁并在步骤1517设置状态变量。如果在步骤1510找到了对于该记录的散列表条目25,则在步骤1520高速缓存管理器1对该记录扫描对象列表8。在对象列表8中有对象ID9的每个对象6被从高速缓存中删除。由于每个对象9被删除,从其他对象列表8到对象6的所有访问关系也被删除。如果任何这种访问关系的删除导致任何空的对象列表的话,则相应的散列表条目25也被删除。在检验了与record_id12(对应于record_id参数)关联的对象列表8中的每个元素之后,该元素可被删除。在步骤1530,对该记录的散列表条目25被删除。在步骤1540高速缓存被解锁,并在步骤1550将状态变量回送给应用程序。本行专家会实现对invalidate_record函数的直接扩展,使其更新一个或多个依赖于record_id参数的对象,而不是使这些对象失效。步骤1099代表高速缓存管理器可能会处理的其他命令。本行专家将会理解,在本发明的范围和精神内有大量扩展和变体。例如,一个变体是允许高速缓存管理器1在对象6被高速缓存之前和在对象6已被从高速缓存中删除之后这两种场合保持和更新关于对象6的OIB10(图2)。利用这种做法,当对象6从高速缓存中被删除时,便不需要对于对象6删除记录列表11和从所有对象列表8中去掉对象6。以这种方式,当对象6不在高速缓存中时,依赖关系信息也能被保持甚至被更新。另一个变体是在任何对象添加到对象列表8之前和在对象列表8变空之后这两种情况下都允许高速缓存管理器1去维持和更新一个记录的散列表条目25。换句话说,即在高速缓存管理器获知对该记录的任何依赖关系之前和在对高速缓存管理器所获知的记录的所有依赖关系都变为过时之后。如果散列表条目25中除了记录ID12和对象列表8外还包括其他信息,则这种变体特别有价值。另一实施例图12a描述了具有本发明特点的系统的另一例。在本实施例以及前一个实施例中,本发明能用于在传统的客户机-服务器环境中改善服务器应用的性能。本行专家还能容易地使本发明适应于不基于客户机-服务器的其他应用。如所描述的那样,一个客户机-服务器结构,其中的客户机90通过网络95与服务器100通信。服务器100维持一个或多个高速缓冲存储器2’。如传统的那样,服务器100使用高速缓存2’来改善性能和减少为满足客户机请求所用的CPU时间。虽然图12显示的高速缓存2’关联于单个服务器,但高速缓存2’也能保持跨越多个服务器。在服务器100上运行的应用创建对象并把这些对象存储在一个或多个高速缓存2’上。该系统还能形成这样的结构,使数据库99中的底层数据与高速缓存2’在地理上分开。在本实施例中,对象是能被存于一个或多个高速缓存2’中的数据。这些对象能由存储在数据库99上的底层数据来构建。底层数据是系统中能影响一个或多个对象之值的所有数据。底层数据是系统中所有对象的超级集合。根据本发明,对象管理器120最好是作为明确地驻留在计算机可读介质中的计算机可执行代码(“程序”)来驻留供计算机(如服务器100或客户机90)上执行。对象管理器帮助确定底层数据的变化如何影响高速缓存2’中的对象之值。虽然图12a显示对象管理器驻留在单个服务器上,但它也可是分布于多个服务器上。对象管理器最好是一个长运行过程,用于管理一个或多个高速缓存2’的存器。“高速缓存”这个词是一个很通用的术语,除了高速缓存的传统意义外,还能包括任何应用(例如一个客户机90的应用)。本行专家能容易地使本发明适应用适用于下列之一的对象管理器1.多个分立过程,其中没有任何过程在时间上重叠;2.多个分立过程,其中有一些可能在时间上重叠。这包括如此设计的多重并发对象管理器以改善系统的吞吐能力。图12b描述了具有本发明特点的一个对象依赖关系图121的一例。对象依赖关系图121(简写为G)代表图对象gobj1…gobjn之间的数据依赖关系。这里gobj1,…,gobjn代表不同的图对象,而图中的边缘e代表数据依赖关系。例如,从gobj1到gobj5的边缘表明如果gobj1已经改变则gobj5也已经改变。边缘的权w指示一个对象(它是边缘的源)的改变对该边缘的靶标对象的影响程度如何。例如,gobj1的改变意味着gobj5中的改变要比由于gobj2的改变所造成的gobj5的改变显著得多。这是因为从gobj1到gobj5的边缘e的权w5倍于从gobj2到gobj5的边缘e的权w。对象管理器120负责维持底层数据结构,这些结构代表对象依赖关系图(见图12a-c及图16)。应用程序通过一组API(见图18a)把对象依赖关系图结构通告给对象管理器。该应用还利用API向对象管理器通告已经改变的底层数据。当对象管理器被告知底层数据改变时,它必须确定哪些其他对象已改变并把这些改变通告给高速缓存2’。它通过追循对象依赖关系图(见图21)中的边缘来确定哪些其他对象已经改变。例如,假定对象管理器120被告知gobj1已改变。通过追循对象依赖关系图121中从gobj1出发的边缘,它确定gobj5和gobj7也已改变。作为另一个例子,假定对象管理器被告知gobj7已改变。由于在对象依赖关系图中没有以gobj7为源的边缘,故对象管理器得出的结论是没有其他对象受到影响。图12c描述具有本发明特点的对象管理器120的一例。如图中所描述的那样,对象管理器120包括几个存储区域1.由多个依赖关系信息块(DIB)128实现的对象依赖关系图G121(见图12d)。本行专家将会理解,能用多种数据结构来存储DIB。最好是使用传统的散列表,这里的DIB由object_id(对象标识)160作为索引。例如,在“计算机算法的设计与分析”(Aho,Hopcroft,Ullman,Addison-Wesley,1974)一文中描述了散列表。2.多重记录树(MRT)122(见图27-28)。3.单个记录树(SRT)123(见图27-28)。4.辅助状态信息124,它包括但不限于下述内容a.num_updates125计数器num_updates125是由对象管理器维持的,用于跟踪对象管理器已经通过该图传播的更新的次数。b.一致性堆栈128.5用于在更新过程中保持一致性。c.关系信息129(见图27-28)。5.程序逻辑126。图13描述了由每个高速缓存127维持的存储区域的举例。每个高速缓存有一个标识它的cache_id135字段。有3个主要存储区1.目录130保持关于对象的信息。目录130包括多个对象信息块(OIB)10’。在对象离开高速缓存之后,关于该对象的信息可以保留在一个OIB10’中(图14)。本行专家将会理解,可以用多种数据结构存储OIB。最好是,使用传统的散列表,其中由object_id160作为OIB的索引。2.对象存储区132这里存储高速缓存中包含的对象。3.辅助状态信息包括其他状态信息,例如cache_id135。图14描述了OIB10’的一例。OIB最好包括如下内容object_id(对象标识)160为了下文的讨论,假定一个对象有一对象标识object_ido1;version_num(版本号)141允许对象管理器唯一地识别同一对象的不同版本;timestamp(时间标记)142用以指明该对象被计算出的时间距现在有多近的一个数;actual_weight(实际权)143从图对象o2到o1的所有边缘的权之和,用于使被高速缓存的o1版本与o2的当前版本一致;以及dep_list(依赖关系列表)144代表对对象o1依赖关系的列表。图15描述了dep_list144元素的举例。如所描述的那样,每个列表最好包括object_id160代表一个图对象o2,它有到o1的依赖关系边缘,即o2是源,而o1是靶标;weight_act(权作用数)152代表o2的最近版本与o1的被高速缓存版本的一致性程度的一个数。本最佳实施例使用值0(完全不一致)或依赖关系信息块(DIB)128中的相应边缘的权(见图16)(完全一致)。一种直接的扩展将允许使用这两个极值之间的数来代表不一致性程度;以及version_num(版本号)153与o1的被高速缓存版本相一致的o2版本号。图16描述了图12中依赖关系信息块(DIB)的一例。如所描述的那样,DIB128最好包括如下字段object_id(对象标识)160被应用程序用来识别图对象。为了下文中的讨论,假定一个图对象有一object_ido1;version_num(版本号)161该图对象的当前版本的版本号;timestamp(时间标记)162该图对象的当前版本的时间标记;storage_list(存储列表)163(用于是对象的图对象)包含该对象的所有高速缓存的cache_id(高速缓存标识)的列表;incoming_dep(进入依赖)164具有到o1的依赖关系边缘的所有图对象o2的(object_id160,weight165)对的列表。权165代表该依赖关系的重要性。例如,较大的数可代表更重要的依赖关系;outgoing_dep(发出依赖)166存在从o1出发的依赖关系边缘的所有object_id的列表;sum_weight(权之和)167进入o1的所有依赖关系边缘的权之和;threshold_weight(权阈值)168(用于是对象的图对象)代表何时一个对象应被认为是高度过时的对象的一个数。每当一个OIB10’(图14)中的actual_weight143落到底于该对象的threshold_weight字段时,该对象被认为是高度过时的并应使其从高速缓存中失效或更新。consistency_list(一致性列表)169(用于是对象的图对象)对应于那些必须与当前对象保持一致的其他对象的object_id160的列表。最好是,只在同一高速缓存中的对象之间实施一致性要求。一种直接的扩展会在多个高速缓存之间实施一致性要求。另一种直接扩展会是要求每当object_id进/出高速缓存时在列表169上的所有对象也要进/出该高速缓存;latest_object(最新对象)1601(用于是对象的图对象)指向对象最新版本的指针,如果对象管理器未得知这样的副本,则该指针为“空”(null)。这个字段允许一个对象在多个高速缓存中被更新而不必每次都重新计算它的值;relational_string(关系串)1602如果该图对象不是一个关系对象,则该字段为“空”。否则,该字段为如下形式SRO的relationname(关系名)(25,30)和MRO的relation_name(>=50)。如果relational_string1602非“空”,下列字段才是有关联的;multiple_records(多重记录)1603如果图对象是一多重记录对象(MRO)则为真,如果它是单记录对象(SRO)则为假;如果multiple_records1603为真,下列字段才是有关联的mro_depWeight(MRO依赖关系权重)1064赋予另一关系对于至o1的隐式依赖关系的权值;和mro_threshold_increment(MRO阈值增量)1605对于每个对o1的隐式依赖关系,threshold_weight应被加一增量。再参考图12,目标管理器最好也维持一个计数器num_updates(计数更新)125(初始化为零),它跟踪目标管理器通过该图传播的更新次数。目标管理器还维持一个称作一致性堆栈128.5(图12c)的数据结构(初始为空的),它用于保留高速缓存中各对象之间的一致性。应用程序97最好是通过一组API函数与对象管理器通信。图17描述了根据本发明的若干API举例。本行专家会理解,其他API也能实现,作为本发明的直接延伸。图18描述了处理不同API函数的目标管理器120逻辑的举例。总体上看,在对象依赖关系图G121中的节点能通过对对象管理器的API调用来建立create_node(obj_id,initial_version_num,thresh_weight)(建立节点)181。通过API调用能建立图中已有节点之间的依赖关系add_dependency(source_object_id,target_object_id,dep_weight)(增添依赖关系)182。通过API调用能设置对应于对象“obj_id”的依赖关系列表169define_consisfency_list(obj_id,listof_objects)(定义依赖关系)183。通过delete_node(obj_id)(删除节点)184这个API函数能从G图中删除节点。cache_latest_version(obj_id,cache)(高速缓存最新版本)185这个API函数向高速缓存添加一个对象的最新版本。copy_object(obj_id,to_cache_id,from_cache_id)(复制对象)186这个API函数试图从一个高速缓存向另一个高速缓存复制一个对象的一个版本。通过API调用delete_object(obj_id,cache)(删除对象)187从高速缓存中删除对象。改变底层数据值的应用程序必须通知对象管理器。用于实现这一点的两个API调用是object_has_changed(obj_id)(对象已改变)188,其中的obj_id参数指定一个图对象;以及objects_have_changed(list_of_objects)(若干对象已改变)189,其中的list_of_objects参数包括图对象(实际是指向图对象的指针)的列表。通过下述API调用能创建对应于一个SRO的节点create_sro_node(obj_id,initial_version_num,thresh_weight,relation_name,list_of_attribute_values)(建立SRO节点)190。通过下述API创建MRO:create_mro_node(obj_id,initial_version_num,thresh_weight,relation_name,list_of_attributeconditions,rel_default_weight,rel_default_threshold)(建立MRO节点)191。compare_object(obj_id,cache_id1,cache_id2)(比较对象)192这个API能用于确定在高速缓存cache_id1和高速缓存cache_id2中对象obj_id的版本的相似程度。update_cache(cache)(更新高速缓存)193这个API保证该高速缓存中的所有项目都是当前的。define_relation(relation_name,list_of_attributes)(定义关系)194这个API定义与对象管理器的关系。通过下述API能在一个或多个记录改变时通知对象管理器record_has_changed(relation_name,list_of_attribute_valuls)195(记录已改变)records_have_changed(relation_name,list_of_attribute_conditlions)196(若干记录已改变)。通过下述API调用创建对象依赖关系图G121中的节点create_node(obj_id,initial_version_num,thresh_weight)(创建节点)181。本行专家会理解,在本发明的精神和范围内能以直接方式实现许多其他API。例如,能增加API在已创建一个节点后来修改object_id_160,version_num161以及threshold_weight168各字段。通过下述API调用创建图中已存在节点之间的依赖关系add_dependency(soure_object_id,target_object_id,dep_weight)(增添依赖关系)182。本行专家会理解,在本发明的精神和范围内能以直接方式实现许多其他API。例如,还能增加API来删除依赖关系和修改依赖关系权。通过下述API设置对应于对象“obj_id”的一致性列表169:define_consistency_list(obj_id,list_of_objects)(定义一致性列表)183。obj_id的一致性列表最好不允许包括该obj_id作为一个成员。API防止发生这种情况。能在本发明的精神和范围内类似地添加API以在一致性列表169创建之后修改它们。当一个对象已被高速缓存之后,一个对象的依赖关系信息块(DIB)128(图16)的变化可能需要更新一个或多个高速缓存127。这是直接了当的事。在从一个新的图对象o2对一被高速缓存的对象o1的一个新的依赖关系的情况中,如果目标管理器不知道o2是何时被创建的或者o2的DIB时标162>o1的DIB时标142,则这个新的依赖关系是过时的。通过delete_node(obj_id)(删除节点)184这个API能把节点删除。通过下述API能明确地向高速缓存添加对象cache_latest_version(obj_id,cache)(高速缓存最新版本)185;copy_object(obj_id,to_cache_id,from_cache_id)(复制对象)186。这些API在高速缓存目录中创建新的OIB135,如果对于该对象还不存在OIB的话。图19描述API函数cache_latest_version(obj_id,cache)185的举例。如所描述的那样,在步骤2030,确认参数obj_id和cache分别指定已存在的对象和高速缓存。如果是这样的话,处理进入步骤2040。如果不是这样,则回送适当的状态信息,处理进入步骤2010。在步骤2040,确定一个对象的最新版本是否在该高速缓存中。如果是,处理继续步骤2010。如果不是,则在步骤2050试图从依赖关系信息块(DIB)128(图16)中的latest_object字段1601中得到obj_id的最新版本。如果该字段为空,则在步骤2050计算obj_id的最新值(还可能通过DIB的latest_object字段1601使它能被访问),并更新依赖关系信息块(DIB)128中的version_num字段161。在步骤2050,或者完全重新计算obj_id的新版本,或者只计算其若干部分并使新的部分与已存在的版本的部分合并。后一种方法往往比前一种方法更有效。在高速缓存的目录130中为obj_id创建一个OIB10’,如果它尚不存在的话。如果该高速缓存先前不包含obj_id的任何版本,则该高速缓存被添加到obj_id的存储列表163。OIB10’(图14)的version_num141和timestamp142字段被设置成依赖关系块(DIB)128(图16)的version_num161和timestamp162字段。OIB10’(图14)的actual_weight字段143被设置成该DIB的sum_weight字段167。对于属于OIB10’(图14)的dep-list144的每个(o2,weight_act,version_num)三元组,weight_act152被设置成DIB的incoming_dep164上的相应边缘的weight165。version_num153被设置成o2的DIB中包含的version_num161字段。在步骤2060,保证保持了一致性。这一函数递归地确保,每当obj2的0IB10’中的时标142处在obj_id的DIB128的时标162之前时,obj_id的一致性列表169上所有非当前对象obj2被更新或被令其无效。如果在这一过程中任何这种对象obj2被更新,则类似步骤递归地应用于每个所述obj2的一致性列表169。步骤2050和2060的顺序对于本实施例的正确性并不重要。图20描述API函数copy_object(obj_id,to_cache_id,from_cache_id)186的举例。如所描述的那样,在步骤2100确认参数obj_id、to_cache_id及from_cache_id都被对象管理器识别出来。如果是,在步骤2110确定from_cache_id是否有obj_id的一个副本。如果不是,则什么事也不发生,处理进入步骤2010。对此(以及其他情况)设置适当的状态变量并将其回送给应用程序以指出发生了什么事。否则,处理继续步骤2120,在那里确定to_cache_id和from_cache_id是否包括obj_id的完全相同的版本。如果是,则不需进行复制,于是处理继续进入步骤2010。否则,步骤2130确定是否from_cache_id包含obj_id的最新版本。如果是,则在步骤2140,该对象被复制到to_cache_id的对象存储区132,而且高速缓存目录130被更新。obj_id的一个OIB10’被创建在to_cache_id的目录130中,如果它尚不存在的话。如果to_cache_id先前不包含obj_id的任何版本,则to_cache_id被添加到obj_id的存储列表163。在步骤2170,通过确保在一致性列表169上OIB时标142先于obj_id的DIB时标的所有非当前对象或被更新或被令其无效,以此来保持一致性。否则,如果步骤2130的结果是否定的,则在步骤2150该对象不被允许复制,除非(1)在obj_id的一致性列表169上的其非当前版本被存于to_cache_id的所有对象所具有的时标142与from_cache_id中的obj_id版本的时标142相同;以及(2)在obj_id的一致性列表169上的其当前版本被存于to_cache_id的所有对象所具有的时标142与from_cache_id中的obj_id版本的时标142相同或在其之前。如果这些条件被满足,则在步骤2160,obj_id被从from_cache_id复制到to_cache_id。在to_cache_id的目录130中创建obj_id的OIB10’,如果它尚不存在的话。如果to_cache_id先前不包含obj_id的任何版本,则to_cache_id被添加到obj_id的存储列表163。对API函数copy_object和cache_latest_version的直接扩充是加上若干标志,如果在一致性列表上的其他对象也需要被更新的话,这些标志能防止一个对象被存储。另一个直接扩充是另一些标志,如果一个高速缓存未曾包括object_id的任何版本的话,则只把该object_id存入该高速缓存。另一直接扩充是一个系统,那里的对象管理器维持一个对象的所有先前版本。于是,我们会有API函数用于向一个高速缓存添加由具体的一对参数(object_id,version_num)所标识的特定对象。通过API调用delete_object(obj_id,cache)(删除对象)187能从一高速缓存中删除对象。本行专家会理解,根据这里的描述实现这一函数是直接了当的。由这一API完成的一个功能的举例是对于由obj_id标识出的对象,从依赖关系信息块(OIB)128(图16)的storage_list字段163中去掉高速缓存cache。改变底层数据值的应用程序必须通知对象管理器。实现这一点的两个API是object_has_changed(obj_id)(对象已改变)188,这里obj_id参数标识一个图对象;以及objects_have-changed(list_of_objects)(若干对象已改变)189,这里的list_of_objects参数包括图对象(的指针)的列表。如果经常有list_of_objects上的图对象影响许多其他图对象的情况,则API函数objects_have_changed将对比列表上的每个图对象都调用一次API函数object_has_changed更有效。图21描述API函数objects_have_changed(listvof_objects)189的举例。本行专家会理解,再实现API函数object_has_changed(obj_id)是直接了当的。为便于解释,我们假定list_of_objects的每个元素对应于G中的一个有效节点,而且在list_of_objects上没有任何两个元素代表同一节点。根据这里的详细描述能直接地使这一函数适应于不是这里所假定情况的场合。如所描述的那样,在步骤2400使计数器num_updates125(图12c)加1。在步骤2402,确定与list_of_objects参数所指定的图对象对应的所有节点是否都已被访问(visit)过。如果是,则在步骤2403跟随进行更新传播阶段(见图22),在步骤2404跟随进行一致性检验阶段(见图26)。如果不是,则在步骤2405,对应于list_of_objects上一个图对象的一个新节点被访问。令obj_id是该节点的object_id。对象管理器把obj_id的依赖关系信息块(DIB)128中的version_num字段增量1,并把时间标记字段162设置成num_up_dates125之值。步骤2406和2408表示一个循环,它通知包含obj_id的每个高速缓存C1(从存储列表163中得到)去更新obj_id的版本或令其无效。在步骤2406,调用函数update_or_invalidate(c1,obj_id)(更新或令其无效)(见图25)来使更新obj_id的版本或令其无效这件事实际发生。本行专家会理解,在步骤2406中应用选择来确定哪些高速缓存必须更新它们的obj_id副本或令其无效,这是可以直接了当地实现的。图25描述了update_or_invalidate(cacheid,objectid)逻辑的举例。每当当前在cacheid中的objectid版本必须被更新或被令其无效(例如见图21的步骤2406)时,该函数便被调用。如所描述的那样,在步骤2407确定在cacheid中是否应更新objectid。如果回答是“不”,则在步骤2440从该高速缓存中取消objectid并在步骤2441该过程返回。如果回答是“是”,则在步骤2442进行对objectid的OIB10’(图14)下列改变1.versionnum141和timestamp142字段被设置成依赖关系信息块(DIB)128(图16)中包含的当前version_num161和timestamp162。2.actual_weight字段143被设置成DIB中的sum_weight字段167。3.dep_list144(图15)被更新。列表144中的每个成员对应于一个图对象o2,该对象与objectid标识的对象有一个依赖关系。weight_act152被设置成与G中同一边缘相对应的依赖关系信息块(DIB)128(图16)中的weight(权)165字段,如果这两个量不同的话。此外,version_num153被设置成o2的DIB中包含的version_num字段161,如果这两个量不同的话。在步骤2444,在对象存储区132中包含的objectid实际值被更新。首先,试图从依赖关系信息块(DIB)128(图16)中的latest_object字段1601中得到objectid的被更新版本。如果这一尝试成功了,则步骤2444结束。如果这失败了(即这个指针为空),则计算出objectid的被更新版本,例如可完全地计算objectid的新版本,也可只重新计算其若干部分再把这新的部分与已有版本中的部分合并。在任何一种情况下,对象管理器都可以选择更新DIB中的latest_object字段,从而使可能需要objectid最新版本的其他高速缓存能简单地复制它而不必重新计算它。在某些情况中,在步骤2444,objectid的实际值能用objectid的较新版本更新,它最好是最新的一个易于访问的版本(它通常会是以最高的version_num141高速缓存的版本),但它不是实际的当前版本。如果计算objectid的当前值是无法容忍地昂贵的话,这样做是有好处的。最好是,在下列条件之一成立的情况下不允许这种类型的更新1.objectid是已传送给函数objects_have_changed(list_of_objects)的列表上的对象之一;或2.对于objectid的较新版本,仍然是actual_weight143<threshold_weight168的情况。在步骤2443,(object_id160,cacheid)对被添加到consistency_list169上的每个对象(它是在cacheid标识的高速缓存中)的一致性堆栈128.5(图12)。对象管理器120在一致性检验阶段(图26)确保一致性堆栈128.5上的所有被高速缓存的项目都是一致的。能以几种方式实现一致性堆栈;两种可能的结构是列表和平衡树(参考Aho,Hopcroft,Ullman)。列表的优点是插入为恒定时间。其缺点是在列表上会出现项目的重复副本。平衡树的优点是不需存储重复项目。缺点是插入是O(leg(n)),这里n是一致性堆栈上的项目数。步骤2443可以在把一对象添加到一致性堆栈之前任意地增加更多的选择性。令object_id2是在cacheid中的一致性列表169上的一个对象。如果cacheid包含object_id2的一个当前版本,则(object_id2,cacheid)不必被添加到一致性堆栈。如果以下两个条件都成立,则该版本是当前版本1.在处理对函数objects_have_changed(list_of_objects)189的当前调用中已经访问过对应于object_id2的顶点。这是当且仅当对象object_id2的依赖关系信息块(DIB)128(图16)中的时间标记timestamp字段162等于num_updates125时才成立的;以及2.对于对象object_id2,在OIB10’(图14)中的version_num字段141和DIB中的161相同。如果在步骤2443中确定(1)和(2)都成立,则(object_id2,cacheid)不被添加到一致性堆栈。如果(1)成立而(2)不成立,步骤2443能递归地调用关于object_id2和cacheid的函数update_or_invelidate,这能使得不需要把(object_id2,cache_id)添加到一致性堆栈。本行专家能根据这里的描述容易地以任何顺序或并行地实现步骤2442、2443及2444。图22描述了函数objects_have_changed(list_of_objects)189的更新传播阶段。由步骤2403和2416完成的基本功能是遍历能从list_of_objects访问的图G的所有边缘。最好采用的技术与“深度优先搜索”(参考Aho,Hopcroft,Ullman)类似。然而,本行专家能容易地使该技术适于与其他图形遍历方法(如“宽度优先搜索”)一起工作。图23描述了响应底层数据变化通过对象依赖关系图以“深度优先搜索”(dfs)传播变化的一种方法的一部分。假定从第一节点obj1到第二节点obj2的一个边缘刚刚被遍历过。在步骤2416确定节点obj2是否已被访问过。当且仅当obj2的时间标志162(图16)=num_updates125(图12)时回答为“是”。如果步骤2416的结果为“真”,处理继续到步骤2417。这一步骤是一个循环的一部分,在此地对storage_list163(图16)上的所有高速缓存进行检查,看它们是否包括obj2的副本。请注意,每个对象最好有一个object_id字段和一个version_number字段。object_id字段对应于一个能由应用程序用来识别该对象的东西(例如URL),而version_number字段允许维持具有同一object_id的多重对象并使它们唯一地被标识出来。对于每个这样的高速缓存cacheid,在步骤2420通过比较OIB10’(图14)中的version_num字段141和依赖关系信息块(DIB)128(图16)中的version_num字段161来确定obj2的版本是否是当前版本。如果步骤2420的结果是肯定的,则在步骤2421确保在obj2的dep_list144上对应于obj1的元素有version_num153等于obj1的DIB中的version_num161。如果步骤2420的结果是否定的,即obj2的版本不是当前版本,则函数decrease_weight(cacheid,obj1,obj2)(减权)被调用(见图24)。请回想一下,每个边缘能伴有一个非负数称作权,它代表该数据依赖关系的重要性。例如,大数能代表重要的依赖关系,而小的数代表不重要的依赖关系。还请回忆一下,对象还能伴有一个值称作threshold_weight(权阈值)。每当对应于当前输入的数据依赖关系的权之和落在threshold_weight之下时,该对象便被认为是高度过时的。对于需要对象新近版本的应用,这些对象应被更新或令其失效。如果步骤2416的结果是“假”,则在步骤2423,obj2的version_num字段被加一增量,并设时间标记timestamp字段162为num_updates125(图12),它表明obj2已被访问过。步骤2424是一个循环的一部分,那里检验storage_list163上的所有高速缓存,看它们是否包括obj2的一个副本。对于每个这种高速缓存cacheid,在步骤2425,函数decrease_weight(cacheid,obj1,obj2)被调用。在退出该循环后,在步骤2426,对于所有从obj2出发的边缘递归调用dfs逻辑(图23)。图24描述decrease_weight(cacheid,from_obj,to_obj)(减权)逻辑的举例。如所描述的那样,在步骤2425,对象to_obj的实际权actual_wieght字段被减去w,这里w是对应于从from_obj到to_obj的边缘的weight_act字段152。在步骤2435,确定是否actual_weight143<threshold_weight168;如果回答为“是”,则函数update_or_invalidate(cacheid,to_obj)被调用。如果回答为“否”,则在步骤2436,对应于从from_obj到to_obj的边缘的weight_act字段152被设为零。在更新传播阶段之后,对象管理器必须保证consistency_lists169在事实上是一致的。这是在图26中描述的一致性校验阶段进行的。如所描述的那样,步骤2404是一个循环的一部分,它检验一致性堆栈128.5(图12c)中的每个(object_id_160,cache_id135)对。对每个这样的对子,在步骤2451,通过比较version_uum字段141和version_num字段161,来检验高速缓存cache_id中的object_id版本是否是当前版本。如果回答为“是”,处理返回步骤2404。否则,该对象必须被更新或被令其无效。在步骤2455,确定该对象是否应被更新。如果回答为“否”,则在前述步骤2440中(见图25)该对象被令其无效。如果回答为“是”,则在步骤2050将最新值添入高速缓存,并在步骤2060使新的一制性约束得到满足(这两点在前面都描述过,见图19)。对于本例的正确性,步骤2050和2060的顺序无关紧要。另一个API函数update_cache(cache)(更新高速缓存)193保证高速缓存中的所有项目都是当前的。这是通过检验高速缓存中每个对象的OIB,并对过时的项目令其无效或进行更新来实现的。它忽略了一致性列表,因为所有对象都将是当前的,所以在完成该函数之后它们必须是一致的。关系本发明在处理记录(这些“记录”与最佳实施例中所用“记录”不是同义词)方面有特别之处,这些记录可以是一个关系数据库的一部分(见J.Melton和A.R.Simon,MorganKaufmann的“理解新SQL一个完全的指南”,1993)。例如,假定一个关系rel_name有属性age和weight,二者都是整型。在下文中,rel_name(age=25,weight=34)代表一单个记录,而rel_name(age=25)则是一个多重记录指示符(MRS)并代表属于age=25的rel_name的所有记录。本发明的特点是允许管理对应于或者单个或者多重记录的对象。这种对象称作关系对象。一个单一对象能代表来自同一关系的多重记录。这样一个对象称作多重记录对象(MRO),而对应于单个记录的对象称作单记录对象(SRO)。如果对应于关系对象obj2的记录集是对应于一个MROobj1的记录集的子集,则称MROobj1包含(包括)另一个关系对象obj2。对象管理器自动地把依赖关系从一个关系对象添加到包含它的一个MRO中对象管理器维持一个平衡树,称作多重记录树(MRT)122,它包含指向G中所有MRO节点的指针,并被依赖关系信息块(DIB)128(图16)中的关系串relational_string字段1602按字母顺序编排索引。称作单关系树(SRT)的平衡树包含指向G中所有SRO节点的指针,而且也被DIB中的关系串relational_string字段1602编排索引。根据这里的描述不难实现的另一种途径是对单个关系和多重关系二者维持单一的平衡树。另一个变体将是利用数据结构而不是用平衡树来维持这一信息。根据本发明,在创造一个关系对象之前,必须通过API函数define_relation(relation_name,list_of_attributes)(定义关系)194,使对象管理器标识出这个关系。list_of_attributes(属性列表)这个参数的每个元素是包含该属性名字和类型的一对。API函数define_relation194把关于关系的信息存于关系信息区129(图12)。图27描述创造对应于单记录对象(SRO)的一个节点的逻辑的举例。请回想一下,对应于单个记录的一个对象称作单记录对象(SRO)。称作单关系树(SRT)的平衡树包含指向G中所有SRO节点的指针,而且也被DIB(图16)中的relational_string字段1602按字母顺序安排索引。通过API函数create_sro_node(obj_id,initial_version_num,thresh_weight,relation_name,list_of-attribute_values)(创建SRO节点)190(图18a)来创造对应于一个SRO的节点。现在参考图27,在步骤2300确定是否所有输入参数都有效(例如,它们有正确地类型等)。还通过检验关系信息区129来确认关系“relation_name”先前曾通过调用define_relation194定义过。还要确认list_of_attributes包含值的个数正确而且所有值的类型正确。还要确认obj_id的一个节点或对应于这同一记录的节点并非已经存在(不难修改设计,从而当obj_id的一个节点已经存在时,该旧的节点将被重写)。还不难修改设计,使能存在具有同一obj_id的多重节点。还不难允许多重节点对应于同一记录。如果确定所有参数都有效,处理继续到步骤2305。否则,在步骤2320,create_sro_node函数返回,并回送适当的状态信息。在步骤2305,通过把object_id160初始化成obj_id,把version_num161初始化成initial_version_num,把threshold_weight168初始化成thresh_weight,把relational_string1602初始化成与所有属性值相联系的relation_name来创建G中的新节点。构成relational_string1602的关系和属性值最好都由分隔符分开。这样,便能容易地从relational_string1602中识别出关系和每个属性值。一个多重记录multiple_recorols_1603字段被设为“假”。在步骤2310,指向该节点的一个指针被添加到SRT。由relational_string1602确定STR中该新指针的位置。在步骤2315,依赖关系从obj_id添加到包含该对象的每个多重记录对象(MRO)。通过检验多重记录树MRT122,可找到这些MR0。MRT最好是包含指向G中所有MRO节点的指针的一个平衡树,并由依赖关系信息块(DIB)128(图16)中的relational_string字段1602按字母顺序编排索引。只需要对于relation_name来检验MRO。所有这种MRO都能在O(log(n)+m)条指令中识别出来,这里n是MRO的总数,m是对于relation_name的MRO个数。对于每个包含obj_id的MRO“obj2_id”,建立一个从obj_id到obj2_id的依赖关系。再参考图16,该依赖关系最好以obj2_id的mro_dep_weight1604的权来初始化。obj2_id的threshold_weight168被obj2_id的mro_threshold_increment1605来增量。对本算法的直接扩展将是使用其他技术对依赖关系赋予权和修改threshold_weight168。现在回到图27,在步骤2320,该过程带着状态信息返回。步骤2305、2310和2315的顺序能被改变。再有,这些步骤可并发执行。图28描述了创建多重记录对象(MRO)的逻辑的举例。MRO是通过下列API函数创建的create_mro_node(obj_id,initial_versionnum,thresh_weight,relation_name,list_of_attribute_conditions,rel_default_weight,rel_default_threshold)(创建MRO节点)191(图18a);属性条件是如下形式=25;>96;>45及<100;等。属性条件也可以是“空”,意思是对属性值没有任何限制。请回想一下,单一对象能代表来自同一关系的多个记录。这样的对象称作多重记录对象(MRO),而对应于单个记录的对象称作单记录对象(SRO)。一个MRO对象obj1包含另一关系对象obj2,如果对应于obj2的记录集是对应于obj1的记录集的子集的话。对象管理器自动地把依赖关系从一关系对象添加到包含它的MRO。对象管理器最好还维持一个称作多重记录树(MRT)122的平衡树,它包含指向G中所有MRO节点的指针,并由依赖关系信息块(DIB)128(图16)中的relational_string字段1602按字母顺序编排索引。称作单关系树(SRT)的平衡树包含指向G中所有SRO节点的指针,并且也由依赖关系信息块(DIB)中的relational_string字段1602按字母顺序编排索引。如所描述的那样,在步骤2600,确定是否输入参数全部有效(例如它们有正确的类型等)。此外,还通过检验关系信息存储区129(图12)来验证先前曾通过调用define_relation194API(图18a)定义过关系“relation_name”。还验证list_of_attribute_conditions(属性条件列表)是有效的;以及obj_id节点或对应于同一个记录集的节点尚没有存在。本行专家将会理解,不难修改设计,从而当obj_id的节点已经存在时,该老节点会被重写。还不难修改设计,从而使具有相同obj_id的多重节点能够存在。还不难允许多重节点对应于同一个记录集。如果步骤2600的结果是确定所有参数有效,则处理继续到步骤2605。否则,在步骤2620,create_mro_node带着适当的状态信息返回。在步骤2605(还参考图16),通过把object_id160初始化成obj_id,把version_num161初始化成initial_version_num,把treshold_weight168初始化成thresh_weight,以及把relational_string1602初始化成与所有属性状态相联系的relation_name,使在G中创建一个新节点。构成relational_string1602的关系和属性条件都由分隔符分开。这样,便能容易地从relational_string1602中识别出关系及每个属性条件。multiple_records1603字段被设为“真”;mro_dep_weight1604被设为rel_default_weight;以及mro_threshold_increment_1605被设为rel_default_threshold。在步骤2610,一个指向该节点的指针被添加到MRT。该新指针在MRT中的位置由reldtional_string1602确定。在步骤2615,以步骤2315同样的方式把依赖关系从obj_id添加到包含它的每个MRO。对于每个obj_id中包括对象obj2_id,在步骤2625把一个依赖关系从obj2_id添加到obj_id。通过搜索MRT122和SRT123并考虑对于relation_name的所有其他关系对象,由此来找出这种依赖对象。对于对象obj_id,每个依赖关系被予权mro_dep_weight1604。对于每个这样的依赖关系,对obj_id的threshold_weight168被增加一个增量,该增量是对obj_id的mro_threshold_increment1605。本行专家将会理解,其他技术也能用来对依赖关系赋予权,并修改threshold_weight168。在步骤2620,create_mro_node带着状态信息返回。步骤2605、2610、2615和2625的顺序可以改变。再有,这些步骤可以并发执行。另一种做法是,关系对象obj1对包含它的MROobj2的依赖关系的权可以以obj2相对应的也被包含在obj1中的记录所占的比例和重要性为基础。这一变体能被应用到步骤2315、2615或2625。如果两个MRO中任何一个都不是另一个的子集,但这两个MRO有一个或多个记录是共同的,在这种情况下的另一种作法可以是有选择地在两个MRO之间添加依赖关系。现在回到图16,本行专家将会理解,在本发明的精神和范围内,能增加API,以便在通过API函数create_sro_node190或create_mro_node191定义过一个关系对象之后能对它修改relational_string1602、multiple_records1603、mro_dep_weight1604、及mro_threshold_increment1605。当一个或多个记录改变时,对象管理器能通过以下API函数(图18a)得到通知record_has_changed(relation_name,list_of_attributevalues)195及records_have_changed(relation_name,list_of_attributeconditions)196。这些API自动地在整个依赖关系结构中传播这种改变。图29a描述了如何实现API函数records_have_changed(relation_name,list_of_attribute_conditions)(若干记录已改变)196。本行专家将会理解,由此来实现record_has_changed(relation_name,list_of_attribute_values)(一个记录已改变)是直接了当的。如所描述的那样,在步骤2700确定输入参数是否有效。还要通过检验关系信息区129(图12)来验证关系relation_name是否先前曾被定义过(通过调用define_relationAPI(图18a))。还要验证list_of_attribute_conditions是有效的。如果输入参数有效,处理进入步骤2710。否则,在步骤2730,该过程带着适当的参数信息被终止。在步骤2710,找出包括至少一个已改变的记录的所有关系对象。这可以通过检验对应于relation_name的MRT122和SRT123(图12)上的所有关系对象来完成。在步骤2720,通过在步骤2710中识别出的所有对象的列表上调用API函数objects_have_changed189,能使这个改变向G中的其他节点传播。最后,在步骤2730,records_have_changed返回一个适当的状态信息。API函数records_have_changed的一个直接的变体是在确定如何在整个G中传播改变信息时,考虑一个关系对象中已经已改变的记录所占的比例和重要性。API函数compare_objects(obj_id,cache_id1,cache_id2)(比较对象)192(图18b)能被用来确定对象obj_id在cache_id1和cache_id2这两个高速缓存中的版本的彼此相似程度。例如,能比较version_num141字段来检验这两个版本是否相同。如果它们是不同的,由可借助例如version_num141和timestamp142字段(图14)之差来指出一个对象比另一个对象的新近程度。如果对象的两个版本不同,则能计算出一个相似度评分,取值范围是0(最不相似)到<1(1对应于该对象的完全相同版本)。相似度评分最好是基于从图对象obj_id2到obj_id的到来依赖关系的权之和,对于对象obj_id2,与cache_id1中的obj_id一致的obj_id2版本和与cache_id2中的obj_id一致的obj_id2版本完全相同。相似度评分(SS)能用如下公式SS=common_weight/sum_weight167,这里common_weight=与从图对象obj_id2到ojb_id的边缘相对应的权165之和,这里与边缘对应的version_num153字段对于obj_id的两个版本是完全相同的。compare_objects(比较对象)逻辑也能被用来确定两个版本是否高度地不相似。当且仅当common_weight<threshold_weight时才认为它们是高度不相似的。扩展对本发明的一个直接扩展是在OIB(图14)中包括threshold_weight字段,并让高速缓存2’(图13)独立地设置这些字段。另一个直接扩展是允许对同一对象有对应于不同高速缓存的不同的一致性列表。另一个扩展是这样一个系统,那里会存在从图对象obj1到另一图对象obj2的多重依赖关系,而且这些依赖关系具有不同的权。应用程序能独立地修改这些多重依赖关系。另一个扩展是使用其他算法根据到一对象的过时链接来确定何时该对象是过时的。当一个图对象改变时,本最佳实施例在通过依赖关系图G传播该信息时并不考虑该图对象是如何改变的。它只考虑这样的事实,即该图对象已经改变。一个扩展将是还考虑一个图对象是如何改变的,以便把这种改变传播给其他图对象。这可按下述方式完成1.通过参数向object_has_changed之类函数提供关于一个图对象已经如何改变的附加信息。这个信息将被用于修改从该图对象到依赖于它的值的其他图对象的链接,并在其后被用于确定该图对象的后继者们已经如何改变。2.当对象管理器120确定一个图对象o2已经改变时,该对象管理器能考虑两点它的哪些前趋已经改变;以及它递归地收集的关于前趋已经如何改变的任何信息。然后,对象管理器将使用这一信息确定o2是如何改变的。关于o2如何改变的信息将被用于修改到依赖于o2的其他图对象的链接,还将被用于确定对o2的继承者已如何改变。例如,考虑图29b。u2和u3是已经改变的底层数据。对象管理器把改变信息传播给o1和o3。当对象管理器把改变信息传播给o2时,在确定如何更新o2的被高速缓存的副本或如何令其无效的时候,它不仅考虑从o1和o3到o2的边缘的权,它还考虑u2、u3、o1和o3的改变的性质。这一信息也被用于确定如何更新o4的被高速缓存版本或如何令其无效。其他应用本发明还能被用于这样的系统,那里一个应用程序要决定是否要更新底层数据。通过检验对象依赖关系图,系统能确定受底层数据改变影响的其他对象。如果这一设定是令人满意的,则将进行改变。否则,系统将从“改变底层数据”这一操作中退出来。本行专家将会理解,本发明还能被编译器、运行时系统或数据库使用,以便有效地对操作安排时间表。不同的操作时间表会对底层数据造成不同的改变。通过检验对象依赖关系图,作时间表决定的程序能确定一个最有利的方法来对操作安排时间表。维护和一致性地更新高速缓存的可伸缩方法的详细描述本发明的这一实施例是设计成在由网络连接的一个或多个物理(计算机)系统的集合上实现其功能。在这个系统集合中可以驻留本发明的一个以上的实现。为了指导区分本发明的多个实例(instance),虽然可以使用字典,但还是提供了如下的定义对象源(objectsources)。对象源包括一个或多个产品,如IBM以DB2为商标销售的产品,Lotus(莲花公司)以LOTUSNOTES和DOMINO服务器为商标销售的产品,或者其他源3030,包括用于建立更复杂对象(如HTML页面)的数据或对象。触发器(trigger)。能用来响应数据的修改而使得动作自动发生的任何手段。触发器是许多标准性对象源的一个标准特征,这些标准对象源诸如IBM以DB2为商标销售的产品,Lotus以LOTUSNOTES和DOMINO服务器为商标销售的产品,都能响应数据的修改而自动地使动作发生。本发明的一个实施例以一种新的方式使用触发器以保持一对象源中存储的由数据建立的对象与数据同步。触发通告(triggernotification)。这是响应一对象源中被调用的触发器而向本发明发送的消息。高速缓存事务(cachetransactions)。包括对高速缓存管理器提出的读、更新、或删除高速缓存对象的请求。触发监视器(triggermonitor)。这是根据本发明的用于保持高速缓存管理器管理的高速缓存中的对象与相关联的远程数据同步的逻辑的一例。触发监视器可以是一个监视远程数据源的单个长运行过程,用于使高速缓存管理器管理的高速缓存中存储的复杂对象与底层数据保持一致。主触发监视器(mastertriggermonitor)。这是触发监视器的一个实例,它接收触发通告。从属触发监视器(slavetriggermonitor)。这是触发监视器的一个实例,触发通告从主触发监视器3000’传送给它(即不是直接从对象源传送)。本机高速缓存(localcache)。这是一个由驻留在高速缓存本身所在的同一物理机器上的触发监视器的一个实例来进行更新的高速缓存(或其他标准对象存储器,如一个文件系统)。远程高速缓存(remotecache)。这是一个由驻留在与高速缓存本身不同的物理机器上的触发监视器的一个实例来进行更新的高速缓存(或其他标准对象存储器,如一个文件系统)。由本发明担任主触发监视器3000(如果它接受触发事件)和从属触发监视器3000a(如果它从某一主触发监视器接受触发事件通告)的双重角色。现在参考图件,图30a描述了具有本发明特点的系统的方框图举例。如所描述的那样,该系统包括(一个或多个)远程节点3108。节点3108可以是通过万维网服务器(表示为httpd3080)向客户机提供万维网页的服务器。每个万维网服务器能提供大百分比的由数据库3010构建的动态万维网页。由于产生万维网页所涉及的费用,每个这种服务器节点100高速缓存一个或多个对象3004,包括复杂对象,例如动态万维网页。对同一动态网页的多重请求能由高速缓存3003满足,从而降低开销。使用多重服务器节点3108增大了系统能服务的请求量。服务器节点3108在地理上被远距离分开,这是可能的,虽然这不是一种要求。根据本发明,当一个对象源(如数据库)3010发生改变而这种改变会影响高速缓存3003中存储的一个或多个对象3004之值时,触发监视器3000向对象的每个高速缓存管理器3001通告哪些对象的值已改变。触发监视器3000可能会通知高速缓存管理器3001在它的高速缓存3003中的对象3004已改变。在这种情况中,高速缓存管理器3001会使对象3004的副本无效。另一种情况是,触发监视器3000可能会通知高速缓存管理器3001对象3004已改变而且还提供对象3004的新值。本行专家会理解,对象3004的新值可在数据服务器节点3102以及远程节点3108或某个中间节点(例如代理(proxy)节点)被计算出来。在这另一种情况的每种情形中,高速缓存管理器还会选择动态更新对象3004(例如存储新版本)而不是令其无效。图30b描述了触发监视器3000的一个更详细的举例。这里,触发监视器3000被作为主触发监视器3000’的具体实例。如所描述的那样,对包括复杂对象3004的高速缓存3003的维护是由根据本发明称作触发监视器3000的这个过程(或过程集合)来完成的。触发监视器3000最好是单个长运行过程,它监视数据源3050以使高速缓存管理器3001的内容与底层数据同步。主触发监视器3000’是触发监视器3000的一个实例,它接受触发事件3020。主触发监视器3000’包括触发监视器驱动器3040;对象标识(id)分析逻辑3041;对象发生器逻辑3042;以及分布管理器3043。主触发监视器3000’与对象源3050、高速缓存管理器3001(称作本机高速缓存管理器)以及零个或多个其他(从属)触发监视器3000”(图30c)和一个远程高速缓存管理器3002,这些驻留在其他物理机器上。对象源3050包括一个或多个实体;例如数据库3010(如由IBM以DB2商标销售的);或任何其他源3030(如由Lotus公司以DOMINO商标销售的),由这些源建造了更复杂的源(如HTML页面)。当对象源3050检测到一个改变时,一个触发器被调用。该触发器(它是许多标准对象源3050(如前述)的标准特征)通常被用于响应修改数据而自动产生行动。本发明以一种新的方式使用触发器来保持由对象源中存储的数据建造的对象3004与数据同步。伴随该触发器的是一个send_trigger(发送触发器)3026API(见图30d),它使一消息送到触发监视器驱动器3040。于是触发监视器驱动器能响应这一消息而产生一个称作触发事件3020的事务(见图30e)。触发事件3020能被翻译(按传统意义)成记录ID(标识)3012并传送给高速缓存管理器3001供翻译。高速缓存管理器3001返回一个相应的对象ID列表3009,它被排队到对象ID分析(OIA)部分3041。OIA3041用已知手段产生一组对象分配块(ODB)3100(下文中描述),每个对象ID3009有一个。图31描述对象分配块(ODB)3100的举例。对象ID3009被用于当其后代替或删除对象时识别高速缓存3003中的对象3004。高速缓存ID3200被用于识别对象3004属于哪个高速缓存3003。外部ID3101是一个附加标识,对象发生器3042会借助它识别对象。请求分配3103被对象发生器用于产生“更新对象请求”3022或“删除远程对象请求”3025(图30e)。如果请求分配3103是DispRegenerate(分配再生)3130,由ODB3100代表的对象3004由系统再生并被分布出去。如果请求分配3103是DispInvalidate(分配无效)3131,则对象3004被从所有系统中删除。图32描述高速缓存ID3200的举例。如所描述的那样,高速缓存ID最好包括高速缓存名3201、高速缓存主机3202标识以及高速缓存端口3203标识。现在回到图30b,ODB3100被送到对象发生器3042。对象发生器检验ODB3100并完成下列两项之一a)产生一个删除远程对象请求3025;b)与对象源3050建立连接,重建对象3004,并建立更新对象请求3022。然后TMD3040把删除远程对象请求3025或更新对象请求3022传送给分布管理器3043。分布管理器3043建立与每个被配置的远程高速缓存管理器3002或从属触发监视器3000”(图30c)的连接并发送每个请求。如果请求是一个“向前送触发器请求”3021,该请求被送到从属触发监视器3000”(图30a)。如果请求是“更新对象请求”3022,新的对象被通过cache_object(高速缓存对象)410API(图4)传送给远程高速缓存管理器3001。如果请求是“删除远程对象请求”3025,则对象3004被通过delete_object(删除对象)420API(图4)从远程高速缓存管理器3001中清除出去。图30c描述了触发监视器3000的另一例。这里,触发监视器3000被作为从属触发监视器3000”的具体实例。如果主触发监视器3000’只是维护一个系统,或者如果要重新产生对象3004(即不删除它),则该系统能被图30b描述的过程完全地维护。如果触发管理器3000是维护多重系统,则有可能对3004存在于某些但不是所有高速缓存中。特别是,对象3004可能不存在于接收触发事件3020的触发监视器3000所在的同一高速缓存中。为对付这种情况,在每个被配置的节点上运行一个从属触发监视器3000”(图30c)。如所描述的那样,从属触发监视器3000”接收一个向前传送触发请求3021。这一处理与触发事件3020是完全相同的,直至它到达对象发生器3042。如果对象分配块3100有一请求分配3103等于DispRegenerate3130,该请求被放弃。如果请求分配3101是DispInvalidate3131,则建立“删除本机对象请求3023”并发送给从属触发监视器的本机高速缓存。再次参考图30,触发监视器3000最好是作为单个长运行过程来实现,监视对象源3050。本行专家不难使本发明适应于每个部分包含一个或多个过程,其中一些可以在时间上重迭以改善系统的吞吐能力。本行专家还不难使本发明适应于在单一过程中使用多线程,每个线程实现一个或多个组成部分,一些线程可以在时间上重迭,如果底层系统支持线程过程的话。当收到触发事件3020和向前发送触发请求3021时,最好使用传统的机制,如多阶段提交和不变数据对象,来向对象源3050保证这些请求一旦被传送便在系统中保持直至完成。最好使用传统的机制,如重试和多阶段提交,以保证在系统中保持被排队的向外出的请求(图30e描述的)直至完成。对象ID分析(OIA)部分3041把对象ID3009翻译成对象分配块3100(图31)。OLA3041可以作为一个配置选择或一个API或以任何其他标准方式来指定和通过接口连接。本行专家能容易地建立这种机制。对象发生器3042把对象分配块(3100)中的信息翻译成图30c和下文中描述的事务类型。触发监视器3000使用配置选项对这一组成部分提供接口。对象发生器3042的实例是如下产品IBM以NETDATA为商标的产品;Lotus公司以DOMINO服务器为商标的产品;或能从中提取HTML页面的任何万维网服务器。图30d描述send_trigger(发送触发器)API的举例。如所描述的那样,send_trigger3026API使对象源3050能与触发监视器驱动器3040通信。send_trigger3026API发送包括足够信息(消息参数)的消息以唯一地标识该触发器并构成触发事件3020。本行专家能容易地用标准性技术(如可变长参数列表)来定义和指定这一信息。图30e描述根据本发明所用的事务类型举例。如所描述的那样,在系统内能产生若干事务3020…3025。触发事件3020是响应通过send_trigger3026API发送的消息被收到而产生的。触发事件3020是一个结构,它包含足够的信息以把send_trigger3026API发送的数据翻译成一个或多个“显示依赖对象请求”3024和适当地通过系统跟踪与引导本身。向前传送触发请求3021是响应通过send_trigger3026API发送的触发事件3020的接收而产生的。向前传送触发请求3021是一个结构,它维持足够的信息以产生一个或多个显示依赖对象请求3024并适当地通过系统跟踪与引导它本身。由对象发生器3042产生“更新对象请求”3022,以使新对象通过分布管理器3043分布到远程高速缓存管理器3002。更新对象请求是一个结构,它维持足够的信息去替换任意高速缓存3003中的对象3004。由对象发生器产生“删除本机对象请求”3023,以使本机高速缓存3003删除对象3004。删除本机对象请求3023是一个结构,它维持足够的信息从本机高速缓存管理器3001中删除对象3004。“显示依赖对象请求”3024是由触发监视器驱动器3040响应触发事件3020而产生的,用以从本机高速缓存管理器3001请求依赖关系信息。显示依赖对象请求3024是一个结构,它维持足够的信息以分析触发事件3020或向前传送触发器请求3021,并调用API函数show_dependent_objects(显示依赖对象)3024来从本机高速缓存管理器3001获取对象ID3009。“删除远程对象请求”3025是由对象发生器3042产生的,它引起通过分布管理器3043从远程高速缓存管理器3002中删除一对象3004。删除远程对象请求是一个结构,它维持足够的信息以从任意高速缓存3003中删除一对象3004。图33描述了触发监视驱动器3040和分布管理器3043的高级组织和通信路径。最佳组织是由若干个独立执行的控制线程组成的接收线程3300接收请求,包括触发事件3020和向前传送触发器请求3021,并把它们存入某个永久存储器。到来任务分送线程3320对来自3300的到来请求解除队列,并把它们编队以便处理。管理器通信线程3340把“删除本机对象请求”3023和“显示依赖对象请求”3024发送给本机高速缓存管理器3060。对象发生器线程3360协调如下对象请求的产生删除远程对象请求3025;更新对象请求3022,并把它们排队以便分发出去。分布线程3080(它是分布管理器3043的主要组成部分)对来自分布管理器队列3370的请求解除队列,并把它们排队到所有远处的机器上。“外部事务”线程3395接触远程机器并把机外部队列3390上排队的工作向前方传送。如传统的那样,这些线程能通过若干FIFO队列进行通信到达请求队列3310;高速缓存管理器请求队列3330;对象发生器队列3350;分布管理器队列3370;以及机器外部队列3390(每个分布式高速缓存有一个)。图34描述接收线程3300逻辑的举例。如所描述的那样,在步骤3410,一个到达消息(或者是send_triggerAPI3026,或者是向前发送触发器请求3021)进入系统并被转换成触发事件3020。在步骤3420,由接收线程3300把消息写入永久队列3450,并在步骤3430排队到到达请求队列3310。在步骤3440,检验请求类型。在步骤3460,如果它是一个触发事件3020,则一个向前传送触发请求3021被排队到分布管理器队列3370。在步骤3490,接收线程3300返回到等待3490以等待任务。图35描述了到达任务分解线程3320逻辑的举例。如所描述的那样,在步骤3510,到达任务分解线程3320对任务请求解除队列。在步骤3520,一个显示依赖对象请求3024被排队到高速缓存管理器请求队列3330。在步骤3590,接收线程3300返回等待任务。图36描述了高速缓存管理器通信线程3340逻辑的举例。如所描述的那样,高速缓存管理器通信线程3340把下一个请求解除队列,并建立与本机高速缓存管理器3001的通信。在步骤3023,如果该请求是删除本机对象请求,则在步骤3650,使用delete_object420API从本机高速缓存3003中删除该对象。在步骤3024,如果该请求是显示依赖对象请求,则在步骤3620,使用show_dependent_objects460API提取对象ID3009。在步骤3630,对象ID3009被传送到对象ID分析部分3042,它建立一个对象分配块3100。在步骤3640,对象分配块3100被排队到对象发生器3043。最后,在步骤3690,高速缓存管理器通信线程3340返回3690等待任务。图37描述对象发生器线程3360逻辑的举例。如所描述的那样,在步骤3710,对象发生器线程3360将下一个请求从队列3350中解除。在步骤3720,检验对象的分配。如果它是DispInvalidate3131,则进入步骤3750;如果是DispRegenerate3130,则进入步骤3730。在步骤3730,检验请求类型。如果它是向前传送触发器请求3021,则进入步骤3770;如果它是触发事件3020,则进入步骤3740。在步骤3740,数据源3050被接触以产生对象3004。由更新对象请求3022把新对象3004排队到分布管理器队列3370。然后过程返回步骤3790等待任务。在步骤3750,检验请求类型。如果它是向前传送触发器请求3021,则进入步骤3780;如果它是触发事件3020,则进入步骤3760。在步骤3760,建立一个删除远程对象请求3024并排队到分布管理器队列3370。然后过程返回步骤3790等待任务。在步骤3770,请求被从系统中删除。然后过程返回步骤3790等待任务。在步骤3780,删除本机对象请求3023被排队到高速缓存管理器请求队列3330。然后过程返回步骤3790等待任务。图38描述分布管理器线程3380逻辑的举例。如所描述的那样,在步骤3810,分布管理器线程3380把任务从分布管理器队列3370中解除,并把该请求的副本排队到每个机器外部线程3390。然后过程返回步骤3790等待业务。图39描述向外事务线程3395逻辑的举例。每个参加分布式更新机制的机器有一个向外事务线程3395。如所描述的那样,在步骤3910,该线程把任务从机器外部队列3390中解除,并检验请求类型。在步骤3920,如果它是更新对象请求3022或删除远程对象请求3025,则过程继续到步骤3920;如果它是向前传送触发请求3021,则过程继续到步骤3930。在步骤3930,如果它是向前传送触发请求3021,则过程继续到步骤3930。在步骤3920,远程高速缓存管理器3001被接触。在步骤3940,如果该请求是更新对象请求3022,则使用cache_object410API把新对象3004发送到远程高速缓存管理器3002。然后过程返回步骤3990等待任务。在步骤3950,如果该请求是删除远程对象请求3025,则使用delete_object420API从远程高速缓存管理器3002中删除对象3004。然后过程返回步骤3990等待任务。在步骤3930,远程触发监视器3000a被接触。在步骤3960,该向前传送触发器请求3021被送到远程触发监视器3000。然后过程返回步骤3990等待任务。然后过程返回步骤3790等待任务。扩展和变体根据本发明的具体应用,可能需要这里没有迭代过的其他出口以充分地分析触发事件3020和翻译成行动(例如更新对象请求3022或删除远程对象请求3025)。例如,现在参考图40a)通过一个出口把单个触发事件3020翻译(4000)成一组多个显示依赖对象请求3024,这可能是有用的;b)在更新对象请求3022中把对象3004排队之前,对这个由对象发生器3042创建的对象3004进行修改和分析(4010)可能是有用的;以及c)把对象3004写入文件系统,以替代把对象3004写入高速缓存3003,或作为写入高速缓存3003的补充,这可能是有用的。触发监视器3000的另一用途将是重新使用它的能力来产生和分布对象,以处理那些当前可能在高速缓存中不存在的对象a)能使用一个prime_cache(初级高速缓存)API4020来产生和分布一个给定对象ID3009的对象3004,不论该对象3004当前是否为任何高速缓存3003所知道;以及b)能使用一个global_delete(全局删除)API4030来保证一些特定对象3004从系统中的所有高速缓存1中被删除,而不需知道该对象是否实际存在于任何地方。触发监视器3000可以被实现来执行严格的FIFO顺序和处理请求,或允许完全异步处理请求,或者按任何公知的时间安排方案来处理请求,或者按上述各种方式的任何组合。维持一致性如前所述,尽管这里所用的术语含有字典上的意义,但这里对一些术语提供如下词汇表作为指导事务管理器(transactionmanager)是一个管理状态的程序。例如包括管理高速缓存的高速缓存管理器;数据库管理系统(如DB2);以及事务处理系统(如CICS)。事务(transaction)是由另一个程序向一个事务管理器发出的请求。变状态事务(state_chagingtransaction)是一个事务,它改变由事务监视器管理的状态。向高速缓存管理器提出的读、更新或删除高速缓存对象的请求会构成事务。读数据或修改数据被称作访问(access)。锁(lock)是一个实体,它限制过程读或写共享数据的能力。当一个过程得到对一片数据的读锁时,其他过程能访问这些数据,但没有任何其他过程可以修改这数据。当一个过程得到对数据写或排他锁,则没有任何其他过程可以读或修改该数据。在先有技术中存在若干方法来实现锁,例如参见由Hennessy和Patterson写的“计算机结构一种定量手段”,第二版,MorganKaufmann,1996。设S是一组事务,它们修改含有一个或多个事务管理器的系统上的数据。如果满足下列条件,则S是被一致性地完成的(1)对于不属于S的任何其他请求r1,它访问d的全部或部分,被r1访问的d的所有部分或者处在被S中任何事务修改之前的状态或者处于被S中所有事务修改之后的状态。(2)对于不属于S的任何请求r1和r2,这里r2或与r1同时或在r1之后被系统接受,而且r1和r2二者访问d的子集d’,(a)如果被r1访问的d’版本已被S中的事务修改过,那么被r2访问的d’版本也已被S中的事务修改过。(b)如果被r2访问的d’版本当未被S中的事务修改过,那么被r1访问的d’版本也尚未被S中的事务修改过。时标(timestamp)是一个属性,能被赋予事件,如被系统接受的事务或被获得的锁。在先有技术中实现时间标记的一般方法包括时钟计时和对事件排序的数字。本发明的另一特点是对一个或多个高速缓存造成一组一致性更新的能力。本发明被用于把一组请求S应用到一个或多个高速缓存管理器3001,这里的如下特性是人们所希望的(1)对访问系统的任何程序P,必须自动地造成S。就是说,P不能看到一些S中的请求已被满足而另一些尚未被满足的系统视图(view)。(2)对同时被适当的高速缓存管理器3001接受的任何两个请求r1和r2,r1和r2关于S看到同一个系统视图。就是说,或者r1和r2二者看到的是S中请求已被满足之前的系统视图,或者r1和r2二者看到的是S中请求已被满足之后的系统视图。(3)对于任何两个请求r1和r2,这里r2被高速缓存管理器3001接收是在r1被高速缓存管理器接收之后,如果r1看到的系统是在S中请求已被满足之后的系统视图,那么r2必须看到的是该系统的同一视图。如果r2看到的是S中请求被满足之前的系统视图,那么r1必须看到这同一视图。图41描述了对于含有一个或多个高速缓存的系统一致性地造成一组请求S的逻辑的举例。最好是S中每个请求被指向一个高速缓存管理器3001。这一组接受来自S的一个请求的高速缓存管理器C可以有一个或多个成员。如所描述的那样,在步骤4500,一组请求S被系统接受。每个请求被指向一个特定的高速缓存管理器3001。在步骤4505,高速缓存管理器锁住数据。对于每个从S接受一个请求的高速缓存管理器j,高速缓存管理器j获得对于被S中一请求修改的数据的写锁,和对于被S中一请求读但不被S中一请求写的数据的读锁。在这一步中被锁住的数据将在下文中称作被锁数据。在步骤4600,系统确定最后一次获得锁的时间、last_lock_time。如果从S中接受一个请求的这组高速缓存管理器C只有一个成员,则能用先有技术容易地实现这一步骤。如果C有多个成员,则按图42中描述的方式确定last_lock_time。在步骤4510,在last_lock_time之前收到的正在等待被锁数据的请求被完成。在步骤4520,S中的请求被完成。在步骤4530,从被锁数据中去掉锁,这允许在last_lock_time之后收到的等待被锁住数据的请求被完成。步骤4510、4520及4530必须按顺序完成。与图41描述的不同的另一实施例是使用单个锁来防止请求去访问被S中一请求访问的数据。最佳实施例允许的并发级别比这另一个途径要高得多。图42描述了当从S接收请求的一组高速缓存管理器C有多个成员时确定last_lock_time的逻辑的举例。如所描述的那样,在步骤4600,表示为cachemgri的C的每个成员确定它在步骤4505获得最后的锁的时间last_lock_time_i;然后高速缓存管理器cachemgri把last_lock_time_i发送给一个称作协调程序的程序。在步骤4610,协调程序从C中所有高速缓存管理器接收last_lock_time_i之值,并把last_lock_time设成它收到的最近的一个last_lock_time_i。在步骤4615,协调程序把last_lock_time发送到C中所有高速缓存管理器。图42中描述的举例的一个变体是在步骤4600中由C中每个高速缓存管理器i以last_lock_time_i之值与C中其他高速缓存管理器进行交换,用来代替把last_lock_time_i发送给协调程序。在步骤4610,C中每个高速缓存管理器i将根据它收到的last_lock_time_i值来确定last_lock_time。步骤4615将是不必要的。当C大时该最佳实施例需要较少的通信和较少的比较次数,因而比刚才描述的变体更具可伸缩性。本行专家不难采用本发明在其他含有一个或多个事务管理器的系统中实现一致性,这里的事务管理器不一定必须是高速缓存管理器。既然已经通过详细描述加上替代物描述了本发明,各种扩充、变体和等效物对于本行专家而言就变得显而易见了。这样便会理解,详细描述是以举例方式提供的,因而不是一种限制。本发明的合适范围由权利要求适当地确定。权利要求1.在包括一个或多个高速缓存以存储一个或多个复杂对象的计算机系统中,一种确定底层数据的改变如何影响一个或多个复杂对象之值的方法,其特点在于它由以下步骤组成识别至少一部分底层数据,这里的底层数据可以是或可以不是可高速缓存的;以及把所述至少一部分底层数据映射到一个或多个所述复杂对象,这些对象对所述至少一部分底层数据有一个或多个数据依赖关系。2.权利要求1的方法,特点在于还包括多个计算机,这里伴随第一高速缓存的第一组计算机与伴随所述映射步骤的第二组计算机分离。3.权利要求1的方法,特点在于还包括步骤维持一个对象依赖关系图(G),它可以随时间改变,而且它包括多个图对象和指示图对象之间一个或多个数据依赖关系的边缘。4.权利要求1的方法,特点在于所述映射步骤还包括由程序安排的操作时间表的步骤,这里不同的时间表会造成对底层数据的不同的改变。5.权利要求4的方法,特点在于所述安排操作时间表的程序是一个编译器、运行时系统或数据库。6.权利要求3的方法,特点在于所述映射步骤包括使用所述图把所述至少一部分底层数据映射到至少一个复杂对象。7.权利要求3的方法,特点在于还包括对边缘赋予权的步骤,这里的权与数据依赖关系的重要性相关联。8.权利要求7的方法,特点在于至少一个边缘的权在被赋予之后是不改变的。9.权利要求7的方法,特点在于(1)一个图对象o1存在两个版本o1_v1和o1_v2;以及(2)对象依赖关系图G包含至少一个边缘(o2,o1)终止于o1并有被赋予的权;而且还包含以下步骤对于终止于所述o1并由一个集合S组成的一个或多个边缘(o2,o1),保持所述对象o2的一个版本号,它与o1_v1一致;保持所述对象o2的第二版本号,它与o1_v2一致;基于所述集合S中边缘(o2,o1)的权之和,确定o1_v1和o1_v2的相似程度,从而使所述图对象o2的同一版本与所述版本o1_v1和o1_v2以及所述集合S中所有终止于o1的边缘的权和相一致。10.权利要求9的方法,特点在于所述确定两个版本相似程度的步骤还包括把所述集合S中的边缘(o2,o1)权之和分割的步骤,从而借助所述集合S中终止于o1的所有边缘的权之和来使所述图对象o2的同一版本与所述版本o1_v1和o1_v2一致。11.权利要求1的方法,特点在于所述映射还包括以下步骤利用关于一个或多个复杂对象如何受所述至少一部分底层数据改变的影响的信息,确定是否或如何造成对所述至少一部分底层数据的改变。12.权利要求1的方法,特点在于实现所述映射步骤的程序产生一个或多个多重过程、多重线程、以及管理所述一个或多个高速缓存存储器的一个或多个长运行过程或线程。13.权利要求1的方法,特点在于所述映射步骤还包括如下步骤识别对所述至少一部分底层数据的改变;以及响应所述识别对所述至少一部分底层数据的改变,识别一个或多个复杂对象受影响程度。14.权利要求12的方法,特点在于实现所述映射步骤的程序产生至少一个长运行过程,而且还包括以下步骤一个应用程序识别对至少一部分底层数据的改变;以及该应用程序把识别出的对至少一部分底层数据的改变通知给所述实现所述映射步骤的程序。15.权利要求1的方法,特点在于还包括一个步骤,确定由于对所述至少一部分底层数据的改变使存储在一高速缓存中的复杂对象的一个版本变为高度过时。16.权利要求15的方法,特点在于还包括一个步骤从高速缓存中删除一个对象的高度过时版本。17.权利要求15的方法,特点在于每当一个对象的版本不是当前版本时便被认为是高度过时的。18.权利要求15的方法,特点在于所述确定一个对象(o1_v1)的一个版本为高度过时由以下步骤组成维持一个对象依赖关系图(G),它可以随时间改变,而且它包括多个图对象(o1…on)以及指示图对象之间一个或多个依赖关系的边缘;以及根据o1_v1与o2当前版本不一致的边缘(o2,o1)的个数,确定所述o1_v1将变为高度过时。19.权利要求15的方法,特点在于还包括一个步骤以更新近的版本代替该对象的一个高度过时版本。20.权利要求19的方法,特点在于该更新近的版本是该对象的当前版本。21.权利要求15的方法,特点在于所述确定存储在高速缓存中的对象o1的一个版本o1_v1将变为高度过时的步骤由以下步骤组成维持一个对象依赖关系图(G),它可以随时间改变,而且它包括多个图对象和指示图对象之间一个或多个依赖关系的边缘;为对应于一个或多个终止于所述o1的边缘的所述o1_v1,初始化和维持weight_act字段;对于一个图对象o2的当前版本的一个或多个改变,从所述对象o2到所述对象o1的边缘存在,o1_v1有一weight_act字段,确定对应于该边缘的weight_act字段减量;以及根据其weight_act字段确定是否所述o1_v1会变为高度过时的。22.权利要求21的方法,特点在于还包括步骤对所述o1_v1维持一个阈值权;这里所述基于其weight_act字段确定是否所述o1_v1会变为高度过时包括所述o1_v1的weight_act字段之和与所述阈值权比较的步骤。23.权利要求21的方法,特点在于还包括以下步骤对对象依赖关系图的边缘赋予权,这里的权与数据依赖关系的重要性相关联;以及把所述o1_v1的一个或多个weight_act字段初始化为对象关系图中相应边缘的一个或多个权。24.权利要求21的方法,特点在于还包括一个步骤,每当o2的当前版本被更新时把对应于对象依赖关系图中从所述o2到所述o1的边缘的weight_act字段(它大于预先确定的最小可能值)设置成这个预先确定的最小可能值。25.权利要求1的方法,特点在于所述一个或多个高速缓存包括下列当中的一个或多个一个多版本高速缓存;一个单版本高速缓存;以及一个当前版本高速缓存。26.权利要求25的方法,特点在于所述一个或多个高速缓存包括至少一个单版本高速缓存c1,而且还包括以下步骤对于至少一个对象o1,维持其他对象o2的一致性集,使得每当o1和o2都被包含在c1中时o1和o2必须是一致的。27.权利要求26的方法,特点在于还包括一个步骤,保证当所述o1和所述o2都在c1中时,所述o1和所述o2是一致的。28.权利要求27的方法,特点在于还包括以下步骤把所述对象o1的当前版本添加到单版本高速缓存,可能代替对象o1的一个先前版本;识别o1的一致性集合中的一个或多个对象o2,这里所述高速缓存c1中包含所述对象o2的一个非当前版本o2_v,而所述o2_v是在所述o1的当前版本被创建之前被创建的;从所述高速缓存c1中删除所述o2_v,或以所述对象o2的更新近版本替代o2_v;对所述对象o2的一致性集合中的对象递归地应用所述识别一个或多个对象的步骤以及从所述高速缓存c1中删除所述o2_v或以所述对象的更新近版本替代o2_v的步骤。29.权利要求26的方法,特点在于还包括以下步骤使用对象o1的一致性集合决定是否把对象o1的一个版本添加到单版本高速缓存,这可能替代对象o1的先前版本。30.权利要求27的方法,特点在于还包括以下步骤对于单版本高速缓存c1中的多重对象o1…on,以c1中的一个不同版本替代每个对象oi,而不保证在所述oi被更新时由对象oi的一致性集合所加的所有约束被满足,但代之以把来自所述o1的一致性集合中的对象obj1添加到一个一致性堆栈中,对于obj1,obj1的不一致性版本可能存在于c1中;在c1中所有对象o1,…,on已被当前版本替代后,遍历一致性堆栈上的所有对象,并对于c1中存在非一致性版本的每个这种对象obj1,从c1中去掉它或以一致性版本替代它。31.权利要求3的方法,特点在于所述G是简单依赖关系图和多重图当中的一个。32.权利要求31的方法,特点在于所述G是一个简单依赖关系图,其中适当的最大节点是复杂对象,适当的叶节点是不为对象的底层数据。33.权利要求32的方法,特点在于所述维持对象依赖关系图由以下步骤组成对至少一个适当叶节点ν维持一个外行相邻列表;以及对至少一个适当的最大节点w维持一个到来相邻列表。34.权利要求33的方法,特点在于还包括一个步骤通过散列表访问外行相邻列表和到来相邻列表之一。35.权利要求33的方法,特点在于所述维持一个对象依赖关系图还包括以下步骤当初始改变的数据包括能被一适当叶节点的改变所代表的某些数据d时,查寻对应于d的外行相邻列表。如果找到了外行相邻列表,检验该列表以确定哪些复杂对象受到影响。36.权利要求33的方法,特点在于还包括一个步骤从对象依赖关系图中删除至少一个适当的最大节点w。37.权利要求36的方法,特点在于所述从对象依赖关系图中删除至少一个适当的最大节点w的步骤还包括以下步骤对于w的到来相邻列表上的至少一个适当叶节点,从其外行相邻列表中删除所述w;对所述w,删除其到来相邻列表。38.权利要求33的方法,特点在于还包括从对象依赖关系图中删除至少一个适当叶节点ν的步骤。39.权利要求38的方法,特点在于所述从对象依赖关系图中删除至少一个适当叶节点ν的步骤进一步包括以下步骤从对于ν的外行相邻列表上的一个或多个适当的最大节点的到来相邻列表中删除ν;删除所述ν的外行相邻列表。40.权利要求3的方法,特点在于图对象r是一个关系对象(RO),它有一个相关联的关系指示,它能代表单(SRO)记录或多重(MRO)记录,而且所述维持一个对象依赖关系图进一步包括以下步骤(a)存储所述r的关系指示;(b)如果一个或多个对象包括所述r,从所述r向包括所述r的一个或多个图对象添加一个或多个依赖关系;以及(c)如果所述r包括一个或多个图对象,从所述r包括的所述一个或多个图对象向所述r添加一个或多个依赖关系。41.权利要求40的方法,特点在于还包括以下步骤对边缘赋予权,这里的权与数据依赖关系的重要性相关联;而且这里所述步骤(b)和(c)之一包括一个步骤确定对应于包含RO节点r2的RO节点r1的至少一个依赖关系的权,确定该权的依据是以下两者之一或两者所述r2包含的所述r1记录所占的百分数;所述记录的相对重要性。42.权利要求40的方法,还包括以下两个步骤之一或二者(d)从所述r向另一ROr2添加一个或多个依赖关系,这里所述另一个ROr2不包括所述r,所用的度量基于以下两点之一或二者也包含在所述r2中的所述r中记录的百分数;也包含在所述r2中的所述r2中记录的相对重要性。(e)从另一个ROr3向r添加一个或多个依赖关系,这里所述r不包括所述r3,所用的度量基于以下两点之一或二者也包含在所述r中的所述r3中记录的百分数;也包含在所述r中的所述r3中记录的相对重要性。43.权利要求42的方法,特点在于还包括以下步骤对边缘赋予权,这里的权与数据依赖关系的重要性相关联;以及计算在步骤(d)和(e)二者之一或二者当中使用所述度量添加的所述一个或多个依赖关系的权。44.权利要求40的方法,其特征在于所述r是下列之一一个新创建的节点;一个被修改过的现存节点;一个SRO节点;以及一个MRO节点。45.权利要求40的方法,特点在于一个或多个关系指示包括关系名,使得有一共同记录的RO派对以高概率具有同一关系名。46.权利要求45的方法,特点在于还包括利用下列之一分隔RO的步骤关系名;以及与关系名结合的平衡树。47.权利要求40的方法,特点在于识别至少一部分底层数据的步骤包含以下步骤识别一个关系指示;以及在具有一个或多个与关系指示共同的记录的对象依赖关系图中定位一个或多个RO。48.权利要求3的方法,特点在于所述映射由以下步骤组成在对应于所述至少一部分底层数据的对象依赖关系图中访问由一个或多个节点构成的一组节点(updateset);以及遍历对象依赖关系图中的边缘,以便访问从所述updateset能达到的节点。49.权利要求48的方法,特点在于所述遍历过程包括以下列方式之一遍历对象依赖关系图深度优先方式;以及宽度优先方式。50.权利要求48的方法,特点在于还包括以下步骤维持一个时间标记,它唯一地标识每个对象依赖关系图的遍历;每当在遍历过程中第一次访问对象依赖关系图中一个顶点时,便在此顶点处存储一个时间标识;以及通过比较在顶点处的时间标记和当前遍历的时间标识,以确定在当前遍历过程中该顶点是否已被访问过。51.权利要求50的方法,特点在于还包括对每个新的图遍历时的时间标记增量。52.权利要求3的方法,特点在于图对象o1的两个版本o1_v1和o1_v2存在,对象依赖关系图G包含至少一个终止于o1的边缘(o2,o1),而且包含以下步骤对于终止在所述o1并包含一组S的一个或多个边缘(o2,o1),维持一个所述对象o2的版本号,它与o1_v1一致,以及所述对象o2的第二版本号,它与o1_v2一致;基于所述S组中的边缘(o2,o1)个数,和所述S组中终止于o1的所有边缘数,确定o1_v1和o1_v2的相似程度,这里一个图对象o2的同一版本与所述版本o1_v1及o1_v2一致。53.权利要求52的方法,特点在于确定o1_v1和o1_v2相似程度的步骤包括用所述S组中终止于o1的所有边缘数去除所述S组中边缘(o2,o1)的个数,这里图对象o2的同一版本与所述版本o1_v1和o1_v2一致。54.权利要求1的方法,特点在于至少一些对象是万维网文件,而且至少一些底层数据是一个或多个数据库的一部分。55.权利要求15的方法,特点在于确定存储在一高速缓存中的一复杂对象o1的一个版本会是高度过时的步骤包含一个步骤确定边缘(o2,o1)个数,这里所述o1的版本与所述o2的当前版本一致。56.权利要求55的方法,特点在于确定存储在一高速缓存中的一复杂对象o1的一个版本会是高度过时的步骤还基于终止于所述o1的边缘的总数。57.权利要求3的方法,特点在于还包括一个步骤利用关于一个或多个对象的一组supdate会如何受底层数据变化影响的信息,结合对象依赖关系图,确定对所述s_update中的一个或多个对象有依赖关系,或者直接指定,或者由对象依赖关系图间接指明,的至少一个其他图对象会受到影响的程度。58.权利要求30的方法,特点在于还包括一个步骤,通过把对所述对象的访问存储在一个链接列表上来实现一致性堆栈。59.权利要求30的方法,特点在于还包括下列步骤使用一个或多个平衡树来实现所述一致性堆栈;以及对于至少一个对象obj1,确证在把对所述obj1的访问添加到一致性堆栈之前对所述obj1的访问并没有已经包括在一致性堆栈中。60.权利要求26的方法,特点在于所述一致性集合是用一个或多个链接列表实现的。61.在包括一个或多个高速缓存以存储一个或多个复杂对象的计算机系统中,有一个或多个远程数据源存储底层数据,这些底层数据可能影响一个或多个所述对象的当前值,该方法的特点在于以下组成步骤维持一个对象依赖关系图,它可能随时间改变,而且它包括多个图对象和指示所述图对象之间一个或多个数据依赖关系的边缘;识别出何时至少一部分所述底层数据已改变;向高速缓存通告以下信息中的一个或多个关于已改变的至少一部分底层数据的信息;以及包括由于所述底层数据已改变造成其值已改变的至少一个对象的标识的信息;以及允许这个由于所述底层数据已改变造成其值已改变的至少一个对象的标识能被确定所需的信息;以及响应所述通告步骤,从而从高速缓存中去掉一个对象,或对高速缓存中的对象更新为新版本。62.权利要求13的方法,特点在于所述至少一部分底层数据被存储在一个或多个远程数据源中,而且还包括以下步骤向高速缓存通告以下信息中的一个或多个关于已改变的至少一部分底层数据的信息;以及包括由于所述底层数据已改变造成其值已改变的至少一个对象的标识的信息;以及允许这个由于所述底层数据已改变造成其值已改变的至少一个对象的标识能被确定所需的信息;以及响应所述通告步骤,从而从高速缓存中去掉一个对象,或对高速缓存中的对象更新为新版本。63.一个机器可读的程序存储装置,真实地实现由该机器可执行的指令程序,完成根据权利要求1-11,13,18,21-24,26-30,40,45,47,48或50中的任何项的方法步骤,以确定底层数据的改变如何能影响一个或多个复杂对象之值。全文摘要能够确定底层数据的改变如何影响对象之值。应用实例包括:高速缓存动态万维网页;客户机-服务器应用,借助这些应用,把对象(这些对象总在改变)发送到多个客户机的服务器能跟踪哪些版本被送到哪些用户以及这些版本的过时程度;以及任何这样的场合,那里需要维持和唯一地识别对象的若干版本,更新过时的对象,定量评估同一对象的两个版本的差异程度,和/或在一组对象中维持其一致性。一个称作对象依赖关系图的有方向图可被用来代替对象间的数据依赖关系。文档编号G06F12/08GK1213800SQ98116759公开日1999年4月14日申请日期1998年7月31日优先权日1997年8月1日发明者詹姆斯·罗伯特·哈罗德·查林杰,保罗·迈克尔·丹特兹格,阿鲁·K·伊延加,杰拉尔德·A·斯皮瓦克申请人:国际商业机器公司