cdocutils.nodes document q)q}q(U nametypesq}q(X#changes constituting a new snapshotqNX+preservation and scientific reproducibilityqX!importance of the obsolete fieldsqNX1series identifier resolution to the head revisionq NXoverviewq NXaggregating download statisticsq NXmutable member node exampleq NXusage conventionsq NX%identifier resolution in dataone apisqNX"immutability of content in dataoneqNXsummaryqNX!changes constituting a new seriesqNXcontentsqNuUsubstitution_defsq}qUparse_messagesq]qUcurrent_sourceqNU decorationqNUautofootnote_startqKUnameidsq}q(hU#changes-constituting-a-new-snapshotqhU+preservation-and-scientific-reproducibilityqhU!importance-of-the-obsolete-fieldsqh U1series-identifier-resolution-to-the-head-revisionqh Uoverviewq h Uaggregating-download-statisticsq!h Umutable-member-node-exampleq"h Uusage-conventionsq#hU%identifier-resolution-in-dataone-apisq$hU"immutability-of-content-in-dataoneq%hUsummaryq&hU!changes-constituting-a-new-seriesq'hUcontentsq(uUchildrenq)]q*(cdocutils.nodes section q+)q,}q-(U rawsourceq.UUparentq/hUsourceq0Xo/var/lib/jenkins/jobs/API_Documentation_trunk/workspace/api-documentation/source/design/ContentImmutability.txtq1Utagnameq2Usectionq3U attributesq4}q5(Udupnamesq6]Uclassesq7]Ubackrefsq8]Uidsq9]q:h%aUnamesq;]qhh)]q?(cdocutils.nodes title q@)qA}qB(h.X"Immutability of Content in DataONEqCh/h,h0h1h2UtitleqDh4}qE(h9]h8]h6]h7]h;]UrefidqFUid1qGuh=Kh>hh)]qHcdocutils.nodes Text qIX"Immutability of Content in DataONEqJqK}qL(h.hCh/hAubaubcsphinx.addnodes index qM)qN}qO(h.Uh/h,h0h1h2UindexqPh4}qQ(h9]h8]h6]h7]h;]UentriesqR]qS(UsingleqTX immutabilityUindex-0qUUNtqVaUinlineqWuh=Kh>hh)]ubcdocutils.nodes target qX)qY}qZ(h.Uh/h,h0h1h2Utargetq[h4}q\(h9]h8]h6]h7]h;]hFhUuh=Kh>hh)]ubcdocutils.nodes topic q])q^}q_(h.Uh/h,h0h1Uexpect_referenced_by_nameq`}h2Utopicqah4}qb(h6]h7]qcUcontentsqdah8]h9]qe(h(hUeh;]qfhauh=Kh>hUexpect_referenced_by_idqg}qhhUhYsh)]qi(h@)qj}qk(h.XContentsh4}ql(h6]h7]h8]h9]h;]uh/h^h)]qmhIXContentsqnqo}qp(h.Uh/hjubah2hDubcdocutils.nodes bullet_list qq)qr}qs(h.Uh/h^h0Nh2U bullet_listqth4}qu(h6]h7]h8]h9]h;]uh=Nh>hh)]qv(cdocutils.nodes list_item qw)qx}qy(h.Uh4}qz(h6]h7]h8]h9]h;]uh/hrh)]q{(cdocutils.nodes paragraph q|)q}}q~(h.Uh4}q(h6]h7]h8]h9]h;]uh/hxh)]qcdocutils.nodes reference q)q}q(h.Uh4}q(h9]qhGah8]h6]h7]h;]Urefidh%uh/h}h)]qhIX"Immutability of Content in DataONEqq}q(h.hCh/hubah2U referencequbah2U paragraphqubhq)q}q(h.Uh4}q(h6]h7]h8]h9]h;]uh/hxh)]q(hw)q}q(h.Uh4}q(h6]h7]h8]h9]h;]uh/hh)]qh|)q}q(h.Uh4}q(h6]h7]h8]h9]h;]uh/hh)]qh)q}q(h.Uh4}q(h9]qUid2qah8]h6]h7]h;]Urefidh uh/hh)]qhIXOverviewqq}q(h.XOverviewqh/hubah2hubah2hubah2U list_itemqubhw)q}q(h.Uh4}q(h6]h7]h8]h9]h;]uh/hh)]qh|)q}q(h.Uh4}q(h6]h7]h8]h9]h;]uh/hh)]qh)q}q(h.Uh4}q(h9]qUid3qah8]h6]h7]h;]Urefidhuh/hh)]qhIX#Changes constituting a new snapshotqq}q(h.X#Changes constituting a new snapshotqh/hubah2hubah2hubah2hubhw)q}q(h.Uh4}q(h6]h7]h8]h9]h;]uh/hh)]qh|)q}q(h.Uh4}q(h6]h7]h8]h9]h;]uh/hh)]qh)q}q(h.Uh4}q(h9]qUid4qah8]h6]h7]h;]Urefidh'uh/hh)]qhIX!Changes constituting a new seriesqÅq}q(h.X!Changes constituting a new seriesqh/hubah2hubah2hubah2hubhw)q}q(h.Uh4}q(h6]h7]h8]h9]h;]uh/hh)]qh|)q}q(h.Uh4}q(h6]h7]h8]h9]h;]uh/hh)]qh)q}q(h.Uh4}q(h9]qUid5qah8]h6]h7]h;]Urefidh#uh/hh)]qhIXUsage ConventionsqՅq}q(h.XUsage Conventionsqh/hubah2hubah2hubah2hubhw)q}q(h.Uh4}q(h6]h7]h8]h9]h;]uh/hh)]qh|)q}q(h.Uh4}q(h6]h7]h8]h9]h;]uh/hh)]qh)q}q(h.Uh4}q(h9]qUid6qah8]h6]h7]h;]Urefidh!uh/hh)]qhIXAggregating Download Statisticsq煁q}q(h.XAggregating Download Statisticsqh/hubah2hubah2hubah2hubhw)q}q(h.Uh4}q(h6]h7]h8]h9]h;]uh/hh)]qh|)q}q(h.Uh4}q(h6]h7]h8]h9]h;]uh/hh)]qh)q}q(h.Uh4}q(h9]qUid7qah8]h6]h7]h;]Urefidh$uh/hh)]qhIX%Identifier resolution in DataONE APIsqq}q(h.X%Identifier resolution in DataONE APIsqh/hubah2hubah2hubah2hubhw)q}q(h.Uh4}q(h6]h7]h8]h9]h;]uh/hh)]rh|)r}r(h.Uh4}r(h6]h7]h8]h9]h;]uh/hh)]rh)r}r(h.Uh4}r(h9]rUid8r ah8]h6]h7]h;]Urefidhuh/jh)]r hIX1Series Identifier resolution to the head revisionr r }r (h.X1Series Identifier resolution to the head revisionrh/jubah2hubah2hubah2hubhw)r}r(h.Uh4}r(h6]h7]h8]h9]h;]uh/hh)]rh|)r}r(h.Uh4}r(h6]h7]h8]h9]h;]uh/jh)]rh)r}r(h.Uh4}r(h9]rUid9rah8]h6]h7]h;]Urefidhuh/jh)]rhIX!Importance of the obsolete fieldsrr}r(h.X!Importance of the obsolete fieldsr h/jubah2hubah2hubah2hubhw)r!}r"(h.Uh4}r#(h6]h7]h8]h9]h;]uh/hh)]r$h|)r%}r&(h.Uh4}r'(h6]h7]h8]h9]h;]uh/j!h)]r(h)r)}r*(h.Uh4}r+(h9]r,Uid10r-ah8]h6]h7]h;]Urefidh"uh/j%h)]r.hIXMutable Member Node exampler/r0}r1(h.XMutable Member Node exampler2h/j)ubah2hubah2hubah2hubeh2htubeh2hubhw)r3}r4(h.Uh4}r5(h6]h7]h8]h9]h;]uh/hrh)]r6h|)r7}r8(h.Uh4}r9(h6]h7]h8]h9]h;]uh/j3h)]r:h)r;}r<(h.Uh4}r=(h9]r>Uid11r?ah8]h6]h7]h;]Urefidh&uh/j7h)]r@hIXSummaryrArB}rC(h.XSummaryrDh/j;ubah2hubah2hubah2hubeubeubh+)rE}rF(h.Uh/h,h0h1h2h3h4}rG(h6]h7]h8]h9]rHh ah;]rIh auh=K h>hh)]rJ(h@)rK}rL(h.hh/jEh0h1h2hDh4}rM(h9]h8]h6]h7]h;]hFhuh=K h>hh)]rNhIXOverviewrOrP}rQ(h.hh/jKubaubh|)rR}rS(h.X-To support the goals of `preservation and scientific reproducibility `_, all registered objects in DataONE are considered immutable, with each object representing a published snapshot of data or metadata associated with a specific time. DataONE manages the registration, indexing, and replication of these snapshots throughout the DataONE network of Member Nodes. Upon this foundation, DataONE can guarantee that the exact byte array returned through the DataONE Read APIs (MNRead and CNRead) is the one submitted and registered.h/jEh0h1h2hh4}rT(h6]h7]h8]h9]h;]uh=K h>hh)]rU(hIXTo support the goals of rVrW}rX(h.XTo support the goals of h/jRubh)rY}rZ(h.XJ`preservation and scientific reproducibility `_h4}r[(UnameX+preservation and scientific reproducibilityUrefurir\XPreservationStrategy.htmlr]h9]h8]h6]h7]h;]uh/jRh)]r^hIX+preservation and scientific reproducibilityr_r`}ra(h.Uh/jYubah2hubhX)rb}rc(h.X U referencedrdKh/jRh2h[h4}re(Urefurij]h9]rfhah8]h6]h7]h;]rghauh)]ubhIX, all registered objects in DataONE are considered immutable, with each object representing a published snapshot of data or metadata associated with a specific time. DataONE manages the registration, indexing, and replication of these snapshots throughout the DataONE network of Member Nodes. Upon this foundation, DataONE can guarantee that the exact byte array returned through the DataONE Read APIs (MNRead and CNRead) is the one submitted and registered.rhri}rj(h.X, all registered objects in DataONE are considered immutable, with each object representing a published snapshot of data or metadata associated with a specific time. DataONE manages the registration, indexing, and replication of these snapshots throughout the DataONE network of Member Nodes. Upon this foundation, DataONE can guarantee that the exact byte array returned through the DataONE Read APIs (MNRead and CNRead) is the one submitted and registered.h/jRubeubh|)rk}rl(h.XWAny repository that provides unique identifiers to snapshots (or revisions) can participate as DataONE Member Nodes, irrespective of whether or not they retain past snapshots. This is accomplished by the use of two identifiers, one representing the revision, and the other representing the changing (or mutable) entity. For those Member Nodes only managing the mutable entity, as long as a unique revision-level identifier is generated upon each update to the entity, DataONE will not reject the update. In situations where the rate of change is faster than DataONE's Member Node synchronization, it is possible that some snapshots will fail to be registered. However, since that revision's unique identifier is never indexed or otherwise made available, the chance for needing to retrieve that snapshot (and not finding it) in the future is very small.rmh/jEh0h1h2hh4}rn(h6]h7]h8]h9]h;]uh=Kh>hh)]rohIXWAny repository that provides unique identifiers to snapshots (or revisions) can participate as DataONE Member Nodes, irrespective of whether or not they retain past snapshots. This is accomplished by the use of two identifiers, one representing the revision, and the other representing the changing (or mutable) entity. For those Member Nodes only managing the mutable entity, as long as a unique revision-level identifier is generated upon each update to the entity, DataONE will not reject the update. In situations where the rate of change is faster than DataONE's Member Node synchronization, it is possible that some snapshots will fail to be registered. However, since that revision's unique identifier is never indexed or otherwise made available, the chance for needing to retrieve that snapshot (and not finding it) in the future is very small.rprq}rr(h.jmh/jkubaubh|)rs}rt(h.X!The two identifiers are known as:ruh/jEh0h1h2hh4}rv(h6]h7]h8]h9]h;]uh=K h>hh)]rwhIX!The two identifiers are known as:rxry}rz(h.juh/jsubaubcdocutils.nodes definition_list r{)r|}r}(h.Uh/jEh0h1h2Udefinition_listr~h4}r(h6]h7]h8]h9]h;]uh=Nh>hh)]r(cdocutils.nodes definition_list_item r)r}r(h.X**Persistent Identifier (PID)** declared in the ``systemMetadata.identifier`` field. This identifier represents the snapshot or revision DataONE replicates among the DataONE federation. h/j|h0h1h2Udefinition_list_itemrh4}r(h6]h7]h8]h9]h;]uh=K$h)]r(cdocutils.nodes term r)r}r(h.X**Persistent Identifier (PID)**rh/jh0h1h2Utermrh4}r(h6]h7]h8]h9]h;]uh=K$h)]rcdocutils.nodes strong r)r}r(h.jh4}r(h6]h7]h8]h9]h;]uh/jh)]rhIXPersistent Identifier (PID)rr}r(h.Uh/jubah2Ustrongrubaubcdocutils.nodes definition r)r}r(h.Uh4}r(h6]h7]h8]h9]h;]uh/jh)]rh|)r}r(h.Xdeclared in the ``systemMetadata.identifier`` field. This identifier represents the snapshot or revision DataONE replicates among the DataONE federation.h/jh0h1h2hh4}r(h6]h7]h8]h9]h;]uh=K#h)]r(hIXdeclared in the rr}r(h.Xdeclared in the h/jubcdocutils.nodes literal r)r}r(h.X``systemMetadata.identifier``h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIXsystemMetadata.identifierrr}r(h.Uh/jubah2UliteralrubhIXl field. This identifier represents the snapshot or revision DataONE replicates among the DataONE federation.rr}r(h.Xl field. This identifier represents the snapshot or revision DataONE replicates among the DataONE federation.h/jubeubah2U definitionrubeubj)r}r(h.X**Series Identifier (SID)** declared in the ``systemMetadata.seriesId`` field. This identifier represents the mutable content, and resolves to the latest revision among all registered revisions when used in the DataONE Read APIs. h/j|h0h1h2jh4}r(h6]h7]h8]h9]h;]uh=K)h>hh)]r(j)r}r(h.X**Series Identifier (SID)**rh/jh0h1h2jh4}r(h6]h7]h8]h9]h;]uh=K)h)]rj)r}r(h.jh4}r(h6]h7]h8]h9]h;]uh/jh)]rhIXSeries Identifier (SID)rr}r(h.Uh/jubah2jubaubj)r}r(h.Uh4}r(h6]h7]h8]h9]h;]uh/jh)]rh|)r}r(h.Xdeclared in the ``systemMetadata.seriesId`` field. This identifier represents the mutable content, and resolves to the latest revision among all registered revisions when used in the DataONE Read APIs.h/jh0h1h2hh4}r(h6]h7]h8]h9]h;]uh=K'h)]r(hIXdeclared in the rr}r(h.Xdeclared in the h/jubj)r}r(h.X``systemMetadata.seriesId``h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIXsystemMetadata.seriesIdrr}r(h.Uh/jubah2jubhIX field. This identifier represents the mutable content, and resolves to the latest revision among all registered revisions when used in the DataONE Read APIs.rr}r(h.X field. This identifier represents the mutable content, and resolves to the latest revision among all registered revisions when used in the DataONE Read APIs.h/jubeubah2jubeubeubh|)r}r(h.XDataONE relies on content originators to generate the identifiers they use for each snapshot (with the series identifier being optional) being registered, and determining which field will hold the "citable" identifier.rh/jEh0h1h2hh4}r(h6]h7]h8]h9]h;]uh=K+h>hh)]rhIXDataONE relies on content originators to generate the identifiers they use for each snapshot (with the series identifier being optional) being registered, and determining which field will hold the "citable" identifier.rr}r(h.jh/jubaubeubh+)r}r(h.Uh/h,h0h1h2h3h4}r(h6]h7]h8]h9]rhah;]rhauh=K1h>hh)]r(h@)r}r(h.hh/jh0h1h2hDh4}r(h9]h8]h6]h7]h;]hFhuh=K1h>hh)]rhIX#Changes constituting a new snapshotrr}r(h.hh/jubaubh|)r}r(h.XRDataONE considers any change that results in a different byte array of content to be a new snapshot, and thus a new object to be registered. Subtle changes, such as whitespace differences, although potentially meaningless, do therefore constitute a new object. If not properly identified with a new PID, the content held on that Member Node is invalid. Member Nodes that periodically regenerate their stored content or manipulate it upon retrieval will need to take extra care to validate checksums after regeneration or manipulation and resolve any discrepancies in content they may encounter.rh/jh0h1h2hh4}r(h6]h7]h8]h9]h;]uh=K2h>hh)]rhIXRDataONE considers any change that results in a different byte array of content to be a new snapshot, and thus a new object to be registered. Subtle changes, such as whitespace differences, although potentially meaningless, do therefore constitute a new object. If not properly identified with a new PID, the content held on that Member Node is invalid. Member Nodes that periodically regenerate their stored content or manipulate it upon retrieval will need to take extra care to validate checksums after regeneration or manipulation and resolve any discrepancies in content they may encounter.rr}r(h.jh/jubaubeubh+)r}r(h.Uh/h,h0h1h2h3h4}r(h6]h7]h8]h9]rh'ah;]rhauh=K=h>hh)]r(h@)r}r(h.hh/jh0h1h2hDh4}r(h9]h8]h6]h7]h;]hFhuh=K=h>hh)]rhIX!Changes constituting a new seriesrr}r(h.hh/jubaubh|)r}r(h.XtThe SID is provided expressly to group the snapshots of a single entity that is stable over time. It was not intended to represent highly volatile entities, or those that significantly "drift" over time. Member Nodes are encouraged to instead use registered services for volatile content, and create new entities when significant change in the scope of an entity occurs.rh/jh0h1h2hh4}r(h6]h7]h8]h9]h;]uh=K>h>hh)]rhIXtThe SID is provided expressly to group the snapshots of a single entity that is stable over time. It was not intended to represent highly volatile entities, or those that significantly "drift" over time. Member Nodes are encouraged to instead use registered services for volatile content, and create new entities when significant change in the scope of an entity occurs.rr}r(h.jh/jubaubh|)r}r(h.X7It is not clear that individual contributers will always have the means to register a service, and so may have entities organized for input, such as a file that accumulates observations. If items such as these are registered as an object, the rightsHolders should be mindful to apply reasonable temporal bounds.r h/jh0h1h2hh4}r (h6]h7]h8]h9]h;]uh=KDh>hh)]r hIX7It is not clear that individual contributers will always have the means to register a service, and so may have entities organized for input, such as a file that accumulates observations. If items such as these are registered as an object, the rightsHolders should be mindful to apply reasonable temporal bounds.r r }r(h.j h/jubaubh|)r}r(h.XtWhen the scope of an item has changed significantly, it is permissible to supply a new seriesId to the next snapshot while still relating the two items by obsoletes and obsoletedBy. However, it is not necessary, and may be more straightforward to simply save the new entity without relating the snapshots through system metadata, but through provenance mechanisms instead.rh/jh0h1h2hh4}r(h6]h7]h8]h9]h;]uh=KIh>hh)]rhIXtWhen the scope of an item has changed significantly, it is permissible to supply a new seriesId to the next snapshot while still relating the two items by obsoletes and obsoletedBy. However, it is not necessary, and may be more straightforward to simply save the new entity without relating the snapshots through system metadata, but through provenance mechanisms instead.rr}r(h.jh/jubaubeubh+)r}r(h.Uh/h,h0h1h2h3h4}r(h6]h7]h8]h9]rh#ah;]rh auh=KQh>hh)]r(h@)r}r(h.hh/jh0h1h2hDh4}r(h9]h8]h6]h7]h;]hFhuh=KQh>hh)]r hIXUsage Conventionsr!r"}r#(h.hh/jubaubh|)r$}r%(h.XDataONE anticipates data consumers using other contributors' data will prefer to cite using the PID, for the certainty that provides, and will prefer using the SID when citing indirectly (when citing metadata). Similarly, we anticipate content originators will wish to promote one identifier for citation. For those content providers using both identifiers, it is recommended to assign the preferred identifier according to anticipated data consumer preference.r&h/jh0h1h2hh4}r'(h6]h7]h8]h9]h;]uh=KRh>hh)]r(hIXDataONE anticipates data consumers using other contributors' data will prefer to cite using the PID, for the certainty that provides, and will prefer using the SID when citing indirectly (when citing metadata). Similarly, we anticipate content originators will wish to promote one identifier for citation. For those content providers using both identifiers, it is recommended to assign the preferred identifier according to anticipated data consumer preference.r)r*}r+(h.j&h/j$ubaubeubh+)r,}r-(h.Uh/h,h0h1h2h3h4}r.(h6]h7]h8]h9]r/h!ah;]r0h auh=K[h>hh)]r1(h@)r2}r3(h.hh/j,h0h1h2hDh4}r4(h9]h8]h6]h7]h;]hFhuh=K[h>hh)]r5hIXAggregating Download Statisticsr6r7}r8(h.hh/j2ubaubh|)r9}r:(h.XTo aid in aggregating download statistics for data providers, DataONE provides the ``cn/v2/query/logsolr`` query endpoint. Both PID and SID field are included in the index records to allow straightforward retrieval of download statistics by either field.h/j,h0h1h2hh4}r;(h6]h7]h8]h9]h;]uh=K\h>hh)]r<(hIXSTo aid in aggregating download statistics for data providers, DataONE provides the r=r>}r?(h.XSTo aid in aggregating download statistics for data providers, DataONE provides the h/j9ubj)r@}rA(h.X``cn/v2/query/logsolr``h4}rB(h6]h7]h8]h9]h;]uh/j9h)]rChIXcn/v2/query/logsolrrDrE}rF(h.Uh/j@ubah2jubhIX query endpoint. Both PID and SID field are included in the index records to allow straightforward retrieval of download statistics by either field.rGrH}rI(h.X query endpoint. Both PID and SID field are included in the index records to allow straightforward retrieval of download statistics by either field.h/j9ubeubeubh+)rJ}rK(h.Uh/h,h0h1h2h3h4}rL(h6]h7]h8]h9]rMh$ah;]rNhauh=Kbh>hh)]rO(h@)rP}rQ(h.hh/jJh0h1h2hDh4}rR(h9]h8]h6]h7]h;]hFhuh=Kbh>hh)]rShIX%Identifier resolution in DataONE APIsrTrU}rV(h.hh/jPubaubh|)rW}rX(h.X All DataONE APIs accepting an Identifier must treat PIDs as requests for the exact snapshot, and SIDs as a request for the latest snapshot that DataONE Node has knowledge of. Due to the distributed nature of snapshot replication, it is possible that a replica Member Node not know about the latest snapshot, in which case, a request by SID to that node should give a previous snapshot. For all nodes, even the authoritative Member Node, a request by PID for a snapshot that it doesn't host must return a NotFound exception.rYh/jJh0h1h2hh4}rZ(h6]h7]h8]h9]h;]uh=Kch>hh)]r[hIX All DataONE APIs accepting an Identifier must treat PIDs as requests for the exact snapshot, and SIDs as a request for the latest snapshot that DataONE Node has knowledge of. Due to the distributed nature of snapshot replication, it is possible that a replica Member Node not know about the latest snapshot, in which case, a request by SID to that node should give a previous snapshot. For all nodes, even the authoritative Member Node, a request by PID for a snapshot that it doesn't host must return a NotFound exception.r\r]}r^(h.jYh/jWubaubh|)r_}r`(h.XEnd users should therefore rely on ``v2.cn.resolve`` for object retrieval. If the Identifier used for the resolve is a SID, this method will return an ObjectLocationList for the latest known snapshot.h/jJh0h1h2hh4}ra(h6]h7]h8]h9]h;]uh=Kkh>hh)]rb(hIX#End users should therefore rely on rcrd}re(h.X#End users should therefore rely on h/j_ubj)rf}rg(h.X``v2.cn.resolve``h4}rh(h6]h7]h8]h9]h;]uh/j_h)]rihIX v2.cn.resolverjrk}rl(h.Uh/jfubah2jubhIX for object retrieval. If the Identifier used for the resolve is a SID, this method will return an ObjectLocationList for the latest known snapshot.rmrn}ro(h.X for object retrieval. If the Identifier used for the resolve is a SID, this method will return an ObjectLocationList for the latest known snapshot.h/j_ubeubeubh+)rp}rq(h.Uh/h,h0h1h2h3h4}rr(h6]h7]h8]h9]rshah;]rth auh=Kqh>hh)]ru(h@)rv}rw(h.jh/jph0h1h2hDh4}rx(h9]h8]h6]h7]h;]hFj uh=Kqh>hh)]ryhIX1Series Identifier resolution to the head revisionrzr{}r|(h.jh/jvubaubh|)r}}r~(h.XThe primary way for determining the head of a series is via the ``obsoletedBy`` field in the system metadata that links to the next snapshot in the chain. With all of the snapshots synchronized, there should only be one of the series that is not obsolete, and that is the head. With incomplete synchronization, there will be possibly more than one snapshot that is not obsoleted, and in these cases, the one with the latest ``dateUploaded`` value will be chosen as the head.h/jph0h1h2hh4}r(h6]h7]h8]h9]h;]uh=Krh>hh)]r(hIX@The primary way for determining the head of a series is via the rr}r(h.X@The primary way for determining the head of a series is via the h/j}ubj)r}r(h.X``obsoletedBy``h4}r(h6]h7]h8]h9]h;]uh/j}h)]rhIX obsoletedByrr}r(h.Uh/jubah2jubhIXZ field in the system metadata that links to the next snapshot in the chain. With all of the snapshots synchronized, there should only be one of the series that is not obsolete, and that is the head. With incomplete synchronization, there will be possibly more than one snapshot that is not obsoleted, and in these cases, the one with the latest rr}r(h.XZ field in the system metadata that links to the next snapshot in the chain. With all of the snapshots synchronized, there should only be one of the series that is not obsolete, and that is the head. With incomplete synchronization, there will be possibly more than one snapshot that is not obsoleted, and in these cases, the one with the latest h/j}ubj)r}r(h.X``dateUploaded``h4}r(h6]h7]h8]h9]h;]uh/j}h)]rhIX dateUploadedrr}r(h.Uh/jubah2jubhIX" value will be chosen as the head.rr}r(h.X" value will be chosen as the head.h/j}ubeubh|)r}r(h.XUse of the obsoleted fields as the primary indicator for the head of the series is preferred because it is a direct reflection of the rightsHolder's intentions, whereas the ``dateUploaded`` value is only a reflection of the order in which the Member Node processes uploaded content.h/jph0h1h2hh4}r(h6]h7]h8]h9]h;]uh=Kyh>hh)]r(hIXUse of the obsoleted fields as the primary indicator for the head of the series is preferred because it is a direct reflection of the rightsHolder's intentions, whereas the rr}r(h.XUse of the obsoleted fields as the primary indicator for the head of the series is preferred because it is a direct reflection of the rightsHolder's intentions, whereas the h/jubj)r}r(h.X``dateUploaded``h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIX dateUploadedrr}r(h.Uh/jubah2jubhIX] value is only a reflection of the order in which the Member Node processes uploaded content.rr}r(h.X] value is only a reflection of the order in which the Member Node processes uploaded content.h/jubeubeubh+)r}r(h.Uh/h,h0h1h2h3h4}r(h6]h7]h8]h9]rhah;]rhauh=Kh>hh)]r(h@)r}r(h.j h/jh0h1h2hDh4}r(h9]h8]h6]h7]h;]hFjuh=Kh>hh)]rhIX!Importance of the obsolete fieldsrr}r(h.j h/jubaubh|)r}r(h.X=Member Nodes that manage by mutable entity (don't preserve prior snapshots) should populate the ``obsoletes`` and ``obsoletedBy`` fields, even if they do not plan to preserve older snapshots. Replica nodes and the DataONE Coordinating Nodes can use these fields to optimize queries for finding the head of the series.h/jh0h1h2hh4}r(h6]h7]h8]h9]h;]uh=Kh>hh)]r(hIX`Member Nodes that manage by mutable entity (don't preserve prior snapshots) should populate the rr}r(h.X`Member Nodes that manage by mutable entity (don't preserve prior snapshots) should populate the h/jubj)r}r(h.X ``obsoletes``h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIX obsoletesrr}r(h.Uh/jubah2jubhIX and rr}r(h.X and h/jubj)r}r(h.X``obsoletedBy``h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIX obsoletedByrr}r(h.Uh/jubah2jubhIX fields, even if they do not plan to preserve older snapshots. Replica nodes and the DataONE Coordinating Nodes can use these fields to optimize queries for finding the head of the series.rr}r(h.X fields, even if they do not plan to preserve older snapshots. Replica nodes and the DataONE Coordinating Nodes can use these fields to optimize queries for finding the head of the series.h/jubeubh|)r}r(h.X*Question: should mutable Member Nodes keep systemMetadata documents for snapshots they no longer have? (it would allow the obsoletedBy fields to be synchronized, but would it be in conflict with the behavior of deleted items (and would it matter?)*rh/jh0h1h2hh4}r(h6]h7]h8]h9]h;]uh=Kh>hh)]rcdocutils.nodes emphasis r)r}r(h.jh4}r(h6]h7]h8]h9]h;]uh/jh)]rhIXQuestion: should mutable Member Nodes keep systemMetadata documents for snapshots they no longer have? (it would allow the obsoletedBy fields to be synchronized, but would it be in conflict with the behavior of deleted items (and would it matter?)rr}r(h.Uh/jubah2Uemphasisrubaubeubh+)r}r(h.Uh/h,h0h1h2h3h4}r(h6]h7]h8]h9]rh"ah;]rh auh=Kh>hh)]r(h@)r}r(h.j2h/jh0h1h2hDh4}r(h9]h8]h6]h7]h;]hFj-uh=Kh>hh)]rhIXMutable Member Node examplerr}r(h.j2h/jubaubh|)r}r(h.X[To illustrate by way of example, author **A** uploads an item to Member Node **M**, with an identifier **S** not using the DataONE API, but with **M**'s primary API. **M** builds a systemMetadata document for **S**, generating a PID, **P1**, to uniquely identify the initial snapshot, and assigns an upload date of **D1**, and uses the identifier **S** for the seriesId. DataONE synchronizes the object, and replicates the snapshot **P1** to one other Member Node **R1**. The author, **A**, then saves changes to the item, whereupon **M** generates another PID, **P2**, to uniquely identifier this newer snapshot, uses **S** in the seriesId field, puts **P1** in the obsoletes field, and **D2** in the dateUploaded field. (size and checksum are also calculated for the new snapshot.) This is synchronized and replicated to a different Member Node, **R2**.h/jh0h1h2hh4}r(h6]h7]h8]h9]h;]uh=Kh>hh)]r(hIX(To illustrate by way of example, author rr}r(h.X(To illustrate by way of example, author h/jubj)r}r(h.X**A**h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIXAr}r(h.Uh/jubah2jubhIX uploads an item to Member Node rr}r(h.X uploads an item to Member Node h/jubj)r}r(h.X**M**h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIXMr}r(h.Uh/jubah2jubhIX, with an identifier rr}r(h.X, with an identifier h/jubj)r}r(h.X**S**h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIXSr }r (h.Uh/jubah2jubhIX% not using the DataONE API, but with r r }r (h.X% not using the DataONE API, but with h/jubj)r}r(h.X**M**h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIXMr}r(h.Uh/jubah2jubhIX's primary API. rr}r(h.X's primary API. h/jubj)r}r(h.X**M**h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIXMr}r(h.Uh/jubah2jubhIX& builds a systemMetadata document for rr}r(h.X& builds a systemMetadata document for h/jubj)r }r!(h.X**S**h4}r"(h6]h7]h8]h9]h;]uh/jh)]r#hIXSr$}r%(h.Uh/j ubah2jubhIX, generating a PID, r&r'}r((h.X, generating a PID, h/jubj)r)}r*(h.X**P1**h4}r+(h6]h7]h8]h9]h;]uh/jh)]r,hIXP1r-r.}r/(h.Uh/j)ubah2jubhIXK, to uniquely identify the initial snapshot, and assigns an upload date of r0r1}r2(h.XK, to uniquely identify the initial snapshot, and assigns an upload date of h/jubj)r3}r4(h.X**D1**h4}r5(h6]h7]h8]h9]h;]uh/jh)]r6hIXD1r7r8}r9(h.Uh/j3ubah2jubhIX, and uses the identifier r:r;}r<(h.X, and uses the identifier h/jubj)r=}r>(h.X**S**h4}r?(h6]h7]h8]h9]h;]uh/jh)]r@hIXSrA}rB(h.Uh/j=ubah2jubhIXQ for the seriesId. DataONE synchronizes the object, and replicates the snapshot rCrD}rE(h.XQ for the seriesId. DataONE synchronizes the object, and replicates the snapshot h/jubj)rF}rG(h.X**P1**h4}rH(h6]h7]h8]h9]h;]uh/jh)]rIhIXP1rJrK}rL(h.Uh/jFubah2jubhIX to one other Member Node rMrN}rO(h.X to one other Member Node h/jubj)rP}rQ(h.X**R1**h4}rR(h6]h7]h8]h9]h;]uh/jh)]rShIXR1rTrU}rV(h.Uh/jPubah2jubhIX. The author, rWrX}rY(h.X. The author, h/jubj)rZ}r[(h.X**A**h4}r\(h6]h7]h8]h9]h;]uh/jh)]r]hIXAr^}r_(h.Uh/jZubah2jubhIX,, then saves changes to the item, whereupon r`ra}rb(h.X,, then saves changes to the item, whereupon h/jubj)rc}rd(h.X**M**h4}re(h6]h7]h8]h9]h;]uh/jh)]rfhIXMrg}rh(h.Uh/jcubah2jubhIX generates another PID, rirj}rk(h.X generates another PID, h/jubj)rl}rm(h.X**P2**h4}rn(h6]h7]h8]h9]h;]uh/jh)]rohIXP2rprq}rr(h.Uh/jlubah2jubhIX3, to uniquely identifier this newer snapshot, uses rsrt}ru(h.X3, to uniquely identifier this newer snapshot, uses h/jubj)rv}rw(h.X**S**h4}rx(h6]h7]h8]h9]h;]uh/jh)]ryhIXSrz}r{(h.Uh/jvubah2jubhIX in the seriesId field, puts r|r}}r~(h.X in the seriesId field, puts h/jubj)r}r(h.X**P1**h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIXP1rr}r(h.Uh/jubah2jubhIX in the obsoletes field, and rr}r(h.X in the obsoletes field, and h/jubj)r}r(h.X**D2**h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIXD2rr}r(h.Uh/jubah2jubhIX in the dateUploaded field. (size and checksum are also calculated for the new snapshot.) This is synchronized and replicated to a different Member Node, rr}r(h.X in the dateUploaded field. (size and checksum are also calculated for the new snapshot.) This is synchronized and replicated to a different Member Node, h/jubj)r}r(h.X**R2**h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIXR2rr}r(h.Uh/jubah2jubhIX.r}r(h.X.h/jubeubh|)r}r(h.XWhen ``v2.cn.resolve(S`)`` is called, an ObjectLocationList for **P2** is returned, listing Member Nodes **M** and **R2** as locations for retrieval. A call to ``M.get(P2)`` or ``R2.get(P2)`` will return the latest snapshot, as will the same call using **S** as the identifier instead. However, a call to ``R1.get(P2)`` will return NotFound, because it was not a replication target for that snapshot, and a call to ``R1.get(S)`` will return the initial snapshot, because it has snapshot **P1** with the associated seriesId **S**.h/jh0h1h2hh4}r(h6]h7]h8]h9]h;]uh=Kh>hh)]r(hIXWhen rr}r(h.XWhen h/jubj)r}r(h.X``v2.cn.resolve(S`)``h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIXv2.cn.resolve(S`)rr}r(h.Uh/jubah2jubhIX& is called, an ObjectLocationList for rr}r(h.X& is called, an ObjectLocationList for h/jubj)r}r(h.X**P2**h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIXP2rr}r(h.Uh/jubah2jubhIX# is returned, listing Member Nodes rr}r(h.X# is returned, listing Member Nodes h/jubj)r}r(h.X**M**h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIXMr}r(h.Uh/jubah2jubhIX and rr}r(h.X and h/jubj)r}r(h.X**R2**h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIXR2rr}r(h.Uh/jubah2jubhIX( as locations for retrieval. A call to rr}r(h.X( as locations for retrieval. A call to h/jubj)r}r(h.X ``M.get(P2)``h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIX M.get(P2)rr}r(h.Uh/jubah2jubhIX or rr}r(h.X or h/jubj)r}r(h.X``R2.get(P2)``h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIX R2.get(P2)rr}r(h.Uh/jubah2jubhIX> will return the latest snapshot, as will the same call using rr}r(h.X> will return the latest snapshot, as will the same call using h/jubj)r}r(h.X**S**h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIXSr}r(h.Uh/jubah2jubhIX0 as the identifier instead. However, a call to rr}r(h.X0 as the identifier instead. However, a call to h/jubj)r}r(h.X``R1.get(P2)``h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIX R1.get(P2)rr}r(h.Uh/jubah2jubhIX` will return NotFound, because it was not a replication target for that snapshot, and a call to rr}r(h.X` will return NotFound, because it was not a replication target for that snapshot, and a call to h/jubj)r}r(h.X ``R1.get(S)``h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIX R1.get(S)rr}r(h.Uh/jubah2jubhIX; will return the initial snapshot, because it has snapshot rr}r(h.X; will return the initial snapshot, because it has snapshot h/jubj)r}r(h.X**P1**h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIXP1rr}r(h.Uh/jubah2jubhIX with the associated seriesId rr}r(h.X with the associated seriesId h/jubj)r}r(h.X**S**h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIXSr }r (h.Uh/jubah2jubhIX.r }r (h.X.h/jubeubh|)r }r(h.XQNotice, too, that ``v2.cn.resolve(P1)`` will return an ObjectLocationList containing both **M** and **R1**, although retrieval from **M** is no longer possible, since **M** doesn't preserve past snapshots. ``M.get(P1)`` should return a NotFound, and the client will move on to **R1**, and be able to retrieve **P1** with ``R1.get(P1)``.h/jh0h1h2hh4}r(h6]h7]h8]h9]h;]uh=Kh>hh)]r(hIXNotice, too, that rr}r(h.XNotice, too, that h/j ubj)r}r(h.X``v2.cn.resolve(P1)``h4}r(h6]h7]h8]h9]h;]uh/j h)]rhIXv2.cn.resolve(P1)rr}r(h.Uh/jubah2jubhIX3 will return an ObjectLocationList containing both rr}r(h.X3 will return an ObjectLocationList containing both h/j ubj)r}r(h.X**M**h4}r (h6]h7]h8]h9]h;]uh/j h)]r!hIXMr"}r#(h.Uh/jubah2jubhIX and r$r%}r&(h.X and h/j ubj)r'}r((h.X**R1**h4}r)(h6]h7]h8]h9]h;]uh/j h)]r*hIXR1r+r,}r-(h.Uh/j'ubah2jubhIX, although retrieval from r.r/}r0(h.X, although retrieval from h/j ubj)r1}r2(h.X**M**h4}r3(h6]h7]h8]h9]h;]uh/j h)]r4hIXMr5}r6(h.Uh/j1ubah2jubhIX is no longer possible, since r7r8}r9(h.X is no longer possible, since h/j ubj)r:}r;(h.X**M**h4}r<(h6]h7]h8]h9]h;]uh/j h)]r=hIXMr>}r?(h.Uh/j:ubah2jubhIX# doesn't preserve past snapshots. r@rA}rB(h.X# doesn't preserve past snapshots. h/j ubj)rC}rD(h.X ``M.get(P1)``h4}rE(h6]h7]h8]h9]h;]uh/j h)]rFhIX M.get(P1)rGrH}rI(h.Uh/jCubah2jubhIX: should return a NotFound, and the client will move on to rJrK}rL(h.X: should return a NotFound, and the client will move on to h/j ubj)rM}rN(h.X**R1**h4}rO(h6]h7]h8]h9]h;]uh/j h)]rPhIXR1rQrR}rS(h.Uh/jMubah2jubhIX, and be able to retrieve rTrU}rV(h.X, and be able to retrieve h/j ubj)rW}rX(h.X**P1**h4}rY(h6]h7]h8]h9]h;]uh/j h)]rZhIXP1r[r\}r](h.Uh/jWubah2jubhIX with r^r_}r`(h.X with h/j ubj)ra}rb(h.X``R1.get(P1)``h4}rc(h6]h7]h8]h9]h;]uh/j h)]rdhIX R1.get(P1)rerf}rg(h.Uh/jaubah2jubhIX.rh}ri(h.X.h/j ubeubh|)rj}rk(h.XThe CN, when ``v2.cn.resolve(S)`` was called, determined the head of the series by first finding all of the snapshots where the seriesId is **S**, and obsoletedBy is null or the obsoletedBy object has a different seriesId. In this case, since the **P1** systemMetadata is never updated to fill in the obsoletedBy field, the algorithm will get both **P1** and **P2**. It will then notice that **P2** has the later date of **D2**, so will choose **P2** as the head of the series.h/jh0h1h2hh4}rl(h6]h7]h8]h9]h;]uh=Kh>hh)]rm(hIX The CN, when rnro}rp(h.X The CN, when h/jjubj)rq}rr(h.X``v2.cn.resolve(S)``h4}rs(h6]h7]h8]h9]h;]uh/jjh)]rthIXv2.cn.resolve(S)rurv}rw(h.Uh/jqubah2jubhIXk was called, determined the head of the series by first finding all of the snapshots where the seriesId is rxry}rz(h.Xk was called, determined the head of the series by first finding all of the snapshots where the seriesId is h/jjubj)r{}r|(h.X**S**h4}r}(h6]h7]h8]h9]h;]uh/jjh)]r~hIXSr}r(h.Uh/j{ubah2jubhIXf, and obsoletedBy is null or the obsoletedBy object has a different seriesId. In this case, since the rr}r(h.Xf, and obsoletedBy is null or the obsoletedBy object has a different seriesId. In this case, since the h/jjubj)r}r(h.X**P1**h4}r(h6]h7]h8]h9]h;]uh/jjh)]rhIXP1rr}r(h.Uh/jubah2jubhIX_ systemMetadata is never updated to fill in the obsoletedBy field, the algorithm will get both rr}r(h.X_ systemMetadata is never updated to fill in the obsoletedBy field, the algorithm will get both h/jjubj)r}r(h.X**P1**h4}r(h6]h7]h8]h9]h;]uh/jjh)]rhIXP1rr}r(h.Uh/jubah2jubhIX and rr}r(h.X and h/jjubj)r}r(h.X**P2**h4}r(h6]h7]h8]h9]h;]uh/jjh)]rhIXP2rr}r(h.Uh/jubah2jubhIX. It will then notice that rr}r(h.X. It will then notice that h/jjubj)r}r(h.X**P2**h4}r(h6]h7]h8]h9]h;]uh/jjh)]rhIXP2rr}r(h.Uh/jubah2jubhIX has the later date of rr}r(h.X has the later date of h/jjubj)r}r(h.X**D2**h4}r(h6]h7]h8]h9]h;]uh/jjh)]rhIXD2rr}r(h.Uh/jubah2jubhIX, so will choose rr}r(h.X, so will choose h/jjubj)r}r(h.X**P2**h4}r(h6]h7]h8]h9]h;]uh/jjh)]rhIXP2rr}r(h.Uh/jubah2jubhIX as the head of the series.rr}r(h.X as the head of the series.h/jjubeubh|)r}r(h.XSuppose now that **A** spawns two more snapshots in quick succession, and DataONE synchronizes afterwards. It missed **P3(S)** but picks up **P4(S)**. ``Cn.resolve(S)`` will return an ObjectLocationList for the **P4** snapshot, since it is the latest of all non-obsoleted snapshots.h/jh0h1h2hh4}r(h6]h7]h8]h9]h;]uh=Kh>hh)]r(hIXSuppose now that rr}r(h.XSuppose now that h/jubj)r}r(h.X**A**h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIXAr}r(h.Uh/jubah2jubhIX` spawns two more snapshots in quick succession, and DataONE synchronizes afterwards. It missed rr}r(h.X` spawns two more snapshots in quick succession, and DataONE synchronizes afterwards. It missed h/jubj)r}r(h.X **P3(S)**h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIXP3(S)rr}r(h.Uh/jubah2jubhIX but picks up rr}r(h.X but picks up h/jubj)r}r(h.X **P4(S)**h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIXP4(S)rr}r(h.Uh/jubah2jubhIX. rr}r(h.X. h/jubj)r}r(h.X``Cn.resolve(S)``h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIX Cn.resolve(S)rr}r(h.Uh/jubah2jubhIX+ will return an ObjectLocationList for the rr}r(h.X+ will return an ObjectLocationList for the h/jubj)r}r(h.X**P4**h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIXP4rr}r(h.Uh/jubah2jubhIXA snapshot, since it is the latest of all non-obsoleted snapshots.rr}r(h.XA snapshot, since it is the latest of all non-obsoleted snapshots.h/jubeubh|)r}r(h.XLater, **A** makes some changes and realizes that the content is significantly different from previous revisions, so renames it **S2**. The system treats it as related, so links to the **P4** snapshot with the obsoletes field. **P5(S2)** is now hosted on **M**, but **P4(S)** is gone. ``cn.resolve(S)`` will return an ObjectLocationList for **P4**, but ``M.get(P4)`` will return NotFound, and the client will have to retrieve from a replica Member Node, if possible. ``Cn.resolve(S2)`` will return an OLL for **P5**. Note also that ``M.get(S)`` will not be able to resolve the SID to any PID, since it doesn't host any of the snapshots of **S**.h/jh0h1h2hh4}r(h6]h7]h8]h9]h;]uh=Kh>hh)]r(hIXLater, rr}r(h.XLater, h/jubj)r}r(h.X**A**h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIXAr}r(h.Uh/jubah2jubhIXt makes some changes and realizes that the content is significantly different from previous revisions, so renames it rr}r(h.Xt makes some changes and realizes that the content is significantly different from previous revisions, so renames it h/jubj)r}r (h.X**S2**h4}r (h6]h7]h8]h9]h;]uh/jh)]r hIXS2r r }r(h.Uh/jubah2jubhIX4. The system treats it as related, so links to the rr}r(h.X4. The system treats it as related, so links to the h/jubj)r}r(h.X**P4**h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIXP4rr}r(h.Uh/jubah2jubhIX% snapshot with the obsoletes field. rr}r(h.X% snapshot with the obsoletes field. h/jubj)r}r(h.X **P5(S2)**h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIXP5(S2)r r!}r"(h.Uh/jubah2jubhIX is now hosted on r#r$}r%(h.X is now hosted on h/jubj)r&}r'(h.X**M**h4}r((h6]h7]h8]h9]h;]uh/jh)]r)hIXMr*}r+(h.Uh/j&ubah2jubhIX, but r,r-}r.(h.X, but h/jubj)r/}r0(h.X **P4(S)**h4}r1(h6]h7]h8]h9]h;]uh/jh)]r2hIXP4(S)r3r4}r5(h.Uh/j/ubah2jubhIX is gone. r6r7}r8(h.X is gone. h/jubj)r9}r:(h.X``cn.resolve(S)``h4}r;(h6]h7]h8]h9]h;]uh/jh)]r<hIX cn.resolve(S)r=r>}r?(h.Uh/j9ubah2jubhIX' will return an ObjectLocationList for r@rA}rB(h.X' will return an ObjectLocationList for h/jubj)rC}rD(h.X**P4**h4}rE(h6]h7]h8]h9]h;]uh/jh)]rFhIXP4rGrH}rI(h.Uh/jCubah2jubhIX, but rJrK}rL(h.X, but h/jubj)rM}rN(h.X ``M.get(P4)``h4}rO(h6]h7]h8]h9]h;]uh/jh)]rPhIX M.get(P4)rQrR}rS(h.Uh/jMubah2jubhIXf will return NotFound, and the client will have to retrieve from a replica Member Node, if possible. rTrU}rV(h.Xf will return NotFound, and the client will have to retrieve from a replica Member Node, if possible. h/jubj)rW}rX(h.X``Cn.resolve(S2)``h4}rY(h6]h7]h8]h9]h;]uh/jh)]rZhIXCn.resolve(S2)r[r\}r](h.Uh/jWubah2jubhIX will return an OLL for r^r_}r`(h.X will return an OLL for h/jubj)ra}rb(h.X**P5**h4}rc(h6]h7]h8]h9]h;]uh/jh)]rdhIXP5rerf}rg(h.Uh/jaubah2jubhIX. Note also that rhri}rj(h.X. Note also that h/jubj)rk}rl(h.X ``M.get(S)``h4}rm(h6]h7]h8]h9]h;]uh/jh)]rnhIXM.get(S)rorp}rq(h.Uh/jkubah2jubhIX_ will not be able to resolve the SID to any PID, since it doesn't host any of the snapshots of rrrs}rt(h.X_ will not be able to resolve the SID to any PID, since it doesn't host any of the snapshots of h/jubj)ru}rv(h.X**S**h4}rw(h6]h7]h8]h9]h;]uh/jh)]rxhIXSry}rz(h.Uh/juubah2jubhIX.r{}r|(h.X.h/jubeubeubeubh+)r}}r~(h.Uh/hh0h1h2h3h4}r(h6]h7]h8]h9]rh&ah;]rhauh=Kh>hh)]r(h@)r}r(h.jDh/j}h0h1h2hDh4}r(h9]h8]h6]h7]h;]hFj?uh=Kh>hh)]rhIXSummaryrr}r(h.jDh/jubaubhq)r}r(h.Uh/j}h0h1h2hth4}r(UbulletrX-h9]h8]h6]h7]h;]uh=Kh>hh)]r(hw)r}r(h.X<the PID represents the snapshot, and snapshots are immutablerh/jh0h1h2hh4}r(h6]h7]h8]h9]h;]uh=Nh>hh)]rh|)r}r(h.jh/jh0h1h2hh4}r(h6]h7]h8]h9]h;]uh=Kh)]rhIX<the PID represents the snapshot, and snapshots are immutablerr}r(h.jh/jubaubaubhw)r}r(h.XQthe SID represents the entity, and can be applied to several connected snapshots.rh/jh0h1h2hh4}r(h6]h7]h8]h9]h;]uh=Nh>hh)]rh|)r}r(h.jh/jh0h1h2hh4}r(h6]h7]h8]h9]h;]uh=Kh)]rhIXQthe SID represents the entity, and can be applied to several connected snapshots.rr}r(h.jh/jubaubaubhw)r}r(h.X A particular SID cannot be used if it is either reserved by or in use by someone else. * Specifically, the CN checks that the submitter has CHANGE_PERMISSION on the current head of the series * if not in use, checks submitter against ``cn.hasReservation(SID)`` * h/jh0Nh2hh4}r(h6]h7]h8]h9]h;]uh=Nh>hh)]r(h|)r}r(h.XVA particular SID cannot be used if it is either reserved by or in use by someone else.rh/jh0h1h2hh4}r(h6]h7]h8]h9]h;]uh=Kh)]rhIXVA particular SID cannot be used if it is either reserved by or in use by someone else.rr}r(h.jh/jubaubhq)r}r(h.Uh4}r(jX*h9]h8]h6]h7]h;]uh/jh)]r(hw)r}r(h.XfSpecifically, the CN checks that the submitter has CHANGE_PERMISSION on the current head of the seriesh4}r(h6]h7]h8]h9]h;]uh/jh)]rh|)r}r(h.XfSpecifically, the CN checks that the submitter has CHANGE_PERMISSION on the current head of the seriesrh/jh0h1h2hh4}r(h6]h7]h8]h9]h;]uh=Kh)]rhIXfSpecifically, the CN checks that the submitter has CHANGE_PERMISSION on the current head of the seriesrr}r(h.jh/jubaubah2hubhw)r}r(h.XBif not in use, checks submitter against ``cn.hasReservation(SID)``rh4}r(h6]h7]h8]h9]h;]uh/jh)]rh|)r}r(h.jh/jh0h1h2hh4}r(h6]h7]h8]h9]h;]uh=Kh)]r(hIX(if not in use, checks submitter against rr}r(h.X(if not in use, checks submitter against h/jubj)r}r(h.X``cn.hasReservation(SID)``h4}r(h6]h7]h8]h9]h;]uh/jh)]rhIXcn.hasReservation(SID)rr}r(h.Uh/jubah2jubeubah2hubhw)r}r(h.Uh4}r(h6]h7]h8]h9]h;]uh/jh)]h2hubeh2htubeubhw)r}r(h.X2cannot put SID in obsoletes and obsoletedBy fieldsrh/jh0h1h2hh4}r(h6]h7]h8]h9]h;]uh=Nh>hh)]rh|)r}r(h.jh/jh0h1h2hh4}r(h6]h7]h8]h9]h;]uh=Kh)]rhIX2cannot put SID in obsoletes and obsoletedBy fieldsrr}r(h.jh/jubaubaubhw)r}r(h.XlSID resolution is "latest upload" among the set of snapshots not obsoleted by another member of the series. h/jh0h1h2hh4}r(h6]h7]h8]h9]h;]uh=Nh>hh)]rh|)r}r(h.XkSID resolution is "latest upload" among the set of snapshots not obsoleted by another member of the series.rh/jh0h1h2hh4}r(h6]h7]h8]h9]h;]uh=Kh)]rhIXkSID resolution is "latest upload" among the set of snapshots not obsoleted by another member of the series.rr}r(h.jh/jubaubaubhw)r}r(h.Xnot all revisions are guaranteed to be synchronized or replicated * is dependent on synchronization frequency, CN availability for sync * missing revisions, if synced but not replicated will appear as NotFound exceptions on forwarded resolve requests *h/jh0Nh2hh4}r(h6]h7]h8]h9]h;]uh=Nh>hh)]r(h|)r}r(h.XAnot all revisions are guaranteed to be synchronized or replicatedrh/jh0h1h2hh4}r(h6]h7]h8]h9]h;]uh=Kh)]rhIXAnot all revisions are guaranteed to be synchronized or replicatedrr}r(h.jh/jubaubhq)r}r(h.Uh4}r(jX*h9]h8]h6]h7]h;]uh/jh)]r(hw)r}r(h.XCis dependent on synchronization frequency, CN availability for syncrh4}r(h6]h7]h8]h9]h;]uh/jh)]rh|)r}r(h.jh/jh0h1h2hh4}r(h6]h7]h8]h9]h;]uh=Kh)]r hIXCis dependent on synchronization frequency, CN availability for syncr r }r (h.jh/jubaubah2hubhw)r }r(h.Xpmissing revisions, if synced but not replicated will appear as NotFound exceptions on forwarded resolve requestsh4}r(h6]h7]h8]h9]h;]uh/jh)]rh|)r}r(h.Xpmissing revisions, if synced but not replicated will appear as NotFound exceptions on forwarded resolve requestsrh/j h0h1h2hh4}r(h6]h7]h8]h9]h;]uh=Kh)]rhIXpmissing revisions, if synced but not replicated will appear as NotFound exceptions on forwarded resolve requestsrr}r(h.jh/jubaubah2hubhw)r}r(h.Uh4}r(h6]h7]h8]h9]h;]uh/jh)]h2hubeh2htubeubhw)r}r(h.XSunsynchronized revisions might appear in obsoletes/dBy fields of existing revisionsrh/jh0h1h2hh4}r(h6]h7]h8]h9]h;]uh=Nh>hh)]r h|)r!}r"(h.jh/jh0h1h2hh4}r#(h6]h7]h8]h9]h;]uh=Kh)]r$hIXSunsynchronized revisions might appear in obsoletes/dBy fields of existing revisionsr%r&}r'(h.jh/j!ubaubaubhw)r(}r)(h.XDcn.listObjects(idFilter=sid)?? retrieves all synchronized revisions h/jh0h1h2hh4}r*(h6]h7]h8]h9]h;]uh=Nh>hh)]r+h|)r,}r-(h.XCcn.listObjects(idFilter=sid)?? retrieves all synchronized revisionsr.h/j(h0h1h2hh4}r/(h6]h7]h8]h9]h;]uh=Kh)]r0hIXCcn.listObjects(idFilter=sid)?? retrieves all synchronized revisionsr1r2}r3(h.j.h/j,ubaubaubhw)r4}r5(h.Xonce SeriesID is set, it cannot be changed, because it breaks the trust that the identifier always gets the user to a conceptually equivalent object.h/jh0h1h2hh4}r6(h6]h7]h8]h9]h;]uh=Nh>hh)]r7h|)r8}r9(h.Xonce SeriesID is set, it cannot be changed, because it breaks the trust that the identifier always gets the user to a conceptually equivalent object.r:h/j4h0h1h2hh4}r;(h6]h7]h8]h9]h;]uh=Kh)]r<hIXonce SeriesID is set, it cannot be changed, because it breaks the trust that the identifier always gets the user to a conceptually equivalent object.r=r>}r?(h.j:h/j8ubaubaubeubeubeh.UU transformerr@NU footnote_refsrA}rBUrefnamesrC}rDUsymbol_footnotesrE]rFUautofootnote_refsrG]rHUsymbol_footnote_refsrI]rJU citationsrK]rLh>hU current_linerMNUtransform_messagesrN]rOcdocutils.nodes system_message rP)rQ}rR(h.Uh4}rS(h6]UlevelKh9]h8]Usourceh1h7]h;]UlineKUtypeUINFOrTuh)]rUh|)rV}rW(h.Uh4}rX(h6]h7]h8]h9]h;]uh/jQh)]rYhIX-Hyperlink target "index-0" is not referenced.rZr[}r\(h.Uh/jVubah2hubah2Usystem_messager]ubaUreporterr^NUid_startr_K U autofootnotesr`]raU citation_refsrb}rcUindirect_targetsrd]reUsettingsrf(cdocutils.frontend Values rgorh}ri(Ufootnote_backlinksrjKUrecord_dependenciesrkNU rfc_base_urlrlUhttps://tools.ietf.org/html/rmU tracebackrnUpep_referencesroNUstrip_commentsrpNU toc_backlinksrqUentryrrU language_codersUenrtU datestampruNU report_levelrvKU _destinationrwNU halt_levelrxKU strip_classesryNhDNUerror_encoding_error_handlerrzUbackslashreplacer{Udebugr|NUembed_stylesheetr}Uoutput_encoding_error_handlerr~UstrictrU sectnum_xformrKUdump_transformsrNU docinfo_xformrKUwarning_streamrNUpep_file_url_templaterUpep-%04drUexit_status_levelrKUconfigrNUstrict_visitorrNUcloak_email_addressesrUtrim_footnote_reference_spacerUenvrNUdump_pseudo_xmlrNUexpose_internalsrNUsectsubtitle_xformrU source_linkrNUrfc_referencesrNUoutput_encodingrUutf-8rU source_urlrNUinput_encodingrU utf-8-sigrU_disable_configrNU id_prefixrUU tab_widthrKUerror_encodingrUUTF-8rU_sourcerh1Ugettext_compactrU generatorrNUdump_internalsrNU smart_quotesrU pep_base_urlrU https://www.python.org/dev/peps/rUsyntax_highlightrUlongrUinput_encoding_error_handlerrjUauto_id_prefixrUidrUdoctitle_xformrUstrip_elements_with_classesrNU _config_filesr]Ufile_insertion_enabledrU raw_enabledrKU dump_settingsrNubUsymbol_footnote_startrKUidsr}r(h jEh%h,h(h^hjj jjjhhhhhhhhhhhhhGhj-j)j?j;h$jJh"jhUh^hjbhjph!j,h'jh#jh&j}hjuUsubstitution_namesr}rh2h>h4}r(h6]h9]h8]Usourceh1h7]h;]uU footnotesr]rUrefidsr}rhU]rhYasub.