792 |
6.1. Pointers: implementing mutable resources |
6.1. Pointers: implementing mutable resources |
793 |
--------------------------------------------- |
--------------------------------------------- |
794 |
|
|
795 |
In Storm, *pointers* are used to implement mutable resources. |
A Storm pointer is a globally unique identifier (usually created randomly) |
|
A pointer is a globally unique identifier (usually created randomly) |
|
796 |
that can refer to different blocks over time. A block a pointer |
that can refer to different blocks over time. A block a pointer |
797 |
points to is called the pointer's *target* (Fig. [ref-storm_pointers]_). |
points to is called the pointer's *target* (Fig. [ref-storm_pointers]_). |
798 |
|
|
800 |
a *pointer block*, representing an assertion like *pointer P targets |
a *pointer block*, representing an assertion like *pointer P targets |
801 |
block B*. To find the target of pointer P, Storm searches for |
block B*. To find the target of pointer P, Storm searches for |
802 |
blocks of this form. This is one application of Storm |
blocks of this form. This is one application of Storm |
803 |
indexing (Section 5): Keeping an index of all pointer blocks |
indexing (Section 5), using P as the index key. |
|
about pointer ``P``, we can quickly find out the current one. |
|
804 |
|
|
805 |
.. uml:: storm_pointers |
.. uml:: storm_pointers |
806 |
:caption: The Storm pointer system |
:caption: The Storm pointer system |
847 |
alternative versions have been consolidated, a pointer block |
alternative versions have been consolidated, a pointer block |
848 |
obsoleting both consolidated previous versions is created. |
obsoleting both consolidated previous versions is created. |
849 |
|
|
850 |
In a multi-user environement, we generally want only |
In a multi-user environment, we usually want only one user |
851 |
one user or group of users to be able to produce new |
or group to be able to publish official versions a document. |
852 |
official versions of a given document (an exception may |
It is not yet clear how to do this. |
|
be wikis, which are collaboratively edited by anyone |
|
|
interested [leuf01wiki]_). It is not yet clear how to do this. |
|
853 |
Signing pointer blocks digitally may be sensible, but |
Signing pointer blocks digitally may be sensible, but |
854 |
digital signatures require a public key infrastructure |
digital signatures require a public key infrastructure |
855 |
and a trusted timestamping mechanism [#]_, which |
and a trusted timestamping mechanism, which |
856 |
is hardly feasible for a system intended to be used |
are hardly feasible for a system intended to be used |
857 |
for off-line as well as on-line work. |
for off-line as well as on-line work. |
858 |
For long-term publishing, one-time signatures have been |
For long-term publishing, one-time signatures have been |
859 |
found useful [anderson98erl]_. For the time being, the pointer mechanism |
found useful [anderson98erl]_. Currently, the pointer mechanism |
860 |
works only in trusted Storm pools (Section 4), e.g. |
works only in trusted Storm pools, e.g. |
861 |
in a workgroup collaborating on a set of documents. |
in a workgroup collaborating on a set of documents. |
862 |
|
|
|
.. [#] Without timestamps, digital signatures are only valid |
|
|
for a limited time [ref]. |
|
|
|
|
863 |
The ability to retain multiple 'current' versions of a document |
The ability to retain multiple 'current' versions of a document |
864 |
can be useful, for example when there is no time to consolidate |
can be useful, for example when there is no time to consolidate |
865 |
changes at the time of synchronization. |
changes at the time of synchronization. However, we need |
866 |
Yet, it is decidedly inconvenient when every time one opens a document, |
to choose one such version when loading the document. |
867 |
the computer pops up a little window saying, "There are currently |
For example, we could open an official or original version automatically |
|
three different versions of this resource. Which one would you like |
|
|
to open?" Overcoming this problem will be an important issue |
|
|
as the system matures. A possible way to alleviate this problem |
|
|
would be to allow prioritizing alternate versions based on metadata, |
|
|
for example opening an official or original version automatically |
|
868 |
if one exists. |
if one exists. |
869 |
|
|
870 |
While we think that alternative current versions are useful for |
While we think that alternative current versions are useful for |
894 |
each with only small changes. Instead, we use the well-known |
each with only small changes. Instead, we use the well-known |
895 |
technique of storing only the differences between versions. |
technique of storing only the differences between versions. |
896 |
|
|
897 |
A simplistic scheme to implement this atop block storage would be |
Even though we use diffs, |
898 |
to form a block by storing the difference to the previous version |
we *pretend* to store whole versions: We refer to a version |
899 |
together with the id of the block representing that version |
by the id of a block containing it. |
|
(indeed, this was the way our first implementation worked). |
|
|
To load a version, it is then necessary to process |
|
|
all the differences in order. This scheme makes it extremely |
|
|
difficult to remove an older version: The chain of versions |
|
|
leading up to the current one would be broken if any |
|
|
previous version were deleted. |
|
|
|
|
|
Additionally, many versioning systems (e.g. CVS [cvs]_) |
|
|
store the current version as well as the differences, |
|
|
enabling them to retrieve the current version quickly and compute |
|
|
recent versions by applying the differences 'backwards,' |
|
|
starting from the current version. If this technique were applied |
|
|
in the simplistic scheme above, there would be no guarantee |
|
|
that the resulting version would really be the version referred to: |
|
|
The cryptographic hashes only guarantee this when all of the |
|
|
differences are processed. |
|
|
|
|
|
The root of these difficulties is that we refer to a version |
|
|
by the hash of a data record referencing the previous version, |
|
|
represented as a hash of a data record referencing the version |
|
|
before that, and so on. |
|
|
|
|
|
To solve this problem, in our current |
|
|
design we refer to a version simply by the hash of that version-- |
|
|
that is, the hash of a block containing that version. |
|
900 |
However, we do not necessarily store this block, |
However, we do not necessarily store this block, |
901 |
even though we refer to it. Instead, we may create a *diff block*, |
even though we refer to it. Instead, we may create a *diff block*, |
902 |
containing a difference and the ids of the versions this |
containing a difference and the ids of the versions this |