summaryrefslogtreecommitdiffstats
path: root/doc/html/review1a.html
diff options
context:
space:
mode:
Diffstat (limited to 'doc/html/review1a.html')
-rw-r--r--doc/html/review1a.html252
1 files changed, 0 insertions, 252 deletions
diff --git a/doc/html/review1a.html b/doc/html/review1a.html
deleted file mode 100644
index 3df8af7..0000000
--- a/doc/html/review1a.html
+++ /dev/null
@@ -1,252 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
- <head>
- <title>Group Examples</title>
- </head>
- <body>
- <center><h1>Group Examples</h1></center>
-
- <hr>
- <h1>Background</h1>
-
- <p>Directories (or now <i>Groups</i>) are currently implemented as
- a directed graph with a single entry point into the graph which
- is the <i>Root Object</i>. The root object is usually a
- group. All objects have at least one predecessor (the <i>Root
- Object</i> always has the HDF5 file super block as a
- predecessor). The number of predecessors of a group is also
- known as the <i>hard link count</i> or just <i>link count</i>.
- Unlike Unix directories, HDF5 groups have no ".." entry since
- any group can have multiple predecessors. Given the handle or
- id of some object and returning a full name for that object
- would be an expensive graph traversal.
-
- <p>A special optimization is that a file may contain a single
- non-group object and no group(s). The object has one
- predecessor which is the file super block. However, once a root
- group is created it never dissappears (although I suppose it
- could if we wanted).
-
- <p>A special object called a <i>Symbolic Link</i> is simply a
- name. Usually the name refers to some (other) object, but that
- object need not exist. Symbolic links in HDF5 will have the
- same semantics as symbolic links in Unix.
-
- <p>The symbol table graph contains "entries" for each name. An
- entry contains the file address for the object header and
- possibly certain messages cached from the object header.
-
- <p>The H5G package understands the notion of <i>opening</i> and object
- which means that given the name of the object, a handle to the
- object is returned (this isn't an API function). Objects can be
- opened multiple times simultaneously through the same name or,
- if the object has hard links, through other names. The name of
- an object cannot be removed from a group if the object is opened
- through that group (although the name can change within the
- group).
-
- <p>Below the API, object attributes can be read without opening
- the object; object attributes cannot change without first
- opening that object. The one exception is that the contents of a
- group can change without opening the group.
-
- <hr>
- <h1>Building a hierarchy from a flat namespace</h1>
-
- <p>Assuming we have a flat name space (that is, the root object is
- a group which contains names for all other objects in the file
- and none of those objects are groups), then we can build a
- hierarchy of groups that also refer to the objects.
-
- <p>The file initially contains `foo' `bar' `baz' in the root
- group. We wish to add groups `grp1' and `grp2' so that `grp1'
- contains objects `foo' and `baz' and `grp2' contains objects
- `bar' and `baz' (so `baz' appears in both groups).
-
- <p>In either case below, one might want to move the flat objects
- into some other group (like `flat') so their names don't
- interfere with the rest of the hierarchy (or move the hierarchy
- into a directory called `/hierarchy').
-
- <h2>with symbolic links</h2>
-
- <p>Create group `grp1' and add symbolic links called `foo' whose
- value is `/foo' and `baz' whose value is `/baz'. Similarly for
- `grp2'.
-
- <p>Accessing `grp1/foo' involves searching the root group for
- the name `grp1', then searching that group for `foo', then
- searching the root directory for `foo'. Alternatively, one
- could change working groups to the grp1 group and then ask for
- `foo' which searches `grp1' for the name `foo', then searches
- the root group for the name `foo'.
-
- <p>Deleting `/grp1/foo' deletes the symbolic link without
- affecting the `/foo' object. Deleting `/foo' leaves the
- `/grp1/foo' link dangling.
-
- <h2>with hard links</h2>
-
- <p>Creating the hierarchy is the same as with symbolic links.
-
- <p>Accessing `/grp1/foo' searches the root group for the name
- `grp1', then searches that group for the name `foo'. If the
- current working group is `/grp1' then we just search for the
- name `foo'.
-
- <p>Deleting `/grp1/foo' leaves `/foo' and vice versa.
-
- <h2>the code</h2>
-
- <p>Depending on the eventual API...
-
- <code><pre>
-H5Gcreate (file_id, "/grp1");
-H5Glink (file_id, H5G_HARD, "/foo", "/grp1/foo");
- </pre></code>
-
- or
-
- <code><pre>
-group_id = H5Gcreate (root_id, "grp1");
-H5Glink (file_id, H5G_HARD, root_id, "foo", group_id, "foo");
-H5Gclose (group_id);
- </pre></code>
-
-
- <hr>
- <h1>Building a flat namespace from a hierarchy</h1>
-
- <p>Similar to abvoe, but in this case we have to watch out that
- we don't get two names which are the same: what happens to
- `/grp1/baz' and `/grp2/baz'? If they really refer to the same
- object then we just have `/baz', but if they point to two
- different objects what happens?
-
- <p>The other thing to watch out for cycles in the graph when we
- traverse it to build the flat namespace.
-
- <hr>
- <h1>Listing the Group Contents</h1>
-
- <p>Two things to watch out for are that the group contents don't
- appear to change in a manner which would confuse the
- application, and that listing everything in a group is as
- efficient as possible.
-
- <h2>Method A</h2>
-
- <p>Query the number of things in a group and then query each item
- by index. A trivial implementation would be O(n*n) and wouldn't
- protect the caller from changes to the directory which move
- entries around and therefore change their indices.
-
- <code><pre>
-n = H5GgetNumContents (group_id);
-for (i=0; i&lt;n; i++) {
- H5GgetNameByIndex (group_id, i, ...); /*don't worry about args yet*/
-}
- </pre></code>
-
- <h2>Method B</h2>
-
- <p>The API contains a single function that reads all information
- from the specified group and returns that info through an array.
- The caller is responsible for freeing the array allocated by the
- query and the things to which it points. This also makes it
- clear the the returned value is a snapshot of the group which
- doesn't change if the group is modified.
-
- <code><pre>
-n = H5Glist (file_id, "/grp1", info, ...);
-for (i=0; i&lt;n; i++) {
- printf ("name = %s\n", info[i].name);
- free (info[i].name); /*and maybe other fields too?*/
-}
-free (info);
- </pre></code>
-
- Notice that it would be difficult to expand the info struct since
- its definition is part of the API.
-
- <h2>Method C</h2>
-
- <p>The caller asks for a snapshot of the group and then accesses
- items in the snapshot through various query-by-index API
- functions. When finished, the caller notifies the library that
- it's done with the snapshot. The word "snapshot" makes it clear
- that subsequent changes to the directory will not be reflected in
- the shapshot_id.
-
- <code><pre>
-snapshot_id = H5Gsnapshot (group_id); /*or perhaps group_name */
-n = H5GgetNumContents (snapshot_id);
-for (i=0; i&lt;n; i++) {
- H5GgetNameByIndex (shapshot_id, i, ...);
-}
-H5Grelease (shapshot_id);
- </pre></code>
-
- In fact, we could allow the user to leave off the H5Gsnapshot and
- H5Grelease and use group_id in the H5GgetNumContents and
- H5GgetNameByIndex so they can choose between Method A and Method
- C.
-
- <hr>
- <h1>An implementation of Method C</h1>
-
- <dl>
- <dt><code>hid_t H5Gshapshot (hid_t group_id)</code>
- <dd>Opens every object in the specified group and stores the
- handles in an array managed by the library (linear-time
- operation). Open object handles are essentialy symbol table
- entries with a little extra info (symbol table entries cache
- certain things about the object which are also found in the
- object header). Because the objects are open (A) they cannot be
- removed from the group, (B) querying the object returns the
- latest info even if something else has that object open, (C)
- if the object is renamed within the group then its name with
- <code>H5GgetNameByIndex</code> is changed. Adding new entries
- to a group doesn't affect the snapshot.
-
- <dt><code>char *H5GgetNameByIndex (hid_t shapshot_id, int
- index)</code>
- <dd>Uses the open object handle from entry <code>index</code> of
- the snapshot array to get the object name. This is a
- constant-time operation. The name is updated automatically if
- the object is renamed within the group.
-
- <dt><code>H5Gget&lt;whatever&gt;ByIndex...()</code>
- <dd>Uses the open object handle from entry <code>index</code>,
- which is just a symbol table entry, and reads the appropriate
- object header message(s) which might be cached in the symbol
- table entry. This is a constant-time operation if cached,
- linear in the number of messages if not cached.
-
- <dt><code>H5Grelease (hid_t snapshot_id)</code>
- <dd>Closes each object refered to by the snapshot and then frees
- the snapshot array. This is a linear-time operation.
- </dl>
-
- <hr>
- <h1>To return <code>char*</code> or some HDF5 string type.</h1>
-
- <p>In either case, the caller has to release resources associated
- with the return value, calling free() or some HDF5 function.
-
- <p>Names in the current implementation of the H5G package don't
- contain embedded null characters and are always null terminated.
-
- <p>Eventually the caller probably wants a <code>char*</code> so it
- can pass it to some non-HDF5 function, does that require
- strdup'ing the string again? Then the caller has to free() the
- the char* <i>and</i> release the DHF5 string.
-
- <hr>
- <address><a href="mailto:matzke@llnl.gov">Robb Matzke</a></address>
-<!-- Created: Fri Sep 26 12:03:20 EST 1997 -->
-<!-- hhmts start -->
-Last modified: Fri Oct 3 09:32:10 EST 1997
-<!-- hhmts end -->
- </body>
-</html>