精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>● 群件>>管理>>Domino/Notes>>Note ID剖析(二)

主题:Note ID剖析(二)
发信人: dega.p()
整理人: kamkam(2002-05-01 23:37:37), 站内信件
http://dingxiang.163.net/notesfaq/noteid.html
=======================================
UNID, the OID, 和复制器( Replicator)

Universal Note ID (Originator ID的第一部分) 唯一的确定了同一文档(no
te)的所有版本和复本。如果两个文档(note)具有相同的UNID则它们互为复本
。因此,相同文档(note)的所有复本的不同版本都有相同的 UNID。这就导出一
个必然的结论:一个数据库中不能含有两个具有相同UNID的文档(note)。如果
复制器(replicator)发现同一个数据库中两个文档(note)具有相同的UNID,
它就会产生一个错误消息写到日志里,并且不对文档进行复制。

完整的 Originator ID, 从另一个方面唯一地确定了一个文档(note)的一个特
殊版本。就是说,一个文档的相同版本的复本具有相同的OID。同时,一个文档(
note)复本修改后,它就会有不同的OID。因为在文档(note)被编辑后, Domi
no 和 Notes 会增加序列号(sequence number)和序列时间(sequence)。 当
文档(note)的一个复本保持不变,而另一个复本被编辑并修改,于是这两个复
本具有相同的 UNID但是序列号(sequence number)和序列时间(sequence tim
es)不同,因此OID也不同。

Domino 复制器(replicator)使用UNID 来匹配数据库中的文档(note),例如
:如果数据库A和数据库B进行复制,数据库A中有个文档含有特殊的UNID,但是数
据库B中没有,于是复制器(replicator)在数据库B中创建一个该文档的复本拷
贝。

如果数据库A中包含一个文档(note)同时数据库B中有个文档(note)和它有相
同的UNID,复制器(replicator)推断这两个文档(note)是同一个文档的两个
复本。这种情况下,复制器(replicator)继续检查两个文档的序列号(sequen
ce number )和序列时间(sequence time),然后复制器(replicator)推断是
否是同一时间更新过需不需要复制。如果序列号(sequence number )或序列时
间(sequence time)其中有一个或两个都不同,复制器必须决定哪一个是最近更
新的哪一个比较旧一点。

如果其中一个更新过,而另一个未更新过,这样第一个复本的序列号会比第二个
复本的序列号大,复制器(replicator)根据这种情况使用第一个复本覆盖第二
个复本,从而达到两个数据库同步的目的。

复制冲突

复制冲突(Replication conflicts)发生在同时编辑并保存同一个文档(note)
。如果用户修改了数据库A中的一个文档复本,而另一个数据库B中的文档复本也
被修改(所作修改都在上一次成功复制之后,下一次复制之前),于是两个文档
复本具有相同的序列号()但是序列时间不同。这种情况下,复制器产生一个复
制冲突,因为一个文档的两个复本在同一时期都进行了修改。(如果把一个文档
的多个复本看成是同一个文档的话,这就表示同一个文档同时被修改。)

复制器通过生成复制冲突文档处理这种复制冲突。序列时间较早的文档(docume
nt)被标志为冲突文档。两个数据库中将会具有两个文档,只不过序列时间较早
的文档会成为序列时间较晚的文档的答复文档。

复制器产生复制文档冲突,会在冲突文档前标志黑色菱形标记。复制器把序列时
间较晚的文档拷贝到序列时间较早的文档所在的数据库中,并完整的保持它的 O
ID。 然后复制器把序列时间较早的文档转成一个新的文档生成一个截然不同的 
OID 并给它增加一个特殊的条目 "$Conflict" (VIEW_CONFLICT_ITEM) 。 这个 
$Conflict 条目会使文档在视图的左边显示一个黑色的菱形标记,表示它是一个
冲突文档。 复制器也会给这个冲突文档增加一个$REF 条目使他变成答复文档,
$REF 条目中含有其父文档(序列时间较晚)的UNID。

注意: 冲突文档(黑色菱形标记文档)并不总是立刻出现在两个服务器上。当拥
有序列时间较晚文档的服务器发起复制时,冲突文档不会立刻在复制完成后出现
在这个服务器上,但是会出现在那个拥有序列时间较早文档的服务器上。这是因
为复制器仅在拥有序列时间较早文档的服务器上产生复制冲突文档(黑色菱形标
记)。

特殊地,当服务器B初始发起复制,首先服务器B从服务器A拉(PULL),然后服务
器A从服务器B拉(PULL)。当服务器B从服务器A拉动改变时,B看到了A上的冲突
文档,发现B上的文档较新(序列时间较晚),所以不会把A上的冲突文档拉到B上
。这样做的理由是因为B已经是最新的文档了,不需要再取得旧的文档了。然后 
A 从B拉动改变,看到B上的文档较新,因此A把自己的较旧的文档变成复制冲突(
黑色菱形),并把B上的较新的文档拷贝到A上。这就满足复制的需要:使数据库
保持最新的同步。于是冲突文档(较晚的)不会出现在B上。下一次服务器B和服
务器A进行复制时,冲突文档(较晚的)就会出现同时出现在两个服务器上达到同
步的目的。


The OID and the API

API 程序使用 NSFNoteGetInfo 来获得 Originator ID 的不同构件,可以指定 
 _NOTE_OID 标志位,例如:

    ORIGINATORID    NoteOID;

  /*
     * Get the OID from the note AFTER it has been updated
     */

    NSFNoteGetInfo (hNote, _NOTE_OID, &NoteOID);


NSFNoteUpdate 导致 Domino 和 Notes 改变正在更新的文档的序列号(sequenc
e number)和序列时间(sequence time)。 因此, API 程序特别注意他们调用
 NSFNoteUpdate 和 NSFNoteGetInfo 的顺序。

特别的,使用 NSFNoteCreate 创建一个新文档(note)获得文档的句柄后,直到
这个文档保存到数据库中(使用 NSFNoteUpdate),NSFNoteGetInfo 才能返回有
效的 OID。但是,既然这时 UNID 已经被赋值,所以 API 程序能够使用 NSFNot
eGetInfo 分析并返回新建文档的 UNID 。



UNID.File

OID的文件号(File member )包含了一个号码,依赖于 Domino 或 Notes 的不
同版本。 Notes 2.1之前的版本中,文件号表示数据库文件创建的时间和日期。
Notes 2.1 版本设置文件号(File member)跟用户有关的唯一标志符,一部分取
自创建文档的用户的ID,一部分取自文档所在的数据库。Notes 3.0 及以后版本
文档创建后把文件号(File member)设置成一个随机的号码。


UNID.Note

OID的文档号(Note member)是文档创建的时间。 (详细信息参见数据结构 TI
MEDATE )


Global Note ID (GNID) and NOTEID (NID)

Global Note ID (GNID) 由两部分组成:数据库 ID 和文档ID(Note ID)。既然
 GNID 确定数据库和数据库中的文档,所以它可以唯一的确定所有数据库中所有
文档的所有复本。

GNID 出现在 ID 信息的最后一行(使用 Design - Document Properties信息框
)。第一部分对应数据结构 GLOBALNOTEID 的文件部分(File member),第二部
分对应数据结构 GLOBALNOTEID的 NoteID 部分。


Global Note ID (GNID) =
ID: OF0000039D:3836C29F-ON85255DC9:0056FB94
    SD00255DF4:0057B8FA-SN00000003
    DB85255CD9:00567287-NT0000C092


Database ID (GNID.File) =
ID: OF0000039D:3836C29F-ON85255DC9:0056FB94
    SD00255DF4:0057B8FA-SN00000003
    DB85255CD9:00567287-NT0000C092

Note ID (GNID.NoteID) =
ID: OF0000039D:3836C29F-ON85255DC9:0056FB94
    SD00255DF4:0057B8FA-SN00000003
    DB85255CD9:00567287-NT0000C092


第三行开始是字符 "DB" (表示 "Data Base"),紧跟16个16进制字符,然后是
连字符,然后是 "NT" ("NoTe"),跟着是8个16进制字符。在"DB" 后连字符前的
16个16进制字符构成了 GNID的文件号(File member), "NT" 后的8个16进制字
符构成 Note ID 。


Global Note ID (GNID)

不象 OID,GNID 不能区别同一文档的不同版本,因为 NoteID 和包含文档的文件
有关,所以文档复本的 GNID 很可能不同。

Database ID (GNID的文件部分)包含了数据库的复本ID(replica ID),API 
头文件 nsfdata.h 定义 DBID 数据结构为 TIMEDATE类型:

#define DBID TIMEDATE

这个 8-byte DBID 包含了数据库原始创建的 TIMEDATE。你可以验证GNID的文件
号(File member),显示在 File - Document 属性对话框,将会和数据库的 R
eplica ID相同,它显示在 File - Database 属性信息框。因为一个特殊数据库
中的所有复本都有相同的 DBID,所以一个数据库中的所有复本数据库中的所有文
档都有相同的 GNID.File.

typedef struct {
DBID File; /* Creation Date/Time of NSF where note was created */
NOTEID NoteID; /* Note's RRV in this file */
} GLOBALNOTEID;

#define GNID GLOBALNOTEID


Note ID (NID)

note ID (NID) 确定数据库中的一个文档。NID 是文档(note)的记录重布置向
量(Record Relocation Vector (RRV))的文件位置。一个 RRV 是一个 DWORD 
型的偏移量。 因为 note ID 有时会被描述为 "the Note's RRV in this file.
",所以常会导致错误的理解。事实上,note ID 对于 RRV来讲是在文件中的偏移
量,表示文档记录的入口点。RRV 是一个基本的数据结构,而 note ID 则更加明
确。在 Domino 和Notes 内部,除了文档之外的其他不同对象也都有相关的 RRV


typedef DWORD RRV;
typedef DWORD NOTEID;

在一个数据库文件中,note ID 保证不会改变,除非这个文档被删除。当文档被
删除时,note ID中的RRV_DELETED 标志位被设置。

#define RRV_DELETED 0x80000000L /* indicates a deleted note */

因为 note ID 在数据库文件中是明确的,其他数据库中的同一文档的复本拷贝很
可能会有不同的 note ID。


INSTANCEID (IID)

Instance ID 表示给定数据库中的文档对象的实例。每次文档(note)被修改,
Domino 或 Notes 使用时间和日期标志 instance ID。Instance ID 由文档修改
的 TIMEDATE 和 note ID组成。

typedef struct {
TIMEDATE Note; /* Note's MODIFICATION date/time */
NOTEID NoteID; /* Note's RRV */
} INSTANCEID;

#define IID INSTANCEID

文档修改的 TIMEDATE (数据结构IID中的 Note 部分)和OID的修订时间不是相
同的概念。数据库视图使用文档(note)的 IID 修改时间 来决定什么时候显示
未读文档标志。你可以使用NSFNoteGetInfo 并指定 _NOTE_MODIFIED 标志位来访
问IID修改时间。 复制器使用OID的修订时间(Revision Time)来比较不同数据
库中文档的复本。 可以使用NSFNoteGetInfo 并指定  _NOTE_OID 标志位来访问
OID修订时间。

IID的 NoteID 部分是和GNID的 NoteID部分值相同。

NSFNoteUpdate 每次 NSF 文件更新时更新修改时间,这个修改时间(modificat
ion timedate)控制视图显示未读文档标记。

一个API程序有几种方式得到 IID ,从GNID 中取得Note ID,NIFReadEntries 缓
冲区或者 SEARCH_MATCH数据结构的ID的NoteID 部分 。从SEARCH_MATCH数据结构
的ID的NoteID 部分,或者调用 NSFNoteGetInfo 并指定 _NOTE_MODIFIED标志位
来获取修改时间


GLOBALINSTANCEID (GIID)

Global Instance ID 是跨数据库的文档(note)实例。它包含了 Instance ID 
的相同的部分并且增加了 database ID作为文件号。带有最近修改时间的文档是
最新( "most recent")实例。

typedef struct {
DBID File; /* database Creation time/date */
TIMEDATE Note; /* note Modification time/date */
NOTEID NoteID; /* note ID in database */
} GLOBALINSTANCEID;

#define GIID GLOBALINSTANCEID


API 程序能够初始化一个 GIID 数据结构给文档,通过调用 NSFDbIDGet 来获得
文件号,调用 NSFNoteGetInfo并指定_NOTE_MODIFIED 来获得对应于修改时间的
部分。

--
:◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆
: ◇◇◇◇◇◇◇◇◇◇◇◇◇
:   总是想灌水*#$@&%!~
: ◇◇◇◇◇◇◇◇◇◇◇◇◇
:◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆

※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.96.167.50]

[关闭][返回]