summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRobb Matzke <matzke@llnl.gov>1997-10-20 23:14:35 (GMT)
committerRobb Matzke <matzke@llnl.gov>1997-10-20 23:14:35 (GMT)
commit56ad55117a89a423a9341d2f0c3912d4ad57ec6f (patch)
treedff0bada659180ac324d81a4d97f7bfb884f0ed6 /src
parentdc4961d072249ddf39a7db7a945ea627c276d025 (diff)
downloadhdf5-56ad55117a89a423a9341d2f0c3912d4ad57ec6f.zip
hdf5-56ad55117a89a423a9341d2f0c3912d4ad57ec6f.tar.gz
hdf5-56ad55117a89a423a9341d2f0c3912d4ad57ec6f.tar.bz2
[svn-r129] Changes since 19970916
---------------------- ./config/depend.in Fixed backslashes in sed script because the H5Gnode.c dependency info was disappearing. You'll have to rerun config.status to rebuild the Makefiles unless you use gnu make. ./config/conclude.in Also removes emacs backup files, TAGS, and svf backup files. ./config/linux Grouped gcc flags and added provisions for debugging vs. production. ./html/H5.format.html Updated messages 0x0008, 0x0009, and 0x000A. ./html/storage.html Documentation describing storage schemes. ./src/Makefile.in ./test/Makefile.in New source files. ./src/H5A.c ./src/H5Apublic.h ./src/H5C.c Changed VOIDP to void* in a couple places. ./src/H5AC.c ./src/H5ACprivate.h ./src/H5B.c ./src/H5Bprivate.h ./src/H5G.c ./src/H5Gnode.c ./src/H5Gprivate.h ./src/H5H.c ./src/H5O.c Removed `const' from some variables because H5G_node_found() wanted to modify it's udata argument. Removing const there caused it to cascade to these other locations. ./src/H5AC.c ./src/H5ACprivate.h ./src/H5B.c ./src/H5Gnode.c ./src/H5Gstab.c ./src/H5H.c ./src/H5O.c Added an extra argument to H5AC_find_f() and H5AC_protect(). This arg gets passed to the load() method. Also added an extra argument to the H5AC_find() macro. ./src/H5B.c ./src/H5Bprivate.h ./src/H5Gnode.c Extra argument passed to the sizeof_rkey() method. ./src/H5Fprivate.c ./src/H5Fistore.c (new) Added indexed I/O operations. ./src/H5G.c ./src/H5Gnode.c ./src/H5Gprivate.h Beginning to add H5G_open/close and related bug fixes. ./src/H5Oprivate.h ./src/H5Oistore.c (new) Added the H5O_ISTORE messsage (0x0008) for indexed storage of objects. ./src/H5private.h Added extra braces around both sides of the FUNC_ENTER() and FUNC_LEAVE() macros so FUNC_ENTER() can appear before declarations or after executable statements the second case is used by H5G_namei() to initialize output arguments to sane values before FUNC_ENTER() might return failure. int f () { int decl1; printf ("This happens before FUNC_ENTER()\n"); FUNC_ENTER (...); int another_declaration; ./src/H5B.c ./src/H5Bprivate.h ./src/H5Gnode.c Extra arguments for key encoding and decoding. ./src/H5E.c ./src/H5Epublic.h ./src/H5Fistore.c ./src/H5Oistore.c ./src/H5Oprivate.h Indexed, chunked, sparse storage (not ready for general consumption yet). ./src/H5V.c (new) ./src/H5Vprivate.h (new) ./test/hyperslab.c (new) Vector, array, and hyperslab functions. ./src/H5B.c ./src/H5Bprivate.h ./src/H5Fistore.c ./src/H5Gnode.c ./src/H5V.c ./src/H5Vprivate.h ./test/hyperslab.c Added functionality for indexed storage. ./src/H5F.c Fixed problems with seek optimizing. Recommend we disable it until we can implement it in the file/address class since all of HDF5 must be aware of it. ./src/H5O.c Fixed comeent speling erorr :-) ./MANIFEST Added new files. ./config/conclude.in Added the word `Testing' to the test cases. So if a test program is called hyperslab then the make output will contain the line `Testing hyperslab'. ./config/linux The default file I/O library is Posix section 2 on my linux machine so I can do some I/O performance testing. ./src/H5C.c ./src/H5Cprivate.h ./src/H5Cpublic.h Added ability to set size of indexed-storage B-tree. ./src/H5D.c ./src/H5E.c ./src/H5Epublic.h ./src/H5F.c ./src/H5Fprivate.h ./src/H5G.c ./src/H5Gnode.c ./src/H5Gpkg.h ./src/H5Gprivate.h ./src/H5Gpublic.h ./src/H5Gshad.c ./src/H5Gstab.c ./test/stab.c Changed `directory' to `group' in numerous places. ./src/H5private.h The FILELIB constant can be set on the compile command-line. ./src/istore.c NEW Tests for indexed storage.
Diffstat (limited to 'src')
-rw-r--r--src/H5A.c2
-rw-r--r--src/H5AC.c26
-rw-r--r--src/H5ACprivate.h10
-rw-r--r--src/H5Apublic.h2
-rw-r--r--src/H5B.c369
-rw-r--r--src/H5Bprivate.h35
-rw-r--r--src/H5C.c20
-rw-r--r--src/H5Cprivate.h2
-rw-r--r--src/H5Cpublic.h1
-rw-r--r--src/H5D.c8
-rw-r--r--src/H5Distore.c740
-rw-r--r--src/H5E.c5
-rw-r--r--src/H5Epublic.h9
-rw-r--r--src/H5F.c40
-rw-r--r--src/H5Fistore.c740
-rw-r--r--src/H5Fprivate.h11
-rw-r--r--src/H5G.c799
-rw-r--r--src/H5Gent.c2
-rw-r--r--src/H5Gnode.c81
-rw-r--r--src/H5Gpkg.h30
-rw-r--r--src/H5Gprivate.h11
-rw-r--r--src/H5Gpublic.h10
-rw-r--r--src/H5Gshad.c86
-rw-r--r--src/H5Gstab.c10
-rw-r--r--src/H5H.c21
-rw-r--r--src/H5O.c43
-rw-r--r--src/H5Oistore.c271
-rw-r--r--src/H5Oname.c14
-rw-r--r--src/H5Oprivate.h21
-rw-r--r--src/H5Osdtyp.c2
-rw-r--r--src/H5config.h.in12
-rw-r--r--src/H5private.h14
-rw-r--r--src/Makefile.in10
33 files changed, 2943 insertions, 514 deletions
diff --git a/src/H5A.c b/src/H5A.c
index 5605c34..52622bc 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -276,7 +276,7 @@ done:
*******************************************************************************/
hid_t H5Aregister_atom(group_t grp, /* IN: Group to register the object in */
- const VOIDP object /* IN: Object to attach to atom */
+ const void *object /* IN: Object to attach to atom */
)
{
atom_group_t *grp_ptr=NULL; /* ptr to the atomic group */
diff --git a/src/H5AC.c b/src/H5AC.c
index dda2fc2..1c570e8 100644
--- a/src/H5AC.c
+++ b/src/H5AC.c
@@ -143,10 +143,12 @@ H5AC_dest (H5F_t *f)
*
* Purpose: Given an object type and the address at which that object
* is located in the file, return a pointer to the object.
- * The optional UDATA structure is passed down to the function
- * that is responsible for loading the object into memory.
- * The pointer is guaranteed to be valid until the next call
- * to an H5AC function (if you want a pointer which is valid
+ * The optional UDATA1 and UDATA2 structures are passed down to
+ * the function that is responsible for loading the object into
+ * memory.
+ *
+ * The returned pointer is guaranteed to be valid until the next
+ * call to an H5AC function (if you want a pointer which is valid
* indefinately then see H5AC_protect()).
*
* If H5AC_DEBUG_PROTECT is defined then this function also
@@ -175,7 +177,8 @@ H5AC_dest (H5F_t *f)
*-------------------------------------------------------------------------
*/
void *
-H5AC_find_f (H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *udata)
+H5AC_find_f (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
+ void *udata1, void *udata2)
{
unsigned idx;
herr_t status;
@@ -228,7 +231,7 @@ H5AC_find_f (H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *udata)
* Load a new thing. If it can't be loaded, then return an error
* without preempting anything.
*/
- if (NULL==(thing=(type->load)(f, addr, udata))) {
+ if (NULL==(thing=(type->load)(f, addr, udata1, udata2))) {
HRETURN_ERROR (H5E_CACHE, H5E_CANTLOAD, NULL);
}
@@ -272,7 +275,7 @@ H5AC_find_f (H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *udata)
* Failure: never fails
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 12 1997
*
* Modifications:
@@ -604,7 +607,7 @@ H5AC_rename (H5F_t *f, const H5AC_class_t *type,
* Failure: NULL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Sep 2 1997
*
* Modifications:
@@ -612,7 +615,8 @@ H5AC_rename (H5F_t *f, const H5AC_class_t *type,
*-------------------------------------------------------------------------
*/
void *
-H5AC_protect (H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *udata)
+H5AC_protect (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
+ void *udata1, void *udata2)
{
int idx;
void *thing = NULL;
@@ -663,7 +667,7 @@ H5AC_protect (H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *udata)
* Load a new thing. If it can't be loaded, then return an error
* without preempting anything.
*/
- if (NULL==(thing=(type->load)(f, addr, udata))) {
+ if (NULL==(thing=(type->load)(f, addr, udata1, udata2))) {
HRETURN_ERROR (H5E_CACHE, H5E_CANTLOAD, NULL);
}
}
@@ -706,7 +710,7 @@ H5AC_protect (H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *udata)
* Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Sep 2 1997
*
* Modifications:
diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h
index a028d9c..25549ff 100644
--- a/src/H5ACprivate.h
+++ b/src/H5ACprivate.h
@@ -39,7 +39,7 @@
* by the LOAD method if the DEST argument is non-zero.
*/
typedef struct H5AC_class_t {
- void *(*load)(H5F_t*, haddr_t addr, void *udata);
+ void *(*load)(H5F_t*, haddr_t addr, void *udata1, void *udata2);
herr_t (*flush)(H5F_t*, hbool_t dest, haddr_t addr, void *thing);
} H5AC_class_t;
@@ -78,9 +78,9 @@ typedef struct H5AC_t {
*/
herr_t H5AC_dest (H5F_t *f);
void *H5AC_find_f (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
- void *udata);
+ void *udata1, void *udata2);
void * H5AC_protect (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
- void *udata);
+ void *udata1, void *udata2);
herr_t H5AC_unprotect (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
void *thing);
herr_t H5AC_flush (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
@@ -91,11 +91,11 @@ herr_t H5AC_rename (H5F_t *f, const H5AC_class_t *type, haddr_t old,
herr_t H5AC_set (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
void *thing);
-#define H5AC_find(F,TYPE,ADDR,UDATA) \
+#define H5AC_find(F,TYPE,ADDR,UDATA1,UDATA2) \
(((F)->shared->cache->slot[H5AC_HASH(F,ADDR)].type==(TYPE) && \
(F)->shared->cache->slot[H5AC_HASH(F,ADDR)].addr==(ADDR)) ? \
(F)->shared->cache->slot[H5AC_HASH(F,ADDR)].thing : \
- H5AC_find_f (F, TYPE, ADDR, UDATA))
+ H5AC_find_f (F, TYPE, ADDR, UDATA1, UDATA2))
#endif /* !_H5ACprivate_H */
diff --git a/src/H5Apublic.h b/src/H5Apublic.h
index 36cceed..efae778 100644
--- a/src/H5Apublic.h
+++ b/src/H5Apublic.h
@@ -110,7 +110,7 @@ intn H5Adestroy_group(group_t grp /* IN: Group to destroy */
*******************************************************************************/
hid_t H5Aregister_atom(group_t grp, /* IN: Group to register the object in */
- const VOIDP object /* IN: Object to attach to atom */
+ const void *object /* IN: Object to attach to atom */
);
/******************************************************************************
diff --git a/src/H5B.c b/src/H5B.c
index cb3d2bb..ccbcdb4 100644
--- a/src/H5B.c
+++ b/src/H5B.c
@@ -100,21 +100,23 @@
/* PRIVATE PROTOTYPES */
static haddr_t H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
+ H5B_ins_t *anchor,
uint8 *lt_key, hbool_t *lt_key_changed,
uint8 *md_key, void *udata,
uint8 *rt_key, hbool_t *rt_key_changed);
static herr_t H5B_insert_child (H5F_t *f, const H5B_class_t *type,
H5B_t *bt, intn idx, haddr_t child,
- intn anchor, void *md_key);
+ H5B_ins_t anchor, void *md_key);
static herr_t H5B_flush (H5F_t *f, hbool_t destroy, haddr_t addr, H5B_t *b);
-static H5B_t *H5B_load (H5F_t *f, haddr_t addr, void *_data);
+static H5B_t *H5B_load (H5F_t *f, haddr_t addr, void *_type, void *udata);
static herr_t H5B_decode_key (H5F_t *f, H5B_t *bt, intn idx);
+static herr_t H5B_decode_keys (H5F_t *f, H5B_t *bt, intn idx);
static size_t H5B_nodesize (H5F_t *f, const H5B_class_t *type,
size_t *total_nkey_size, size_t sizeof_rkey);
/* H5B inherits cache-like properties from H5AC */
static const H5AC_class_t H5AC_BT[1] = {{
- (void*(*)(H5F_t*,haddr_t,void*))H5B_load,
+ (void*(*)(H5F_t*,haddr_t,void*,void*))H5B_load,
(herr_t(*)(H5F_t*,hbool_t,haddr_t,void*))H5B_flush,
}};
@@ -125,7 +127,9 @@ static interface_initialize_g = FALSE;
/*-------------------------------------------------------------------------
* Function: H5B_new
*
- * Purpose: Creates a new empty B-tree leaf node.
+ * Purpose: Creates a new empty B-tree leaf node. The UDATA pointer is
+ * passed as an argument to the sizeof_rkey() method for the
+ * B-tree.
*
* Return: Success: address of new node.
*
@@ -140,7 +144,7 @@ static interface_initialize_g = FALSE;
*-------------------------------------------------------------------------
*/
haddr_t
-H5B_new (H5F_t *f, const H5B_class_t *type)
+H5B_new (H5F_t *f, const H5B_class_t *type, void *udata)
{
H5B_t *bt=NULL;
haddr_t addr;
@@ -159,7 +163,7 @@ H5B_new (H5F_t *f, const H5B_class_t *type)
/*
* Allocate file and memory data structures.
*/
- sizeof_rkey = (type->get_sizeof_rkey)(f);
+ sizeof_rkey = (type->get_sizeof_rkey)(f, udata);
size = H5B_nodesize (f, type, &total_native_keysize, sizeof_rkey);
if ((addr = H5MF_alloc (f, size))<0) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL);
@@ -229,9 +233,9 @@ H5B_new (H5F_t *f, const H5B_class_t *type)
*-------------------------------------------------------------------------
*/
static H5B_t *
-H5B_load (H5F_t *f, haddr_t addr, void *_data)
+H5B_load (H5F_t *f, haddr_t addr, void *_type, void *udata)
{
- const H5B_class_t *type = (H5B_class_t *)_data;
+ const H5B_class_t *type = (H5B_class_t *)_type;
size_t size, total_nkey_size;
H5B_t *bt = NULL;
intn i;
@@ -247,7 +251,7 @@ H5B_load (H5F_t *f, haddr_t addr, void *_data)
assert (type->get_sizeof_rkey);
bt = H5MM_xmalloc (sizeof(H5B_t));
- bt->sizeof_rkey = (type->get_sizeof_rkey)(f);
+ bt->sizeof_rkey = (type->get_sizeof_rkey)(f, udata);
size = H5B_nodesize (f, type, &total_nkey_size, bt->sizeof_rkey);
bt->type = type;
bt->dirty = FALSE;
@@ -375,7 +379,8 @@ H5B_flush (H5F_t *f, hbool_t destroy, haddr_t addr, H5B_t *bt)
assert (bt->key[i].rkey == p);
if (bt->key[i].dirty) {
if (bt->key[i].nkey) {
- if ((bt->type->encode)(f, bt->key[i].rkey, bt->key[i].nkey)<0) {
+ if ((bt->type->encode)(f, bt, bt->key[i].rkey,
+ bt->key[i].nkey)<0) {
HRETURN_ERROR (H5E_BTREE, H5E_CANTENCODE, FAIL);
}
}
@@ -464,21 +469,14 @@ H5B_find (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata)
* Perform a binary search to locate the child which contains
* the thing for which we're searching.
*/
- if (NULL==(bt=H5AC_protect (f, H5AC_BT, addr, type))) {
+ if (NULL==(bt=H5AC_protect (f, H5AC_BT, addr, type, udata))) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
rt = bt->nchildren;
while (lt<rt && cmp) {
idx = (lt + rt) / 2;
-
- /* the left key */
- if (!bt->key[idx].nkey && H5B_decode_key (f, bt, idx)<0) {
- HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
- }
-
- /* the right key */
- if (!bt->key[idx+1].nkey && H5B_decode_key (f, bt, idx+1)<0) {
+ if (H5B_decode_keys (f, bt, idx)<0) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
}
@@ -522,9 +520,11 @@ done:
* Function: H5B_split
*
* Purpose: Split a single node into two nodes. If anchor is
- * H5B_ANCHOR_LT then the new node gets the right half of
- * the old node. If anchor is H5B_ANCHOR_RT then the
- * new node gets the left half of the old node.
+ * H5B_INS_RIGHT then the new node gets the right half of
+ * the old node. If anchor is H5B_INS_LEFT then the
+ * new node gets the left half of the old node. The UDATA
+ * pointer is passed to the sizeof_rkey() method but is
+ * otherwise unused.
*
* The OLD_BT argument is a pointer to a protected B-tree
* node.
@@ -543,7 +543,7 @@ done:
*/
static haddr_t
H5B_split (H5F_t *f, H5B_class_t *type, H5B_t *old_bt, haddr_t old_addr,
- intn anchor)
+ H5B_ins_t anchor, void *udata)
{
H5B_t *new_bt=NULL, *tmp_bt=NULL;
haddr_t ret_value=FAIL, new_addr=FAIL;
@@ -558,21 +558,22 @@ H5B_split (H5F_t *f, H5B_class_t *type, H5B_t *old_bt, haddr_t old_addr,
assert (f);
assert (type);
assert (old_addr>=0);
+ assert (H5B_INS_LEFT==anchor || H5B_INS_RIGHT==anchor);
/*
* Initialize variables.
*/
assert (old_bt->nchildren == 2*H5B_K(f,type));
recsize = old_bt->sizeof_rkey + H5F_SIZEOF_OFFSET(f);
- delta = H5B_ANCHOR_LT==anchor ? H5B_K(f,type) : 0;
+ delta = H5B_INS_RIGHT==anchor ? H5B_K(f,type) : 0;
/*
* Create the new B-tree node.
*/
- if ((new_addr = H5B_new (f, type))<0) {
+ if ((new_addr = H5B_new (f, type, udata))<0) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTINIT, FAIL);
}
- if (NULL==(new_bt=H5AC_protect (f, H5AC_BT, new_addr, type))) {
+ if (NULL==(new_bt=H5AC_protect (f, H5AC_BT, new_addr, type, udata))) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
new_bt->level = old_bt->level;
@@ -606,12 +607,12 @@ H5B_split (H5F_t *f, H5B_class_t *type, H5B_t *old_bt, haddr_t old_addr,
/*
* Truncate the old node.
*/
- delta = H5B_ANCHOR_LT==anchor ? 0 : H5B_K(f,type);
+ delta = H5B_INS_RIGHT==anchor ? 0 : H5B_K(f,type);
old_bt->dirty = TRUE;
old_bt->ndirty = BOUND (0, old_bt->ndirty-delta, H5B_K(f,type));
old_bt->nchildren = H5B_K(f,type);
- if (H5B_ANCHOR_RT==anchor) {
+ if (H5B_INS_LEFT==anchor) {
HDmemcpy (old_bt->page + H5B_SIZEOF_HDR(f),
old_bt->page + H5B_SIZEOF_HDR(f) + delta*recsize,
H5B_K(f,type) * recsize);
@@ -642,12 +643,13 @@ H5B_split (H5F_t *f, H5B_class_t *type, H5B_t *old_bt, haddr_t old_addr,
/*
* Update sibling pointers.
*/
- if (H5B_ANCHOR_LT==anchor) {
+ if (H5B_INS_RIGHT==anchor) {
new_bt->left = old_addr;
new_bt->right = old_bt->right;
if (old_bt->right) {
- if (NULL==(tmp_bt=H5AC_find (f, H5AC_BT, old_bt->right, type))) {
+ if (NULL==(tmp_bt=H5AC_find (f, H5AC_BT, old_bt->right, type,
+ udata))) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
tmp_bt->dirty = TRUE;
@@ -659,7 +661,8 @@ H5B_split (H5F_t *f, H5B_class_t *type, H5B_t *old_bt, haddr_t old_addr,
new_bt->right = old_addr;
if (old_bt->left) {
- if (NULL==(tmp_bt=H5AC_find (f, H5AC_BT, old_bt->left, type))) {
+ if (NULL==(tmp_bt=H5AC_find (f, H5AC_BT, old_bt->left, type,
+ udata))) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
tmp_bt->dirty = TRUE;
@@ -702,7 +705,44 @@ H5B_decode_key (H5F_t *f, H5B_t *bt, intn idx)
FUNC_ENTER (H5B_decode_key, NULL, FAIL);
bt->key[idx].nkey = bt->native + idx * bt->type->sizeof_nkey;
- if ((bt->type->decode)(f, bt->key[idx].rkey, bt->key[idx].nkey)<0) {
+ if ((bt->type->decode)(f, bt, bt->key[idx].rkey,
+ bt->key[idx].nkey)<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5B_decode_keys
+ *
+ * Purpose: Decode keys on either side of the specified branch.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, October 14, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5B_decode_keys (H5F_t *f, H5B_t *bt, intn idx)
+{
+ FUNC_ENTER (H5B_decode_keys, NULL, FAIL);
+
+ assert (f);
+ assert (bt);
+ assert (idx>=0 && idx<bt->nchildren);
+
+ if (!bt->key[idx].nkey && H5B_decode_key (f, bt, idx)<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
+ }
+ if (!bt->key[idx+1].nkey && H5B_decode_key (f, bt, idx+1)<0) {
HRETURN_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
}
@@ -741,6 +781,7 @@ H5B_insert (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata)
size_t size;
uint8 *buf;
haddr_t tmp_addr;
+ H5B_ins_t anchor = H5B_INS_ERROR;
FUNC_ENTER (H5B_insert, NULL, FAIL);
@@ -749,17 +790,18 @@ H5B_insert (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata)
*/
assert (f);
assert (type);
- assert (type->sizeof_nkey < sizeof lt_key);
+ assert (type->sizeof_nkey <= sizeof lt_key);
- child = H5B_insert_helper (f, addr, type, lt_key, &lt_key_changed,
+ child = H5B_insert_helper (f, addr, type, &anchor, lt_key, &lt_key_changed,
md_key, udata, rt_key, &rt_key_changed);
- if (child<0) {
+ if (child<0 || anchor<0) {
HRETURN_ERROR (H5E_BTREE, H5E_CANTINIT, FAIL);
}
- if (0==child) HRETURN (addr);
+ if (H5B_INS_NOOP==anchor) HRETURN (addr);
+ assert (H5B_INS_RIGHT==anchor);
/* the current root */
- if (NULL==(bt = H5AC_find (f, H5AC_BT, addr, type))) {
+ if (NULL==(bt = H5AC_find (f, H5AC_BT, addr, type, udata))) {
HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
level = bt->level;
@@ -771,7 +813,7 @@ H5B_insert (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata)
}
/* the new node */
- if (NULL==(bt = H5AC_find (f, H5AC_BT, child, type))) {
+ if (NULL==(bt = H5AC_find (f, H5AC_BT, child, type, udata))) {
HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
if (!rt_key_changed) {
@@ -812,14 +854,14 @@ H5B_insert (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata)
addr = tmp_addr;
/* update the new child's left pointer */
- if (NULL==(bt=H5AC_find (f, H5AC_BT, child, type))) {
+ if (NULL==(bt=H5AC_find (f, H5AC_BT, child, type, udata))) {
HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
bt->dirty = TRUE;
bt->left = addr;
/* clear the old root at the old address */
- if (NULL==(bt=H5AC_find (f, H5AC_BT, new_root, type))) {
+ if (NULL==(bt=H5AC_find (f, H5AC_BT, new_root, type, udata))) {
HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
bt->dirty = TRUE;
@@ -830,7 +872,7 @@ H5B_insert (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata)
/* the new root */
- if (NULL==(bt = H5AC_find (f, H5AC_BT, new_root, type))) {
+ if (NULL==(bt = H5AC_find (f, H5AC_BT, new_root, type, udata))) {
HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
bt->dirty = TRUE;
@@ -877,7 +919,7 @@ H5B_insert (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata)
*/
static herr_t
H5B_insert_child (H5F_t *f, const H5B_class_t *type, H5B_t *bt,
- intn idx, haddr_t child, intn anchor, void *md_key)
+ intn idx, haddr_t child, H5B_ins_t anchor, void *md_key)
{
size_t recsize;
intn i;
@@ -888,7 +930,7 @@ H5B_insert_child (H5F_t *f, const H5B_class_t *type, H5B_t *bt,
bt->dirty = TRUE;
recsize = bt->sizeof_rkey + H5F_SIZEOF_OFFSET(f);
- if (H5B_ANCHOR_LT==anchor) {
+ if (H5B_INS_RIGHT==anchor) {
/*
* The MD_KEY is the left key of the new node.
*/
@@ -950,6 +992,7 @@ H5B_insert_child (H5F_t *f, const H5B_class_t *type, H5B_t *bt,
FUNC_LEAVE (SUCCEED);
}
+
/*-------------------------------------------------------------------------
* Function: H5B_insert_helper
@@ -985,6 +1028,7 @@ H5B_insert_child (H5F_t *f, const H5B_class_t *type, H5B_t *bt,
*/
static haddr_t
H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
+ H5B_ins_t *parent_ins,
uint8 *lt_key, hbool_t *lt_key_changed,
uint8 *md_key, void *udata,
uint8 *rt_key, hbool_t *rt_key_changed)
@@ -992,7 +1036,7 @@ H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
H5B_t *bt=NULL, *twin=NULL, *tmp_bt=NULL;
intn lt=0, idx=-1, rt, cmp=-1;
haddr_t child_addr=0, twin_addr=0, ret_value=FAIL;
- intn anchor;
+ H5B_ins_t my_ins = H5B_INS_ERROR;
FUNC_ENTER (H5B_insert_helper, NULL, FAIL);
@@ -1005,35 +1049,30 @@ H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
assert (type->decode);
assert (type->cmp);
assert (type->new);
+ assert (parent_ins && H5B_INS_ERROR==*parent_ins);
assert (lt_key);
assert (lt_key_changed);
assert (rt_key);
assert (rt_key_changed);
+ *lt_key_changed = FALSE;
+ *rt_key_changed = FALSE;
+
/*
* Use a binary search to find the child that will receive the new
* data. When the search completes IDX points to the child that
* should get the new data.
*/
- if (NULL==(bt=H5AC_protect (f, H5AC_BT, addr, type))) {
+ if (NULL==(bt=H5AC_protect (f, H5AC_BT, addr, type, udata))) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
rt = bt->nchildren;
while (lt<rt && cmp) {
idx = (lt + rt) / 2;
-
- /* left key */
- if (!bt->key[idx].nkey && H5B_decode_key (f, bt, idx)<0) {
- HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
- }
-
- /* right key */
- if (!bt->key[idx+1].nkey && H5B_decode_key (f, bt, idx+1)<0) {
- HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
+ if (H5B_decode_keys (f, bt, idx)<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
}
-
- /* compare */
if ((cmp=(type->cmp)(f, bt->key[idx].nkey, udata,
bt->key[idx+1].nkey))<0) {
rt = idx;
@@ -1042,46 +1081,14 @@ H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
}
}
- if (cmp<0 && idx<=0) {
- /*
- * Boundary condition: the value to insert is the new minimum
- * value in the B-tree. Insert the value in the left-most node.
- */
- idx = 0;
- cmp = 0;
-
- } else if (cmp>0 && idx+1>=bt->nchildren) {
+ if (0==bt->nchildren) {
/*
- * Boundary condition: the value to insert is the new maximum
- * value in the B-tree. Insert the value in the right-most node.
+ * The value being inserted will be the only value in this tree. We
+ * must necessarily be at level zero.
*/
- idx = bt->nchildren-1;
- cmp = 0;
- }
- assert (0==cmp);
-
- /*
- * Ensure that both native keys exist since we may have made boundary
- * condition adjustments.
- */
- if (bt->nchildren) {
- if (!bt->key[idx].nkey && H5B_decode_key (f, bt, idx)<0) {
- HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
- }
- if (!bt->key[idx+1].nkey && H5B_decode_key (f, bt, idx+1)<0) {
- HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
- }
- }
-
- /*
- * If there are no children, then create a new child. This can only
- * happen at the root of the B-tree. The left and right native keys
- * are output values from the node creation function.
- */
- if (0==bt->nchildren) {
+ assert (0==bt->level);
bt->key[0].nkey = bt->native;
bt->key[1].nkey = bt->native + type->sizeof_nkey;
-
if ((child_addr=(type->new)(f, bt->key[0].nkey, udata,
bt->key[1].nkey))<0) {
bt->key[0].nkey = bt->key[1].nkey = NULL;
@@ -1091,28 +1098,142 @@ H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
bt->dirty = TRUE;
bt->ndirty = 1;
bt->child[0] = child_addr;
-
bt->key[0].dirty = TRUE;
bt->key[1].dirty = TRUE;
idx = 0;
- }
- /*
- * Insert the new data in the child B-tree node or in the data node.
- */
- if (bt->level > 0) {
- child_addr = H5B_insert_helper (f, bt->child[idx], type,
+ if (type->follow_min) {
+ child_addr = (type->insert)(f, bt->child[idx], &my_ins,
+ bt->key[idx].nkey, lt_key_changed,
+ md_key, udata,
+ bt->key[idx+1].nkey, rt_key_changed);
+ } else {
+ my_ins = H5B_INS_NOOP;
+ }
+
+ } else if (cmp<0 && idx<=0 && bt->level>0) {
+ /*
+ * The value being inserted is less than any value in this tree. Follow
+ * the minimum branch out of this node to a subtree.
+ */
+ idx = 0;
+ if (H5B_decode_keys (f, bt, idx)<0) {
+ HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
+ }
+ child_addr = H5B_insert_helper (f, bt->child[idx], type, &my_ins,
bt->key[idx].nkey, lt_key_changed,
md_key, udata,
bt->key[idx+1].nkey, rt_key_changed);
- anchor = H5B_ANCHOR_LT;
+
+ } else if (cmp<0 && idx<=0 && type->follow_min) {
+ /*
+ * The value being inserted is less than any leaf node out of this
+ * current node. Follow the minimum branch to a leaf node and let the
+ * subclass handle the problem.
+ */
+ idx = 0;
+ if (H5B_decode_keys (f, bt, idx)<0) {
+ HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
+ }
+ child_addr = (type->insert)(f, bt->child[idx], &my_ins,
+ bt->key[idx].nkey, lt_key_changed,
+ md_key, udata,
+ bt->key[idx+1].nkey, rt_key_changed);
+
+ } else if (cmp<0 && idx<=0) {
+ /*
+ * The value being inserted is less than any leaf node out of the
+ * current node. Create a new minimum leaf node out of this B-tree
+ * node. This node is not empty (handled above).
+ */
+ idx = 0;
+ if (H5B_decode_keys (f, bt, idx)<0) {
+ HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
+ }
+ my_ins = H5B_INS_LEFT;
+ HDmemcpy (md_key, bt->key[idx].nkey, type->sizeof_nkey);
+ child_addr = (type->new)(f, bt->key[idx].nkey, udata, md_key);
+ *lt_key_changed = TRUE;
+
+ } else if (cmp>0 && idx+1>=bt->nchildren && bt->level>0) {
+ /*
+ * The value being inserted is larger than any value in this tree.
+ * Follow the maximum branch out of this node to a subtree.
+ */
+ idx = bt->nchildren - 1;
+ if (H5B_decode_keys (f, bt, idx)<0) {
+ HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
+ }
+ child_addr = H5B_insert_helper (f, bt->child[idx], type, &my_ins,
+ bt->key[idx].nkey, lt_key_changed,
+ md_key, udata,
+ bt->key[idx+1].nkey, rt_key_changed);
+
+ } else if (cmp>0 && idx+1>=bt->nchildren && type->follow_max) {
+ /*
+ * The value being inserted is larger than any leaf node out of the
+ * current node. Follow the maximum branch to a leaf node and let the
+ * subclass handle the problem.
+ */
+ idx = bt->nchildren - 1;
+ if (H5B_decode_keys (f, bt, idx)<0) {
+ HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
+ }
+ child_addr = (type->insert)(f, bt->child[idx], &my_ins,
+ bt->key[idx].nkey, lt_key_changed,
+ md_key, udata,
+ bt->key[idx+1].nkey, rt_key_changed);
+
+ } else if (cmp>0 && idx+1>=bt->nchildren) {
+ /*
+ * The value being inserted is larger than any leaf node out of the
+ * current node. Create a new maximum leaf node out of this B-tree
+ * node.
+ */
+ idx = bt->nchildren - 1;
+ if (H5B_decode_keys (f, bt, idx)<0) {
+ HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
+ }
+ my_ins = H5B_INS_RIGHT;
+ HDmemcpy (md_key, bt->key[idx+1].nkey, type->sizeof_nkey);
+ child_addr = (type->new)(f, md_key, udata, bt->key[idx+1].nkey);
+ *rt_key_changed = TRUE;
+
+ } else if (cmp) {
+ /*
+ * We couldn't figure out which branch to follow out of this node. THIS
+ * IS A MAJOR PROBLEM THAT NEEDS TO BE FIXED --rpm.
+ */
+ assert ("INTERNAL HDF5 ERROR (see rpm)" && 0);
+
+ } else if (bt->level>0) {
+ /*
+ * Follow a branch out of this node to another subtree.
+ */
+ assert (idx>=0 && idx<bt->nchildren);
+ child_addr = H5B_insert_helper (f, bt->child[idx], type, &my_ins,
+ bt->key[idx].nkey, lt_key_changed,
+ md_key, udata,
+ bt->key[idx+1].nkey, rt_key_changed);
+
+
} else {
- child_addr = (type->insert)(f, bt->child[idx], &anchor,
+ /*
+ * Follow a branch out of this node to a leaf node of some other type.
+ */
+ assert (idx>=0 && idx<bt->nchildren);
+ child_addr = (type->insert)(f, bt->child[idx], &my_ins,
bt->key[idx].nkey, lt_key_changed,
md_key, udata,
bt->key[idx+1].nkey, rt_key_changed);
+
+ }
+
+ if (child_addr<0 || my_ins<0) {
+ /* Insertion failed */
+ HGOTO_ERROR (H5E_BTREE, H5E_CANTINSERT, FAIL);
}
- if (child_addr<0) HGOTO_ERROR (H5E_BTREE, H5E_CANTINSERT, FAIL);
+
/*
* Update the left and right keys of the current node.
@@ -1136,36 +1257,43 @@ H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
}
}
- /*
- * Insert the child, splitting the current node if necessary.
- */
- if (child_addr) {
+ if (H5B_INS_CHANGE==my_ins) {
+ /*
+ * The insertion simply changed the address for the child.
+ */
+ bt->child[idx] = child_addr;
+ bt->dirty = TRUE;
+ bt->ndirty = MAX (bt->ndirty, idx+1);
+ *parent_ins = H5B_INS_NOOP;
+
+ } else if (H5B_INS_LEFT==my_ins || H5B_INS_RIGHT==my_ins) {
/*
- * If the child split and the left node is anchored, then the new
+ * The child split. If the left node is anchored, then the new
* child node gets inserted to the right of our current position.
*/
- if (H5B_ANCHOR_LT==anchor) idx++;
+ if (H5B_INS_RIGHT==my_ins) idx++;
if (bt->nchildren==2*H5B_K(f,type)) {
/* Split the current node */
- if ((twin_addr = H5B_split (f, type, bt, addr, anchor))<0) {
+ if ((twin_addr = H5B_split (f, type, bt, addr, my_ins, udata))<0) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTSPLIT, FAIL);
}
- if (NULL==(twin=H5AC_protect (f, H5AC_BT, twin_addr, type))) {
+ if (NULL==(twin=H5AC_protect (f, H5AC_BT, twin_addr, type,
+ udata))) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
if (idx<=H5B_K(f,type)) {
- tmp_bt = H5B_ANCHOR_LT==anchor ? bt : twin;
+ tmp_bt = H5B_INS_RIGHT==my_ins ? bt : twin;
} else {
idx -= H5B_K (f, type);
- tmp_bt = H5B_ANCHOR_LT==anchor ? twin : bt;
+ tmp_bt = H5B_INS_RIGHT==my_ins ? twin : bt;
}
} else {
tmp_bt = bt;
}
- if (H5B_insert_child (f, type, tmp_bt, idx, child_addr, anchor,
+ if (H5B_insert_child (f, type, tmp_bt, idx, child_addr, my_ins,
md_key)<0) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTINSERT, FAIL);
}
@@ -1177,7 +1305,7 @@ H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
* by the left and right node).
*/
if (twin) {
- if (H5B_ANCHOR_LT==anchor) {
+ if (H5B_INS_RIGHT==my_ins) {
if (!twin->key[0].nkey && H5B_decode_key (f, twin, 0)<0) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
}
@@ -1188,7 +1316,11 @@ H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
}
HDmemcpy (md_key, bt->key[0].nkey, type->sizeof_nkey);
}
+ *parent_ins = H5B_INS_RIGHT;
+ } else {
+ *parent_ins = H5B_INS_NOOP;
}
+
HGOTO_DONE (twin_addr);
done:
@@ -1241,7 +1373,7 @@ H5B_list (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata)
assert (addr>=0);
assert (udata);
- if (NULL==(bt = H5AC_find (f, H5AC_BT, addr, type))) {
+ if (NULL==(bt = H5AC_find (f, H5AC_BT, addr, type, udata))) {
HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
@@ -1254,7 +1386,7 @@ H5B_list (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata)
} else {
for (/*void*/; addr>0; addr=next_addr) {
- if (NULL==(bt=H5AC_protect (f, H5AC_BT, addr, type))) {
+ if (NULL==(bt=H5AC_protect (f, H5AC_BT, addr, type, udata))) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
@@ -1318,6 +1450,7 @@ H5B_nodesize (H5F_t *f, const H5B_class_t *type,
assert (f);
assert (type);
assert (sizeof_rkey>0);
+ assert (H5B_K (f, type)>0);
/*
* Total native key size.
@@ -1356,7 +1489,7 @@ H5B_nodesize (H5F_t *f, const H5B_class_t *type,
*/
herr_t
H5B_debug (H5F_t *f, haddr_t addr, FILE *stream, intn indent,
- intn fwidth, H5B_class_t *type)
+ intn fwidth, H5B_class_t *type, void *udata)
{
H5B_t *bt = NULL;
int i;
@@ -1376,7 +1509,7 @@ H5B_debug (H5F_t *f, haddr_t addr, FILE *stream, intn indent,
/*
* Load the tree node.
*/
- if (NULL==(bt=H5AC_find (f, H5AC_BT, addr, type))) {
+ if (NULL==(bt=H5AC_find (f, H5AC_BT, addr, type, udata))) {
HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
diff --git a/src/H5Bprivate.h b/src/H5Bprivate.h
index 7814eeb..05e2e56 100644
--- a/src/H5Bprivate.h
+++ b/src/H5Bprivate.h
@@ -33,11 +33,17 @@
#define H5B_K(F,TYPE) /*K value given file and Btree subclass */ \
((F)->shared->file_create_parms.btree_k[(TYPE)->id])
-#define H5B_ANCHOR_LT 0 /* left node is anchored, right is new */
-#define H5B_ANCHOR_RT 1 /* right node is anchored, left is new */
+typedef enum H5B_ins_t {
+ H5B_INS_ERROR =-1, /*error return value */
+ H5B_INS_NOOP =0, /*insert made no changes */
+ H5B_INS_LEFT =1, /*insert new node to left of cur node */
+ H5B_INS_RIGHT =2, /*insert new node to right of cur node */
+ H5B_INS_CHANGE =3 /*change child address for cur node */
+} H5B_ins_t;
typedef enum H5B_subid_t {
- H5B_SNODE_ID =0 /*B-tree is for symbol table nodes */
+ H5B_SNODE_ID =0, /*B-tree is for symbol table nodes */
+ H5B_ISTORE_ID =1 /*B-tree is for indexed object storage */
} H5B_subid_t;
@@ -48,18 +54,21 @@ typedef enum H5B_subid_t {
* has an array of K values indexed by the `id' class field below. The
* array is initialized with the HDF5_BTREE_K_DEFAULT macro.
*/
+struct H5B_t; /*forward decl*/
typedef struct H5B_class_t {
H5B_subid_t id; /*id as found in file */
size_t sizeof_nkey; /*size of native (memory) key */
- size_t (*get_sizeof_rkey)(H5F_t*);
- haddr_t (*new)(H5F_t*,void*,void*,void*);
- intn (*cmp)(H5F_t*,void*,void*,void*);
+ size_t (*get_sizeof_rkey)(H5F_t*,const void*);/*raw key size */
+ haddr_t (*new)(H5F_t*,void*,void*,void*); /*create new leaf */
+ intn (*cmp)(H5F_t*,void*,void*,void*); /*compare keys */
herr_t (*found)(H5F_t*,haddr_t,const void*,void*,const void*);
- haddr_t (*insert)(H5F_t*,haddr_t,int*,void*,hbool_t*,void*,void*,
- void*,hbool_t*);
- herr_t (*list)(H5F_t*,haddr_t,void*);
- herr_t (*decode)(H5F_t*,uint8*,void*);
- herr_t (*encode)(H5F_t*,uint8*,void*);
+ haddr_t (*insert)(H5F_t*,haddr_t,H5B_ins_t*,void*,hbool_t*,void*,void*,
+ void*,hbool_t*); /*insert new data */
+ hbool_t follow_min; /*min insert uses min leaf, not new() */
+ hbool_t follow_max; /*max insert uses max leaf, not new() */
+ herr_t (*list)(H5F_t*,haddr_t,void*); /*traverse leaf nodes */
+ herr_t (*decode)(H5F_t*,struct H5B_t*,uint8*,void*);
+ herr_t (*encode)(H5F_t*,struct H5B_t*,uint8*,void*);
} H5B_class_t;
/*
@@ -91,8 +100,8 @@ typedef struct H5B_t {
* Library prototypes.
*/
herr_t H5B_debug (H5F_t *f, haddr_t addr, FILE *stream, intn indent,
- intn fwidth, H5B_class_t *type);
-haddr_t H5B_new (H5F_t *f, const H5B_class_t *type);
+ intn fwidth, H5B_class_t *type, void *udata);
+haddr_t H5B_new (H5F_t *f, const H5B_class_t *type, void *udata);
herr_t H5B_find (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata);
haddr_t H5B_insert (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata);
herr_t H5B_list (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata);
diff --git a/src/H5C.c b/src/H5C.c
index e4b263a..67be020 100644
--- a/src/H5C.c
+++ b/src/H5C.c
@@ -146,7 +146,7 @@ hid_t H5C_get_default_atom(hobjtype_t type)
case H5_TEMPLATE:
if(default_file_id==FAIL)
{
- if((default_file_id=H5Aregister_atom(H5_TEMPLATE, (const VOIDP)&default_file_create))==FAIL)
+ if((default_file_id=H5Aregister_atom(H5_TEMPLATE, (const void *)&default_file_create))==FAIL)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL);
} /* end else */
HGOTO_DONE(default_file_id);
@@ -324,6 +324,9 @@ done:
Robb Matzke, 13 Aug 1997
Removed H5_BTREE_SIZE and replaced it with H5_SYM_LEAF_K and
H5_SYM_INTERN_K.
+
+ Robb Matzke, 17 Oct 1997
+ Added H5_ISTORE_K.
--------------------------------------------------------------------------*/
herr_t H5Cgetparm(hid_t tid, file_create_param_t parm, VOIDP buf)
{
@@ -365,6 +368,10 @@ herr_t H5Cgetparm(hid_t tid, file_create_param_t parm, VOIDP buf)
*(uintn *)buf = template->btree_k[H5B_SNODE_ID];
break;
+ case H5_ISTORE_K:
+ *(uintn *)buf = template->btree_k[H5B_ISTORE_ID];
+ break;
+
case H5_BOOTBLOCK_VER:
*(uint8 *)buf=template->bootblock_ver;
break;
@@ -430,6 +437,9 @@ done:
Robb Matzke, 15 Sep 1997
Fixed the power-of-two test to work with any size integer.
+
+ Robb Matzke, 17 Oct 1997
+ Added H5_ISTORE_K.
--------------------------------------------------------------------------*/
herr_t H5Csetparm(hid_t tid, file_create_param_t parm, const VOIDP buf)
{
@@ -494,6 +504,14 @@ herr_t H5Csetparm(hid_t tid, file_create_param_t parm, const VOIDP buf)
}
template->btree_k[H5B_SNODE_ID] = val;
break;
+
+ case H5_ISTORE_K:
+ val = *(const uintn *)buf;
+ if (val<2) {
+ HGOTO_ERROR (H5E_ARGS, H5E_BADRANGE, FAIL);
+ }
+ template->btree_k[H5B_ISTORE_ID] = val;
+ break;
case H5_BOOTBLOCK_VER: /* this should be range checked */
template->bootblock_ver=*(const uint8 *)buf;
diff --git a/src/H5Cprivate.h b/src/H5Cprivate.h
index 675fba6..168b253 100644
--- a/src/H5Cprivate.h
+++ b/src/H5Cprivate.h
@@ -34,7 +34,7 @@
#define H5C_BTREE_K_DEFAULT { \
16, /* Symbol table internal nodes */ \
- 0, /* unused */ \
+ 32, /* Indexed storage intern nodes */ \
0, /* unused */ \
0, /* unused */ \
0, /* unused */ \
diff --git a/src/H5Cpublic.h b/src/H5Cpublic.h
index 08e7656..4d2fd7d 100644
--- a/src/H5Cpublic.h
+++ b/src/H5Cpublic.h
@@ -37,6 +37,7 @@ typedef enum {
H5_LENGTH_SIZE, /* (uint8) Number of bytes for lengths */
H5_SYM_LEAF_K, /* (uintn) 1/2 rank for symbol table leaf nodes */
H5_SYM_INTERN_K, /* (uintn) 1/2 rank for symbol table internal nodes */
+ H5_ISTORE_K, /* (uintn) 1/2 rank for indexed storage nodes */
H5_BOOTBLOCK_VER, /* (uint8) Version # of the boot-block format */
H5_SMALLOBJECT_VER, /* (uint8) Version # of the small-object heap format */
H5_FREESPACE_VER, /* (uint8) Version # of the free-space info format */
diff --git a/src/H5D.c b/src/H5D.c
index 6153667..7d8b2d3 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -158,7 +158,7 @@ hid_t H5D_create(hid_t owner_id, hobjtype_t type, const char *name)
/* Open (and create) a new file object */
if (NULL==(new_dset->ent = H5G_create (file, name, H5D_MINHDR_SIZE))) {
- HGOTO_ERROR (H5E_DIRECTORY, H5E_CANTINIT, FAIL);
+ HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
}
/* Register the new datatype and get an ID for it */
@@ -183,14 +183,14 @@ done:
Get the OID for accessing an existing HDF5 dataset object
USAGE
hoid_t H5D_find_name(grp_id, type, name)
- hid_t grp_id; IN: Atom for directory to search for dataset
+ hid_t grp_id; IN: Atom for group to search for dataset
hobjtype_t type; IN: Type of object to search for (dataset in
this case)
const char *name; IN: Name of the object to search for
RETURNS
Returns ID (atom) on success, FAIL on failure
DESCRIPTION
- This function finds for a dataset by name in a directory.
+ This function finds for a dataset by name in a group.
--------------------------------------------------------------------------*/
hid_t H5D_find_name(hid_t grp_id, hobjtype_t obj_type, const char *name)
{
@@ -215,7 +215,7 @@ hid_t H5D_find_name(hid_t grp_id, hobjtype_t obj_type, const char *name)
if(NULL==(dset=HDcalloc(1, sizeof(H5D_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL);
- /* Initialize file, directory, name fields */
+ /* Initialize file, group, name fields */
dset->file = file;
dset->dirty = FALSE;
diff --git a/src/H5Distore.c b/src/H5Distore.c
new file mode 100644
index 0000000..b52288c
--- /dev/null
+++ b/src/H5Distore.c
@@ -0,0 +1,740 @@
+/*
+ * Copyright (C) 1997 Spizella Software
+ * All rights reserved.
+ *
+ * Programmer: Robb Matzke <robb@arborea.spizella.com>
+ * Wednesday, October 8, 1997
+ */
+#include <H5private.h>
+#include <H5Eprivate.h>
+#include <H5Fprivate.h>
+#include <H5MFprivate.h>
+#include <H5MMprivate.h>
+#include <H5Oprivate.h>
+#include <H5Vprivate.h>
+
+typedef enum H5F_isop_t {
+ H5F_ISTORE_READ, /*read from file to memory */
+ H5F_ISTORE_WRITE /*write from memory to file */
+} H5F_isop_t;
+
+/* Does the array domain include negative indices? */
+#undef H5F_ISTORE_NEGATIVE_DOMAIN
+
+
+#define PABLO_MASK H5F_istore_mask
+
+/* Is the interface initialized? */
+static hbool_t interface_initialize_g = FALSE;
+
+/* PRIVATE PROTOTYPES */
+static size_t H5F_istore_sizeof_rkey (H5F_t *f, const void *_udata);
+static haddr_t H5F_istore_new (H5F_t *f, void *_lt_key, void *_udata,
+ void *_rt_key);
+static intn H5F_istore_cmp (H5F_t *f, void *_lt_key, void *_udata,
+ void *_rt_key);
+static herr_t H5F_istore_found (H5F_t *f, haddr_t addr, const void *_lt_key,
+ void *_udata, const void *_rt_key);
+static haddr_t H5F_istore_insert (H5F_t *f, haddr_t addr, H5B_ins_t *anchor,
+ void *_lt_key, hbool_t *lt_key_changed,
+ void *_md_key, void *_udata,
+ void *_rt_key, hbool_t *rt_key_changed);
+static herr_t H5F_istore_decode_key (H5F_t *f, H5B_t *bt, uint8 *raw,
+ void *_key);
+static herr_t H5F_istore_encode_key (H5F_t *f, H5B_t *bt, uint8 *raw,
+ void *_key);
+static herr_t H5F_istore_copy_hyperslab (H5F_t *f, H5O_istore_t *istore,
+ H5F_isop_t op, size_t offset_f[],
+ size_t size[], size_t offset_m[],
+ size_t size_m[], void *buf);
+
+
+/*
+ * B-tree key. A key contains the minimum logical N-dimensional address and
+ * the logical size of the chunk to which this key refers. The
+ * fastest-varying dimension is assumed to reference individual bytes of the
+ * array, so a 100-element 1-d array of 4-byte integers would really be a 2-d
+ * array with the slow varying dimension of size 100 and the fast varying
+ * dimension of size 4 (the storage dimensionality has very little to do with
+ * the real dimensionality).
+ *
+ * Only the first few values of the OFFSET and SIZE fields are actually
+ * stored on disk, depending on the dimensionality.
+ *
+ * The storage file address is part of the B-tree and not part of the key.
+ */
+typedef struct H5F_istore_key_t {
+ size_t offset[H5O_ISTORE_NDIMS]; /*logical offset to start*/
+ size_t size[H5O_ISTORE_NDIMS]; /*logical chunk size */
+} H5F_istore_key_t;
+
+typedef struct H5F_istore_ud1_t {
+ H5F_istore_key_t key; /*key values */
+ haddr_t addr; /*file address of chunk */
+ H5O_istore_t mesg; /*storage message */
+} H5F_istore_ud1_t;
+
+/* inherits B-tree like properties from H5B */
+H5B_class_t H5B_ISTORE[1] = {{
+ H5B_ISTORE_ID, /*id */
+ sizeof (H5F_istore_key_t), /*sizeof_nkey */
+ H5F_istore_sizeof_rkey, /*get_sizeof_rkey */
+ H5F_istore_new, /*new */
+ H5F_istore_cmp, /*cmp */
+ H5F_istore_found, /*found */
+ H5F_istore_insert, /*insert */
+ FALSE, /*follow min branch? */
+ FALSE, /*follow max branch? */
+ NULL, /*list */
+ H5F_istore_decode_key, /*decode */
+ H5F_istore_encode_key, /*encode */
+}};
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_sizeof_rkey
+ *
+ * Purpose: Returns the size of a raw key for the specified UDATA. The
+ * size of the key is dependent on the number of dimensions for
+ * the object to which this B-tree points. The dimensionality
+ * of the UDATA is the only portion that's referenced here.
+ *
+ * Return: Success: Size of raw key in bytes.
+ *
+ * Failure: abort()
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, October 8, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static size_t
+H5F_istore_sizeof_rkey (H5F_t *f, const void *_udata)
+{
+ const H5F_istore_ud1_t *udata = (const H5F_istore_ud1_t *)_udata;
+
+ assert (udata);
+ assert (udata->mesg.ndims>0 && udata->mesg.ndims<=H5O_ISTORE_NDIMS);
+
+ return udata->mesg.ndims * (4 + 4);
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_decode_key
+ *
+ * Purpose: Decodes a raw key into a native key for the B-tree
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Friday, October 10, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_istore_decode_key (H5F_t *f, H5B_t *bt, uint8 *raw, void *_key)
+{
+ H5F_istore_key_t *key = (H5F_istore_key_t *)_key;
+ int i;
+ int ndims = bt->sizeof_rkey / 8;
+
+ FUNC_ENTER (H5F_istore_decode_key, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (bt);
+ assert (raw);
+ assert (key);
+ assert (ndims>0 && ndims<=H5O_ISTORE_NDIMS && 8*ndims==bt->sizeof_rkey);
+
+ /* decode */
+ for (i=0; i<ndims; i++) {
+ UINT32DECODE (raw, key->offset[i]);
+ UINT32DECODE (raw, key->size[i]);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_encode_key
+ *
+ * Purpose: Encode a key from native format to raw format.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Friday, October 10, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_istore_encode_key (H5F_t *f, H5B_t *bt, uint8 *raw, void *_key)
+{
+ H5F_istore_key_t *key = (H5F_istore_key_t *)_key;
+ intn ndims = bt->sizeof_rkey / 8;
+ intn i;
+
+ FUNC_ENTER (H5F_istore_encode_key, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (bt);
+ assert (raw);
+ assert (key);
+ assert (ndims>0 && ndims<=H5O_ISTORE_NDIMS && 8*ndims==bt->sizeof_rkey);
+
+ /* encode */
+ for (i=0; i<ndims; i++) {
+ UINT32ENCODE (raw, key->offset[i]);
+ UINT32ENCODE (raw, key->size[i]);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_cmp
+ *
+ * Purpose: Compare the requested datum UDATA with the left and right
+ * keys of the B-tree.
+ *
+ * Return: Success: negative if the min_corner of UDATA is less
+ * than the min_corner of LT_KEY.
+ *
+ * positive if the min_corner of UDATA is
+ * greater than or equal the min_corner of
+ * RT_KEY.
+ *
+ * zero otherwise. The min_corner of UDATA is
+ * not necessarily contained within the address
+ * space represented by LT_KEY, but a key that
+ * would describe the UDATA min_corner address
+ * would fall lexicographically between LT_KEY
+ * and RT_KEY.
+ *
+ * Failure: FAIL (same as UDATA < LT_KEY)
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, October 8, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static intn
+H5F_istore_cmp (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
+{
+ H5F_istore_key_t *lt_key = (H5F_istore_key_t *)_lt_key;
+ H5F_istore_key_t *rt_key = (H5F_istore_key_t *)_rt_key;
+ H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *)_udata;
+
+ assert (lt_key);
+ assert (rt_key);
+ assert (udata);
+ assert (udata->mesg.ndims>0 && udata->mesg.ndims<=H5O_ISTORE_NDIMS);
+
+ if (H5V_vector_lt (udata->mesg.ndims, udata->key.offset, lt_key->offset)) {
+ return -1;
+ } else if (H5V_vector_ge (udata->mesg.ndims, udata->key.offset,
+ rt_key->offset)) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_new
+ *
+ * Purpose: Adds a new entry to an i-storage B-tree. We can assume that
+ * the domain represented by UDATA doesn't intersect the domain
+ * already represented by the B-tree.
+ *
+ * Return: Success: Address of leaf, which is passed in from the
+ * UDATA pointer.
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, October 14, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static haddr_t
+H5F_istore_new (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
+{
+ H5F_istore_key_t *lt_key = (H5F_istore_key_t *)_lt_key;
+ H5F_istore_key_t *rt_key = (H5F_istore_key_t *)_rt_key;
+ H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *)_udata;
+ size_t nbytes;
+ intn i;
+
+ FUNC_ENTER (H5F_istore_new, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (lt_key);
+ assert (rt_key);
+ assert (udata);
+ assert (udata->mesg.ndims>=0 && udata->mesg.ndims<H5O_ISTORE_NDIMS);
+
+ /* Allocate new storage */
+ nbytes = H5V_vector_reduce_product (udata->mesg.ndims, udata->key.size);
+ assert (nbytes>0);
+ if ((udata->addr=H5MF_alloc (f, nbytes))<0) {
+ /* Couldn't allocate new file storage */
+ HRETURN_ERROR (H5E_IO, H5E_CANTINIT, FAIL);
+ }
+
+ /* left key describes the UDATA, right key is a zero-size "edge" */
+ for (i=0; i<udata->mesg.ndims; i++) {
+ lt_key->offset[i] = udata->key.offset[i];
+ lt_key->size[i] = udata->key.size[i];
+ assert (udata->key.size[i]>0);
+
+ rt_key->offset[i] = udata->key.offset[i] + udata->key.size[i];
+ rt_key->size[i] = 0;
+ }
+
+
+ FUNC_LEAVE (udata->addr);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_found
+ *
+ * Purpose: This function is called when the B-tree search engine has
+ * found the leaf entry that points to a chunk of storage that
+ * contains the beginning of the logical address space
+ * represented by UDATA. The LT_KEY is the left key (the one
+ * that describes the chunk) and RT_KEY is the right key (the
+ * one that describes the next or last chunk).
+ *
+ * Return: Success: SUCCEED with information about the chunk
+ * returned through the UDATA argument.
+ *
+ * Failure: FAIL if not found.
+ *
+ * Programmer: Robb Matzke
+ * Thursday, October 9, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_istore_found (H5F_t *f, haddr_t addr, const void *_lt_key,
+ void *_udata, const void *_rt_key)
+{
+ H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *)_udata;
+ const H5F_istore_key_t *lt_key = (const H5F_istore_key_t *)_lt_key;
+ const H5F_istore_key_t *rt_key = (const H5F_istore_key_t *)_rt_key;
+ int i;
+
+ FUNC_ENTER (H5F_istore_found, NULL, FAIL);
+
+ /* Check arguments */
+ assert (f);
+ assert (addr>=0);
+ assert (udata);
+ assert (lt_key);
+ assert (rt_key);
+
+ /* Initialize return values */
+ udata->addr = addr;
+ for (i=0; i<udata->mesg.ndims; i++) {
+ udata->key.offset[i] = lt_key->offset[i];
+ udata->key.size[i] = lt_key->size[i];
+ assert (lt_key->size[i]>0);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_insert
+ *
+ * Purpose: This function is called when the B-tree insert engine finds
+ * the node to use to insert new data. The UDATA argument
+ * points to a struct that describes the logical addresses being
+ * added to the file. This function allocates space for the
+ * data and returns information through UDATA describing a
+ * file chunk to receive (part of) the data.
+ *
+ * The LT_KEY is always the key describing the chunk of file
+ * memory at address ADDR. On entry, UDATA describes the logical
+ * addresses for which storage is being requested (through the
+ * `offset' and `size' fields). On return, UDATA describes the
+ * logical addresses contained in a chunk on disk.
+ *
+ * Return: Success: SUCCEED, with UDATA containing information
+ * about the (newly allocated) chunk.
+ *
+ * If the storage address has changed then the
+ * new address is returned.
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Thursday, October 9, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static haddr_t
+H5F_istore_insert (H5F_t *f, haddr_t addr, H5B_ins_t *parent_ins,
+ void *_lt_key, hbool_t *lt_key_changed,
+ void *_md_key, void *_udata,
+ void *_rt_key, hbool_t *rt_key_changed)
+{
+ H5F_istore_key_t *lt_key = (H5F_istore_key_t *)_lt_key;
+ H5F_istore_key_t *md_key = (H5F_istore_key_t *)_md_key;
+ H5F_istore_key_t *rt_key = (H5F_istore_key_t *)_rt_key;
+ H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *)_udata;
+ intn i, cmp;
+ haddr_t ret_value = 0;
+ size_t nbytes;
+
+ FUNC_ENTER (H5F_istore_insert, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (addr>=0);
+ assert (parent_ins);
+ assert (lt_key);
+ assert (lt_key_changed);
+ assert (md_key);
+ assert (udata);
+ assert (rt_key);
+ assert (rt_key_changed);
+
+ cmp = H5F_istore_cmp (f, lt_key, udata, rt_key);
+ assert (cmp<=0);
+
+ if (cmp<0) {
+ /* Negative indices not supported yet */
+ assert ("HDF5 INTERNAL ERROR -- see rpm" && 0);
+ HRETURN_ERROR (H5E_STORAGE, H5E_UNSUPPORTED, FAIL);
+
+ } else if (H5V_hyper_eq (udata->mesg.ndims,
+ udata->key.offset, udata->key.size,
+ lt_key->offset, lt_key->size)) {
+ /*
+ * Already exists. Just return the info.
+ */
+ udata->addr = addr;
+ *parent_ins = H5B_INS_NOOP;
+
+ } else if (H5V_hyper_disjointp (udata->mesg.ndims,
+ lt_key->offset, lt_key->size,
+ udata->key.offset, udata->key.size)) {
+ assert (H5V_hyper_disjointp (udata->mesg.ndims,
+ rt_key->offset, rt_key->size,
+ udata->key.offset, udata->key.size));
+
+ /*
+ * Split this node, inserting the new new node to the right of the
+ * current node. The MD_KEY is where the split occurs.
+ */
+ for (i=0, nbytes=1; i<udata->mesg.ndims; i++) {
+ assert (0==udata->key.offset[i] % udata->mesg.alignment[i]);
+ assert (udata->key.size[i] == udata->mesg.alignment[i]);
+ md_key->offset[i] = udata->key.offset[i];
+ md_key->size[i] = udata->key.size[i];
+ nbytes *= udata->key.size[i];
+ }
+
+ /*
+ * Allocate storage for the new chunk
+ */
+ if ((udata->addr=ret_value=H5MF_alloc (f, nbytes))<=0) {
+ HRETURN_ERROR (H5E_IO, H5E_CANTINIT, FAIL);
+ }
+
+ *parent_ins = H5B_INS_RIGHT;
+
+ } else {
+ assert ("HDF5 INTERNAL ERROR -- see rpm" && 0);
+ HRETURN_ERROR (H5E_IO, H5E_UNSUPPORTED, FAIL);
+ }
+
+ FUNC_LEAVE (ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_copy_hyperslab
+ *
+ * Purpose: Reads or writes a hyperslab to disk depending on whether OP
+ * is H5F_ISTORE_READ or H5F_ISTORE_WRITE. The hyperslab
+ * storage is described with ISTORE and exists in file F. The
+ * file hyperslab begins at location OFFSET_F[] (an N-dimensional
+ * point in the domain in terms of elements) in the file and
+ * OFFSET_M[] in memory pointed to by BUF. Its size is SIZE[]
+ * elements. The dimensionality of memory is assumed to be the
+ * same as the file and the total size of the multi-dimensional
+ * memory buffer is SIZE_M[].
+ *
+ * The slowest varying dimension is always listed first in the
+ * various offset and size arrays.
+ *
+ * A `chunk' is a hyperslab of the disk array which is stored
+ * contiguously. I/O occurs in units of chunks where the size of
+ * a chunk is determined by the alignment constraints specified
+ * in ISTORE.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Friday, October 17, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_istore_copy_hyperslab (H5F_t *f, H5O_istore_t *istore, H5F_isop_t op,
+ size_t offset_f[], size_t size[],
+ size_t offset_m[], size_t size_m[], void *buf)
+{
+ intn i, carry;
+ size_t idx_cur[H5O_ISTORE_NDIMS];
+ size_t idx_min[H5O_ISTORE_NDIMS];
+ size_t idx_max[H5O_ISTORE_NDIMS];
+ size_t sub_size[H5O_ISTORE_NDIMS];
+ size_t sub_offset_f[H5O_ISTORE_NDIMS];
+ size_t sub_offset_m[H5O_ISTORE_NDIMS];
+ size_t sub_offset_ch[H5O_ISTORE_NDIMS];
+ size_t chunk_size;
+ uint8 *chunk=NULL;
+ H5F_istore_ud1_t udata;
+ herr_t status;
+ herr_t ret_value = FAIL;
+
+ FUNC_ENTER (H5F_istore_copy_hyperslab, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (istore);
+ assert (istore->ndims>0 && istore->ndims<=H5O_ISTORE_NDIMS);
+ assert (H5F_ISTORE_READ==op || H5F_ISTORE_WRITE==op);
+ assert (size);
+ assert (size_m);
+ assert (buf);
+#ifndef NDEBUG
+ for (i=0; i<istore->ndims; i++) {
+ assert (!offset_f || offset_f[i]>=0);/*neg domains unsupported */
+ assert (!offset_m || offset_m[i]>=0);/*mem array offset never neg */
+ assert (size[i]>=0); /*size may be zero, implies no-op */
+ assert (size_m[i]>0); /*destination must exist */
+ /*hyperslab must fit in BUF*/
+ assert ((offset_m?offset_m[i]:0)+size[i]<=size_m[i]);
+ assert (istore->alignment[i]>0);
+ }
+#endif
+
+ /*
+ * Does the B-tree exist?
+ */
+ if (istore->btree_addr<=0) {
+ if (H5F_ISTORE_WRITE==op) {
+ udata.mesg.ndims = istore->ndims;
+ if ((istore->btree_addr=H5B_new (f, H5B_ISTORE, &udata))<0) {
+ /* Can't create B-tree */
+ HGOTO_ERROR (H5E_IO, H5E_CANTINIT, FAIL);
+ }
+ } else {
+ H5V_hyper_fill (istore->ndims, size, size_m, offset_m, buf, 0);
+ HRETURN (SUCCEED);
+ }
+ }
+
+ /* Initialize indices */
+ for (i=0; i<istore->ndims; i++) {
+ idx_min[i] = (offset_f?offset_f[i]:0) / istore->alignment[i];
+ idx_max[i] = ((offset_f?offset_f[i]:0)+size[i]-1)/istore->alignment[i]+1;
+ idx_cur[i] = idx_min[i];
+ }
+
+ /* Allocate buffers */
+ for (i=0, chunk_size=1; i<istore->ndims; i++) {
+ chunk_size *= istore->alignment[i];
+ }
+ chunk = H5MM_xmalloc (chunk_size);
+
+ /* Initialize non-changing part of udata */
+ udata.mesg = *istore;
+
+ /* Loop over all chunks */
+ while (1) {
+
+ /* Read/Write chunk or create it if it doesn't exist */
+ udata.mesg.ndims = istore->ndims;
+ for (i=0; i<istore->ndims; i++) {
+ udata.key.offset[i] = idx_cur[i] * istore->alignment[i];
+ udata.key.size[i] = istore->alignment[i];
+ sub_offset_f[i] = MAX ((offset_f?offset_f[i]:0), udata.key.offset[i]);
+ sub_offset_m[i] = (offset_m?offset_m[i]:0) +
+ sub_offset_f[i] - (offset_f?offset_f[i]:0);
+ sub_size[i] = (idx_cur[i]+1)*istore->alignment[i]-sub_offset_f[i];
+ sub_offset_ch[i] = sub_offset_f[i] - udata.key.offset[i];
+ }
+ if (H5F_ISTORE_WRITE==op) {
+ status = H5B_insert (f, H5B_ISTORE, istore->btree_addr, &udata);
+ assert (status>=0);
+ } else {
+ status = H5B_find (f, H5B_ISTORE, istore->btree_addr, &udata);
+ }
+
+ /*
+ * If the operation is reading from the disk or if we are writing a
+ * partial chunk then load the chunk from disk.
+ */
+ if (H5F_ISTORE_READ==op ||
+ !H5V_hyper_eq (istore->ndims,
+ udata.key.offset, udata.key.size,
+ sub_offset_f, sub_size)) {
+ if (status>=0) {
+ if (H5F_block_read (f, udata.addr, chunk_size, chunk)<0) {
+ HGOTO_ERROR (H5E_IO, H5E_READERROR, FAIL);
+ }
+ } else {
+ HDmemset (chunk, 0, chunk_size);
+ }
+ }
+
+ /* Transfer data to/from the chunk */
+ if (H5F_ISTORE_WRITE==op) {
+ H5V_hyper_copy (istore->ndims, sub_size,
+ udata.key.size, sub_offset_ch, chunk,
+ size_m, sub_offset_m, buf);
+ if (H5F_block_write (f, udata.addr, chunk_size, chunk)<0) {
+ HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL);
+ }
+ } else {
+ H5V_hyper_copy (istore->ndims, sub_size,
+ size_m, sub_offset_m, buf,
+ udata.key.size, sub_offset_ch, chunk);
+ }
+
+ /* Increment indices */
+ for (i=istore->ndims-1, carry=1; i>=0 && carry; --i) {
+ if (++idx_cur[i]>=idx_max[i]) idx_cur[i] = idx_min[i];
+ else carry = 0;
+ }
+ if (carry) break;
+ }
+ ret_value = SUCCEED;
+
+
+ done:
+ chunk = H5MM_xfree (chunk);
+ FUNC_LEAVE (ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_read
+ *
+ * Purpose: Reads a multi-dimensional buffer from (part of) an indexed raw
+ * storage array.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, October 15, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_istore_read (H5F_t *f, struct H5O_istore_t *istore,
+ size_t offset[], size_t size[], void *buf)
+{
+ FUNC_ENTER (H5F_istore_read, NULL, FAIL);
+
+ /* Check args */
+ assert (f);
+ assert (istore);
+ assert (istore->ndims>0 && istore->ndims<=H5O_ISTORE_NDIMS);
+ assert (size);
+ assert (buf);
+
+ if (H5F_istore_copy_hyperslab (f, istore, H5F_ISTORE_READ,
+ offset, size, H5V_ZERO, size, buf)<0) {
+ /* hyperslab output failure */
+ HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_write
+ *
+ * Purpose: Writes a multi-dimensional buffer to (part of) an indexed raw
+ * storage array.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, October 15, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_istore_write (H5F_t *f, struct H5O_istore_t *istore,
+ size_t offset[], size_t size[], void *buf)
+{
+ FUNC_ENTER (H5F_istore_write, NULL, FAIL);
+
+ /* Check args */
+ assert (f);
+ assert (istore);
+ assert (istore->ndims>0 && istore->ndims<=H5O_ISTORE_NDIMS);
+ assert (size);
+ assert (buf);
+
+ if (H5F_istore_copy_hyperslab (f, istore, H5F_ISTORE_WRITE,
+ offset, size, H5V_ZERO, size, buf)<0) {
+ /* hyperslab output failure */
+ HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
diff --git a/src/H5E.c b/src/H5E.c
index 866f8c6..80ab219 100644
--- a/src/H5E.c
+++ b/src/H5E.c
@@ -59,10 +59,10 @@ static const hdf_maj_error_messages_t hdf_maj_error_messages[] =
{H5E_SYM, "Symbol Table"},
{H5E_HEAP, "Heap"},
{H5E_OHDR, "Object Header"},
- {H5E_DIRECTORY, "Directory"},
{H5E_DATATYPE, "Datatype"},
{H5E_DATASPACE, "Dataspace"},
- {H5E_DATASET, "Dataset"}
+ {H5E_DATASET, "Dataset"},
+ {H5E_STORAGE, "Data Storage"},
};
static const hdf_min_error_messages_t hdf_min_error_messages[] =
@@ -104,6 +104,7 @@ static const hdf_min_error_messages_t hdf_min_error_messages[] =
{H5E_ALIGNMENT, "Alignment error"},
{H5E_BADMESG, "Unrecognized message"},
{H5E_COMPLEN, "Name component is too long"},
+ {H5E_CWG, "Problem with current working group"},
{H5E_LINK, "Link count failure"},
};
diff --git a/src/H5Epublic.h b/src/H5Epublic.h
index bde74e5..abb6e3c 100644
--- a/src/H5Epublic.h
+++ b/src/H5Epublic.h
@@ -38,10 +38,10 @@ typedef enum
H5E_SYM, /* Symbol Table */
H5E_HEAP, /* Heap */
H5E_OHDR, /* Object Header */
- H5E_DIRECTORY, /* Directory */
H5E_DATATYPE, /* Datatype */
- H5E_DATASPACE, /* Dataspace */
- H5E_DATASET /* Dataset */
+ H5E_DATASPACE, /* Dataspace */
+ H5E_DATASET, /* Dataset */
+ H5E_STORAGE /* Data storage */
}
hdf_maj_err_code_t;
@@ -102,9 +102,10 @@ typedef enum
H5E_ALIGNMENT, /* Alignment error */
H5E_BADMESG, /* Unrecognized message */
- /* Directory related errors */
+ /* Group related errors */
H5E_CANTOPENOBJ, /* Can't open object */
H5E_COMPLEN, /* Name component is too long */
+ H5E_CWG, /* Problem with current working group */
H5E_LINK /* Link count failure */
}
hdf_min_err_code_t;
diff --git a/src/H5F.c b/src/H5F.c
index 6cba7d0..dbfeeb6 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -69,7 +69,6 @@ static herr_t H5F_init_interface(void);
static H5F_t *H5F_new (H5F_file_t *shared);
static H5F_t *H5F_dest (H5F_t *f);
static herr_t H5F_flush (H5F_t *f, hbool_t invalidate);
-static herr_t H5F_close (H5F_t *f);
/*--------------------------------------------------------------------------
NAME
@@ -500,7 +499,7 @@ H5F_dest (H5F_t *f)
* block is written. This operation will fail
* if the file is already open.
*
- * Unlinking the file name from the directory hierarchy while
+ * Unlinking the file name from the group directed graph while
* the file is opened causes the file to continue to exist but
* one will not be able to upgrade the file from read-only
* access to read-write access by reopening it. Disk resources
@@ -508,13 +507,20 @@ H5F_dest (H5F_t *f)
* closed. NOTE: This paragraph probably only applies to Unix;
* deleting the file name in other OS's has undefined results.
*
+ * The CREATE_PARMS argument is optional. A null pointer will
+ * cause the default file creation parameters to be used.
+ *
* Errors:
+ * ATOM BADATOM Can't unatomize default template
+ * id.
* FILE BADVALUE Can't create file without write
* intent.
* FILE BADVALUE Can't truncate without write intent.
* FILE CANTCREATE Can't create file.
* FILE CANTCREATE Can't stat file.
* FILE CANTCREATE Can't truncate file.
+ * FILE CANTINIT Can't get default file create template
+ * id.
* FILE CANTINIT Can't write file boot block.
* FILE CANTINIT Cannot determine file size.
* FILE CANTOPENFILE Bad boot block version number.
@@ -550,7 +556,7 @@ H5F_dest (H5F_t *f)
*
*-------------------------------------------------------------------------
*/
-static H5F_t *
+H5F_t *
H5F_open (const char *name, uintn flags,
const file_create_temp_t *create_parms)
{
@@ -573,6 +579,21 @@ H5F_open (const char *name, uintn flags,
assert (name && *name);
/*
+ * If no file creation parameters are supplied then use defaults.
+ */
+ if (!create_parms) {
+ hid_t create_temp = H5C_get_default_atom (H5_TEMPLATE);
+ if (create_temp<0) {
+ /* Can't get default file create template id */
+ HRETURN_ERROR (H5E_FILE, H5E_CANTINIT, NULL);
+ }
+ if (NULL==(create_parms=H5Aatom_object (create_temp))) {
+ /* Can't unatomize default template id */
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL);
+ }
+ }
+
+ /*
* Does the file exist? If so, get the device and i-node values so we can
* compare them with other files already open. On Unix (and other systems
* with hard or soft links) it doesn't work to compare files based only on
@@ -984,11 +1005,6 @@ hid_t H5Fcreate(const char *filename, uintn flags, hid_t create_temp,
hid_t H5Fopen(const char *filename, uintn flags, hid_t access_temp)
{
H5F_t *new_file=NULL; /* file struct for new file */
- hid_t create_temp; /* file-creation template ID */
- const file_create_temp_t *f_create_parms; /* pointer to the parameters
- * to use when creating the
- * file
- */
hid_t ret_value = FAIL;
FUNC_ENTER(H5Fopen, H5F_init_interface, FAIL);
@@ -999,10 +1015,6 @@ hid_t H5Fopen(const char *filename, uintn flags, hid_t access_temp)
HGOTO_ERROR (H5E_ARGS, H5E_BADRANGE, FAIL);/*invalid file name*/
flags = flags & H5ACC_WRITE ? H5F_ACC_WRITE : 0;
- create_temp = H5C_get_default_atom (H5_TEMPLATE);
- if (NULL==(f_create_parms=H5Aatom_object(create_temp)))
- HGOTO_ERROR (H5E_ATOM, H5E_BADATOM, FAIL);/*can't unatomize template*/
-
#ifdef LATER
if (access_temp<=0)
access_temp = H5CPget_default_atom (H5_TEMPLATE);
@@ -1011,7 +1023,7 @@ hid_t H5Fopen(const char *filename, uintn flags, hid_t access_temp)
#endif
/* Open the file */
- if (NULL==(new_file=H5F_open (filename, flags, f_create_parms))) {
+ if (NULL==(new_file=H5F_open (filename, flags, NULL))) {
HGOTO_ERROR (H5E_FILE, H5E_CANTOPENFILE, FAIL); /*cant open file*/
}
@@ -1188,7 +1200,7 @@ H5Fflush (hid_t fid, hbool_t invalidate)
*
*-------------------------------------------------------------------------
*/
-static herr_t
+herr_t
H5F_close (H5F_t *f)
{
herr_t ret_value = FAIL;
diff --git a/src/H5Fistore.c b/src/H5Fistore.c
new file mode 100644
index 0000000..b52288c
--- /dev/null
+++ b/src/H5Fistore.c
@@ -0,0 +1,740 @@
+/*
+ * Copyright (C) 1997 Spizella Software
+ * All rights reserved.
+ *
+ * Programmer: Robb Matzke <robb@arborea.spizella.com>
+ * Wednesday, October 8, 1997
+ */
+#include <H5private.h>
+#include <H5Eprivate.h>
+#include <H5Fprivate.h>
+#include <H5MFprivate.h>
+#include <H5MMprivate.h>
+#include <H5Oprivate.h>
+#include <H5Vprivate.h>
+
+typedef enum H5F_isop_t {
+ H5F_ISTORE_READ, /*read from file to memory */
+ H5F_ISTORE_WRITE /*write from memory to file */
+} H5F_isop_t;
+
+/* Does the array domain include negative indices? */
+#undef H5F_ISTORE_NEGATIVE_DOMAIN
+
+
+#define PABLO_MASK H5F_istore_mask
+
+/* Is the interface initialized? */
+static hbool_t interface_initialize_g = FALSE;
+
+/* PRIVATE PROTOTYPES */
+static size_t H5F_istore_sizeof_rkey (H5F_t *f, const void *_udata);
+static haddr_t H5F_istore_new (H5F_t *f, void *_lt_key, void *_udata,
+ void *_rt_key);
+static intn H5F_istore_cmp (H5F_t *f, void *_lt_key, void *_udata,
+ void *_rt_key);
+static herr_t H5F_istore_found (H5F_t *f, haddr_t addr, const void *_lt_key,
+ void *_udata, const void *_rt_key);
+static haddr_t H5F_istore_insert (H5F_t *f, haddr_t addr, H5B_ins_t *anchor,
+ void *_lt_key, hbool_t *lt_key_changed,
+ void *_md_key, void *_udata,
+ void *_rt_key, hbool_t *rt_key_changed);
+static herr_t H5F_istore_decode_key (H5F_t *f, H5B_t *bt, uint8 *raw,
+ void *_key);
+static herr_t H5F_istore_encode_key (H5F_t *f, H5B_t *bt, uint8 *raw,
+ void *_key);
+static herr_t H5F_istore_copy_hyperslab (H5F_t *f, H5O_istore_t *istore,
+ H5F_isop_t op, size_t offset_f[],
+ size_t size[], size_t offset_m[],
+ size_t size_m[], void *buf);
+
+
+/*
+ * B-tree key. A key contains the minimum logical N-dimensional address and
+ * the logical size of the chunk to which this key refers. The
+ * fastest-varying dimension is assumed to reference individual bytes of the
+ * array, so a 100-element 1-d array of 4-byte integers would really be a 2-d
+ * array with the slow varying dimension of size 100 and the fast varying
+ * dimension of size 4 (the storage dimensionality has very little to do with
+ * the real dimensionality).
+ *
+ * Only the first few values of the OFFSET and SIZE fields are actually
+ * stored on disk, depending on the dimensionality.
+ *
+ * The storage file address is part of the B-tree and not part of the key.
+ */
+typedef struct H5F_istore_key_t {
+ size_t offset[H5O_ISTORE_NDIMS]; /*logical offset to start*/
+ size_t size[H5O_ISTORE_NDIMS]; /*logical chunk size */
+} H5F_istore_key_t;
+
+typedef struct H5F_istore_ud1_t {
+ H5F_istore_key_t key; /*key values */
+ haddr_t addr; /*file address of chunk */
+ H5O_istore_t mesg; /*storage message */
+} H5F_istore_ud1_t;
+
+/* inherits B-tree like properties from H5B */
+H5B_class_t H5B_ISTORE[1] = {{
+ H5B_ISTORE_ID, /*id */
+ sizeof (H5F_istore_key_t), /*sizeof_nkey */
+ H5F_istore_sizeof_rkey, /*get_sizeof_rkey */
+ H5F_istore_new, /*new */
+ H5F_istore_cmp, /*cmp */
+ H5F_istore_found, /*found */
+ H5F_istore_insert, /*insert */
+ FALSE, /*follow min branch? */
+ FALSE, /*follow max branch? */
+ NULL, /*list */
+ H5F_istore_decode_key, /*decode */
+ H5F_istore_encode_key, /*encode */
+}};
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_sizeof_rkey
+ *
+ * Purpose: Returns the size of a raw key for the specified UDATA. The
+ * size of the key is dependent on the number of dimensions for
+ * the object to which this B-tree points. The dimensionality
+ * of the UDATA is the only portion that's referenced here.
+ *
+ * Return: Success: Size of raw key in bytes.
+ *
+ * Failure: abort()
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, October 8, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static size_t
+H5F_istore_sizeof_rkey (H5F_t *f, const void *_udata)
+{
+ const H5F_istore_ud1_t *udata = (const H5F_istore_ud1_t *)_udata;
+
+ assert (udata);
+ assert (udata->mesg.ndims>0 && udata->mesg.ndims<=H5O_ISTORE_NDIMS);
+
+ return udata->mesg.ndims * (4 + 4);
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_decode_key
+ *
+ * Purpose: Decodes a raw key into a native key for the B-tree
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Friday, October 10, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_istore_decode_key (H5F_t *f, H5B_t *bt, uint8 *raw, void *_key)
+{
+ H5F_istore_key_t *key = (H5F_istore_key_t *)_key;
+ int i;
+ int ndims = bt->sizeof_rkey / 8;
+
+ FUNC_ENTER (H5F_istore_decode_key, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (bt);
+ assert (raw);
+ assert (key);
+ assert (ndims>0 && ndims<=H5O_ISTORE_NDIMS && 8*ndims==bt->sizeof_rkey);
+
+ /* decode */
+ for (i=0; i<ndims; i++) {
+ UINT32DECODE (raw, key->offset[i]);
+ UINT32DECODE (raw, key->size[i]);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_encode_key
+ *
+ * Purpose: Encode a key from native format to raw format.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Friday, October 10, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_istore_encode_key (H5F_t *f, H5B_t *bt, uint8 *raw, void *_key)
+{
+ H5F_istore_key_t *key = (H5F_istore_key_t *)_key;
+ intn ndims = bt->sizeof_rkey / 8;
+ intn i;
+
+ FUNC_ENTER (H5F_istore_encode_key, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (bt);
+ assert (raw);
+ assert (key);
+ assert (ndims>0 && ndims<=H5O_ISTORE_NDIMS && 8*ndims==bt->sizeof_rkey);
+
+ /* encode */
+ for (i=0; i<ndims; i++) {
+ UINT32ENCODE (raw, key->offset[i]);
+ UINT32ENCODE (raw, key->size[i]);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_cmp
+ *
+ * Purpose: Compare the requested datum UDATA with the left and right
+ * keys of the B-tree.
+ *
+ * Return: Success: negative if the min_corner of UDATA is less
+ * than the min_corner of LT_KEY.
+ *
+ * positive if the min_corner of UDATA is
+ * greater than or equal the min_corner of
+ * RT_KEY.
+ *
+ * zero otherwise. The min_corner of UDATA is
+ * not necessarily contained within the address
+ * space represented by LT_KEY, but a key that
+ * would describe the UDATA min_corner address
+ * would fall lexicographically between LT_KEY
+ * and RT_KEY.
+ *
+ * Failure: FAIL (same as UDATA < LT_KEY)
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, October 8, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static intn
+H5F_istore_cmp (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
+{
+ H5F_istore_key_t *lt_key = (H5F_istore_key_t *)_lt_key;
+ H5F_istore_key_t *rt_key = (H5F_istore_key_t *)_rt_key;
+ H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *)_udata;
+
+ assert (lt_key);
+ assert (rt_key);
+ assert (udata);
+ assert (udata->mesg.ndims>0 && udata->mesg.ndims<=H5O_ISTORE_NDIMS);
+
+ if (H5V_vector_lt (udata->mesg.ndims, udata->key.offset, lt_key->offset)) {
+ return -1;
+ } else if (H5V_vector_ge (udata->mesg.ndims, udata->key.offset,
+ rt_key->offset)) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_new
+ *
+ * Purpose: Adds a new entry to an i-storage B-tree. We can assume that
+ * the domain represented by UDATA doesn't intersect the domain
+ * already represented by the B-tree.
+ *
+ * Return: Success: Address of leaf, which is passed in from the
+ * UDATA pointer.
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, October 14, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static haddr_t
+H5F_istore_new (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
+{
+ H5F_istore_key_t *lt_key = (H5F_istore_key_t *)_lt_key;
+ H5F_istore_key_t *rt_key = (H5F_istore_key_t *)_rt_key;
+ H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *)_udata;
+ size_t nbytes;
+ intn i;
+
+ FUNC_ENTER (H5F_istore_new, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (lt_key);
+ assert (rt_key);
+ assert (udata);
+ assert (udata->mesg.ndims>=0 && udata->mesg.ndims<H5O_ISTORE_NDIMS);
+
+ /* Allocate new storage */
+ nbytes = H5V_vector_reduce_product (udata->mesg.ndims, udata->key.size);
+ assert (nbytes>0);
+ if ((udata->addr=H5MF_alloc (f, nbytes))<0) {
+ /* Couldn't allocate new file storage */
+ HRETURN_ERROR (H5E_IO, H5E_CANTINIT, FAIL);
+ }
+
+ /* left key describes the UDATA, right key is a zero-size "edge" */
+ for (i=0; i<udata->mesg.ndims; i++) {
+ lt_key->offset[i] = udata->key.offset[i];
+ lt_key->size[i] = udata->key.size[i];
+ assert (udata->key.size[i]>0);
+
+ rt_key->offset[i] = udata->key.offset[i] + udata->key.size[i];
+ rt_key->size[i] = 0;
+ }
+
+
+ FUNC_LEAVE (udata->addr);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_found
+ *
+ * Purpose: This function is called when the B-tree search engine has
+ * found the leaf entry that points to a chunk of storage that
+ * contains the beginning of the logical address space
+ * represented by UDATA. The LT_KEY is the left key (the one
+ * that describes the chunk) and RT_KEY is the right key (the
+ * one that describes the next or last chunk).
+ *
+ * Return: Success: SUCCEED with information about the chunk
+ * returned through the UDATA argument.
+ *
+ * Failure: FAIL if not found.
+ *
+ * Programmer: Robb Matzke
+ * Thursday, October 9, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_istore_found (H5F_t *f, haddr_t addr, const void *_lt_key,
+ void *_udata, const void *_rt_key)
+{
+ H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *)_udata;
+ const H5F_istore_key_t *lt_key = (const H5F_istore_key_t *)_lt_key;
+ const H5F_istore_key_t *rt_key = (const H5F_istore_key_t *)_rt_key;
+ int i;
+
+ FUNC_ENTER (H5F_istore_found, NULL, FAIL);
+
+ /* Check arguments */
+ assert (f);
+ assert (addr>=0);
+ assert (udata);
+ assert (lt_key);
+ assert (rt_key);
+
+ /* Initialize return values */
+ udata->addr = addr;
+ for (i=0; i<udata->mesg.ndims; i++) {
+ udata->key.offset[i] = lt_key->offset[i];
+ udata->key.size[i] = lt_key->size[i];
+ assert (lt_key->size[i]>0);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_insert
+ *
+ * Purpose: This function is called when the B-tree insert engine finds
+ * the node to use to insert new data. The UDATA argument
+ * points to a struct that describes the logical addresses being
+ * added to the file. This function allocates space for the
+ * data and returns information through UDATA describing a
+ * file chunk to receive (part of) the data.
+ *
+ * The LT_KEY is always the key describing the chunk of file
+ * memory at address ADDR. On entry, UDATA describes the logical
+ * addresses for which storage is being requested (through the
+ * `offset' and `size' fields). On return, UDATA describes the
+ * logical addresses contained in a chunk on disk.
+ *
+ * Return: Success: SUCCEED, with UDATA containing information
+ * about the (newly allocated) chunk.
+ *
+ * If the storage address has changed then the
+ * new address is returned.
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Thursday, October 9, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static haddr_t
+H5F_istore_insert (H5F_t *f, haddr_t addr, H5B_ins_t *parent_ins,
+ void *_lt_key, hbool_t *lt_key_changed,
+ void *_md_key, void *_udata,
+ void *_rt_key, hbool_t *rt_key_changed)
+{
+ H5F_istore_key_t *lt_key = (H5F_istore_key_t *)_lt_key;
+ H5F_istore_key_t *md_key = (H5F_istore_key_t *)_md_key;
+ H5F_istore_key_t *rt_key = (H5F_istore_key_t *)_rt_key;
+ H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *)_udata;
+ intn i, cmp;
+ haddr_t ret_value = 0;
+ size_t nbytes;
+
+ FUNC_ENTER (H5F_istore_insert, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (addr>=0);
+ assert (parent_ins);
+ assert (lt_key);
+ assert (lt_key_changed);
+ assert (md_key);
+ assert (udata);
+ assert (rt_key);
+ assert (rt_key_changed);
+
+ cmp = H5F_istore_cmp (f, lt_key, udata, rt_key);
+ assert (cmp<=0);
+
+ if (cmp<0) {
+ /* Negative indices not supported yet */
+ assert ("HDF5 INTERNAL ERROR -- see rpm" && 0);
+ HRETURN_ERROR (H5E_STORAGE, H5E_UNSUPPORTED, FAIL);
+
+ } else if (H5V_hyper_eq (udata->mesg.ndims,
+ udata->key.offset, udata->key.size,
+ lt_key->offset, lt_key->size)) {
+ /*
+ * Already exists. Just return the info.
+ */
+ udata->addr = addr;
+ *parent_ins = H5B_INS_NOOP;
+
+ } else if (H5V_hyper_disjointp (udata->mesg.ndims,
+ lt_key->offset, lt_key->size,
+ udata->key.offset, udata->key.size)) {
+ assert (H5V_hyper_disjointp (udata->mesg.ndims,
+ rt_key->offset, rt_key->size,
+ udata->key.offset, udata->key.size));
+
+ /*
+ * Split this node, inserting the new new node to the right of the
+ * current node. The MD_KEY is where the split occurs.
+ */
+ for (i=0, nbytes=1; i<udata->mesg.ndims; i++) {
+ assert (0==udata->key.offset[i] % udata->mesg.alignment[i]);
+ assert (udata->key.size[i] == udata->mesg.alignment[i]);
+ md_key->offset[i] = udata->key.offset[i];
+ md_key->size[i] = udata->key.size[i];
+ nbytes *= udata->key.size[i];
+ }
+
+ /*
+ * Allocate storage for the new chunk
+ */
+ if ((udata->addr=ret_value=H5MF_alloc (f, nbytes))<=0) {
+ HRETURN_ERROR (H5E_IO, H5E_CANTINIT, FAIL);
+ }
+
+ *parent_ins = H5B_INS_RIGHT;
+
+ } else {
+ assert ("HDF5 INTERNAL ERROR -- see rpm" && 0);
+ HRETURN_ERROR (H5E_IO, H5E_UNSUPPORTED, FAIL);
+ }
+
+ FUNC_LEAVE (ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_copy_hyperslab
+ *
+ * Purpose: Reads or writes a hyperslab to disk depending on whether OP
+ * is H5F_ISTORE_READ or H5F_ISTORE_WRITE. The hyperslab
+ * storage is described with ISTORE and exists in file F. The
+ * file hyperslab begins at location OFFSET_F[] (an N-dimensional
+ * point in the domain in terms of elements) in the file and
+ * OFFSET_M[] in memory pointed to by BUF. Its size is SIZE[]
+ * elements. The dimensionality of memory is assumed to be the
+ * same as the file and the total size of the multi-dimensional
+ * memory buffer is SIZE_M[].
+ *
+ * The slowest varying dimension is always listed first in the
+ * various offset and size arrays.
+ *
+ * A `chunk' is a hyperslab of the disk array which is stored
+ * contiguously. I/O occurs in units of chunks where the size of
+ * a chunk is determined by the alignment constraints specified
+ * in ISTORE.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Friday, October 17, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_istore_copy_hyperslab (H5F_t *f, H5O_istore_t *istore, H5F_isop_t op,
+ size_t offset_f[], size_t size[],
+ size_t offset_m[], size_t size_m[], void *buf)
+{
+ intn i, carry;
+ size_t idx_cur[H5O_ISTORE_NDIMS];
+ size_t idx_min[H5O_ISTORE_NDIMS];
+ size_t idx_max[H5O_ISTORE_NDIMS];
+ size_t sub_size[H5O_ISTORE_NDIMS];
+ size_t sub_offset_f[H5O_ISTORE_NDIMS];
+ size_t sub_offset_m[H5O_ISTORE_NDIMS];
+ size_t sub_offset_ch[H5O_ISTORE_NDIMS];
+ size_t chunk_size;
+ uint8 *chunk=NULL;
+ H5F_istore_ud1_t udata;
+ herr_t status;
+ herr_t ret_value = FAIL;
+
+ FUNC_ENTER (H5F_istore_copy_hyperslab, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (istore);
+ assert (istore->ndims>0 && istore->ndims<=H5O_ISTORE_NDIMS);
+ assert (H5F_ISTORE_READ==op || H5F_ISTORE_WRITE==op);
+ assert (size);
+ assert (size_m);
+ assert (buf);
+#ifndef NDEBUG
+ for (i=0; i<istore->ndims; i++) {
+ assert (!offset_f || offset_f[i]>=0);/*neg domains unsupported */
+ assert (!offset_m || offset_m[i]>=0);/*mem array offset never neg */
+ assert (size[i]>=0); /*size may be zero, implies no-op */
+ assert (size_m[i]>0); /*destination must exist */
+ /*hyperslab must fit in BUF*/
+ assert ((offset_m?offset_m[i]:0)+size[i]<=size_m[i]);
+ assert (istore->alignment[i]>0);
+ }
+#endif
+
+ /*
+ * Does the B-tree exist?
+ */
+ if (istore->btree_addr<=0) {
+ if (H5F_ISTORE_WRITE==op) {
+ udata.mesg.ndims = istore->ndims;
+ if ((istore->btree_addr=H5B_new (f, H5B_ISTORE, &udata))<0) {
+ /* Can't create B-tree */
+ HGOTO_ERROR (H5E_IO, H5E_CANTINIT, FAIL);
+ }
+ } else {
+ H5V_hyper_fill (istore->ndims, size, size_m, offset_m, buf, 0);
+ HRETURN (SUCCEED);
+ }
+ }
+
+ /* Initialize indices */
+ for (i=0; i<istore->ndims; i++) {
+ idx_min[i] = (offset_f?offset_f[i]:0) / istore->alignment[i];
+ idx_max[i] = ((offset_f?offset_f[i]:0)+size[i]-1)/istore->alignment[i]+1;
+ idx_cur[i] = idx_min[i];
+ }
+
+ /* Allocate buffers */
+ for (i=0, chunk_size=1; i<istore->ndims; i++) {
+ chunk_size *= istore->alignment[i];
+ }
+ chunk = H5MM_xmalloc (chunk_size);
+
+ /* Initialize non-changing part of udata */
+ udata.mesg = *istore;
+
+ /* Loop over all chunks */
+ while (1) {
+
+ /* Read/Write chunk or create it if it doesn't exist */
+ udata.mesg.ndims = istore->ndims;
+ for (i=0; i<istore->ndims; i++) {
+ udata.key.offset[i] = idx_cur[i] * istore->alignment[i];
+ udata.key.size[i] = istore->alignment[i];
+ sub_offset_f[i] = MAX ((offset_f?offset_f[i]:0), udata.key.offset[i]);
+ sub_offset_m[i] = (offset_m?offset_m[i]:0) +
+ sub_offset_f[i] - (offset_f?offset_f[i]:0);
+ sub_size[i] = (idx_cur[i]+1)*istore->alignment[i]-sub_offset_f[i];
+ sub_offset_ch[i] = sub_offset_f[i] - udata.key.offset[i];
+ }
+ if (H5F_ISTORE_WRITE==op) {
+ status = H5B_insert (f, H5B_ISTORE, istore->btree_addr, &udata);
+ assert (status>=0);
+ } else {
+ status = H5B_find (f, H5B_ISTORE, istore->btree_addr, &udata);
+ }
+
+ /*
+ * If the operation is reading from the disk or if we are writing a
+ * partial chunk then load the chunk from disk.
+ */
+ if (H5F_ISTORE_READ==op ||
+ !H5V_hyper_eq (istore->ndims,
+ udata.key.offset, udata.key.size,
+ sub_offset_f, sub_size)) {
+ if (status>=0) {
+ if (H5F_block_read (f, udata.addr, chunk_size, chunk)<0) {
+ HGOTO_ERROR (H5E_IO, H5E_READERROR, FAIL);
+ }
+ } else {
+ HDmemset (chunk, 0, chunk_size);
+ }
+ }
+
+ /* Transfer data to/from the chunk */
+ if (H5F_ISTORE_WRITE==op) {
+ H5V_hyper_copy (istore->ndims, sub_size,
+ udata.key.size, sub_offset_ch, chunk,
+ size_m, sub_offset_m, buf);
+ if (H5F_block_write (f, udata.addr, chunk_size, chunk)<0) {
+ HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL);
+ }
+ } else {
+ H5V_hyper_copy (istore->ndims, sub_size,
+ size_m, sub_offset_m, buf,
+ udata.key.size, sub_offset_ch, chunk);
+ }
+
+ /* Increment indices */
+ for (i=istore->ndims-1, carry=1; i>=0 && carry; --i) {
+ if (++idx_cur[i]>=idx_max[i]) idx_cur[i] = idx_min[i];
+ else carry = 0;
+ }
+ if (carry) break;
+ }
+ ret_value = SUCCEED;
+
+
+ done:
+ chunk = H5MM_xfree (chunk);
+ FUNC_LEAVE (ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_read
+ *
+ * Purpose: Reads a multi-dimensional buffer from (part of) an indexed raw
+ * storage array.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, October 15, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_istore_read (H5F_t *f, struct H5O_istore_t *istore,
+ size_t offset[], size_t size[], void *buf)
+{
+ FUNC_ENTER (H5F_istore_read, NULL, FAIL);
+
+ /* Check args */
+ assert (f);
+ assert (istore);
+ assert (istore->ndims>0 && istore->ndims<=H5O_ISTORE_NDIMS);
+ assert (size);
+ assert (buf);
+
+ if (H5F_istore_copy_hyperslab (f, istore, H5F_ISTORE_READ,
+ offset, size, H5V_ZERO, size, buf)<0) {
+ /* hyperslab output failure */
+ HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_write
+ *
+ * Purpose: Writes a multi-dimensional buffer to (part of) an indexed raw
+ * storage array.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, October 15, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_istore_write (H5F_t *f, struct H5O_istore_t *istore,
+ size_t offset[], size_t size[], void *buf)
+{
+ FUNC_ENTER (H5F_istore_write, NULL, FAIL);
+
+ /* Check args */
+ assert (f);
+ assert (istore);
+ assert (istore->ndims>0 && istore->ndims<=H5O_ISTORE_NDIMS);
+ assert (size);
+ assert (buf);
+
+ if (H5F_istore_copy_hyperslab (f, istore, H5F_ISTORE_WRITE,
+ offset, size, H5V_ZERO, size, buf)<0) {
+ /* hyperslab output failure */
+ HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index 81f43ce..0d0a65c 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -20,7 +20,7 @@
#define _H5Fprivate_H
#include <H5Fpublic.h>
-/* Private headers needed by this file */
+/* This is a near top-level header! Try not to include much! */
#include <H5private.h>
/* Maximum size of boot-block buffer */
@@ -397,6 +397,7 @@ typedef struct H5F_t {
uintn intent; /* The flags passed to H5F_open() */
char *name; /* Name used to open file */
H5F_file_t *shared; /* The shared file info */
+ struct H5G_cwgstk_t *cwg_stack; /* CWG stack for push/pop functions */
} H5F_t;
@@ -446,12 +447,20 @@ typedef struct H5F_t {
case 2: UINT16DECODE(p,l); break; \
}
+struct H5O_istore_t; /*forward decl for prototype arguments*/
/* Private functions, not part of the publicly documented API */
void H5F_encode_length_unusual(const H5F_t *f, uint8 **p, uint8 *l);
void H5F_encode_offset_unusual(const H5F_t *f, uint8 **p, uint8 *o);
+H5F_t *H5F_open (const char *name, uintn flags,
+ const file_create_temp_t *create_parms);
+herr_t H5F_close (H5F_t *f);
herr_t H5F_block_read (H5F_t *f, haddr_t addr, size_t size, void *buf);
herr_t H5F_block_write (H5F_t *f, haddr_t addr, size_t size, void *buf);
+herr_t H5F_istore_read (H5F_t *f, struct H5O_istore_t *mesg,
+ size_t offset[], size_t size[], void *buf);
+herr_t H5F_istore_write (H5F_t *f, struct H5O_istore_t *mesg,
+ size_t offset[], size_t size[], void *buf);
herr_t H5F_debug (H5F_t *f, haddr_t addr, FILE *stream, intn indent,
intn fwidth);
diff --git a/src/H5G.c b/src/H5G.c
index efb7389..c251b14 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -10,15 +10,15 @@
*
* Purpose: Symbol table functions. The functions that
* begin with `H5G_stab_' don't understand the
- * directory hierarchy; they operate on a single
+ * naming system; they operate on a single
* symbol table at a time.
*
* The functions that begin with `H5G_node_' operate
* on the leaf nodes of a symbol table B-tree. They
* should be defined in the H5Gnode.c file.
*
- * The remaining functions know about the directory
- * hierarchy.
+ * The remaining functions know how to traverse the
+ * group directed graph
*
* Modifications:
*
@@ -53,6 +53,266 @@ static hbool_t interface_initialize_g = FALSE;
/*-------------------------------------------------------------------------
+ * Function: H5Gnew
+ *
+ * Purpose: Creates a new group in FILE and gives it the specified
+ * NAME. Unless NAME begins with `/' it is relative to the
+ * current working group.
+ *
+ * The optional SIZE_HINT specifies how much file space to
+ * reserve to store the names that will appear in this
+ * group (an even number of characters, counting the null
+ * terminator, is allocated for each name). If a non-positive
+ * value is supplied for the SIZE_HINT then a default size is
+ * chosen.
+ *
+ * See also: H5Gset(), H5Gpush(), H5Gpop()
+ *
+ * Errors:
+ * ARGS BADTYPE Not a file atom.
+ * ARGS BADVALUE No name given.
+ * ATOM BADATOM Can't unatomize file.
+ * SYM CANTINIT Can't close handle.
+ * SYM CANTINIT Can't create group.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, September 24, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Gnew (hid_t file, const char *name, size_t size_hint)
+{
+ H5F_t *f=NULL;
+ H5G_entry_t *grp_handle=NULL;
+
+ FUNC_ENTER (H5Gnew, NULL, FAIL);
+
+ /* Check/fix arguments */
+ if (!name || !*name) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL);/*no name given*/
+ }
+ if (H5_FILE!=H5Aatom_group (file)) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL);/*not a file atom*/
+ }
+ if (NULL==(f=H5Aatom_object (file))) {
+ HRETURN_ERROR (H5E_ATOM, H5E_BADATOM, FAIL);/*can't unatomize file*/
+ }
+
+ /* Create the group */
+ if (NULL==(grp_handle=H5G_new (f, name, size_hint))) {
+ /*can't create group*/
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
+ }
+
+ /* Close the group handle */
+ if (H5G_close (f, grp_handle)<0) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);/*can't close handle*/
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Gset
+ *
+ * Purpose: Sets the working group for file handle FILE to the
+ * specified NAME. Unless NAME begins with a `/' it is
+ * interpretted relative to the current working group.
+ *
+ * Each file handle maintains its own notion of the current
+ * working group. That is, if a single file is opened with
+ * multiple calls to H5Fopen(), which returns multiple file
+ * handles, then each handle's current working group can be
+ * set independently of the other file handles for that file.
+ *
+ * See also: H5Gpush(), H5Gpop()
+ *
+ * Errors:
+ * ARGS BADTYPE Not a file atom.
+ * ARGS BADVALUE No name given.
+ * ATOM BADATOM Can't unatomize file.
+ * SYM CANTINIT Can't change current working group.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, September 24, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Gset (hid_t file, const char *name)
+{
+ H5F_t *f=NULL;
+
+ FUNC_ENTER (H5Gset, NULL, FAIL);
+
+ /* Check/fix arguments */
+ if (!name || !*name) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL);/*no name given*/
+ }
+ if (H5_FILE!=H5Aatom_group (file)) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL);/*not a file atom*/
+ }
+ if (NULL==(f=H5Aatom_object (file))) {
+ HRETURN_ERROR (H5E_ATOM, H5E_BADATOM, FAIL);/*can't unatomize file*/
+ }
+
+ if (H5G_set (f, name)<0) {
+ /* Can't change current working group */
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Gpush
+ *
+ * Purpose: Similar to H5Gset() except the new working group is pushed
+ * on a stack.
+ *
+ * Each file handle maintains its own notion of the current
+ * working group. That is, if a single file is opened with
+ * multiple calls to H5Fopen(), which returns multiple file
+ * handles, then each handle's current working group can be
+ * set independently of the other file handles for that file.
+ *
+ * See also: H5Gset(), H5Gpop()
+ *
+ * Errors:
+ * ARGS BADTYPE Not a file atom.
+ * ARGS BADVALUE No name given.
+ * ATOM BADATOM Can't unatomize file.
+ * SYM CANTINIT Can't change current working group.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, September 24, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Gpush (hid_t file, const char *name)
+{
+ H5F_t *f=NULL;
+
+ FUNC_ENTER (H5Gpush, NULL, FAIL);
+
+ /* Check/fix arguments */
+ if (!name || !*name) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL);/*no name given*/
+ }
+ if (H5_FILE!=H5Aatom_group (file)) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL);/*not a file atom*/
+ }
+ if (NULL==(f=H5Aatom_object (file))) {
+ HRETURN_ERROR (H5E_ATOM, H5E_BADATOM, FAIL);/*can't unatomize file*/
+ }
+
+ if (H5G_push (f, name)<0) {
+ /* Can't change current working group */
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Gpop
+ *
+ * Purpose: Removes the top (latest) entry from the working group stack
+ * and sets the current working group to the previous value.
+ *
+ * Each file handle maintains its own notion of the current
+ * working group. That is, if a single file is opened with
+ * multiple calls to H5Fopen(), which returns multiple file
+ * handles, then each handle's current working group can be
+ * set independently of the other file handles for that file.
+ *
+ * See also: H5Gset(), H5Gpush()
+ *
+ * Errors:
+ * ARGS BADTYPE Not a file atom.
+ * ATOM BADATOM Can't unatomize file.
+ * SYM CANTINIT Stack is empty.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL. The final entry cannot be popped from
+ * the group stack (but it can be changed
+ * with H5Gset()).
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, September 24, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Gpop (hid_t file)
+{
+ H5F_t *f=NULL;
+
+ FUNC_ENTER (H5Gpop, NULL, FAIL);
+
+ /* Check/fix arguments */
+ if (H5_FILE!=H5Aatom_group (file)) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL);/*not a file atom*/
+ }
+ if (NULL==(f=H5Aatom_object (file))) {
+ HRETURN_ERROR (H5E_ATOM, H5E_BADATOM, FAIL);/*can't unatomize file*/
+ }
+
+ if (H5G_pop (f)<0) {
+ /* Stack is empty */
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+
+
+/*
+ *-------------------------------------------------------------------------
+ *-------------------------------------------------------------------------
+ * N O A P I F U N C T I O N S B E Y O N D T H I S P O I N T
+ *-------------------------------------------------------------------------
+ *-------------------------------------------------------------------------
+ */
+
+
+
+
+
+
+
+/*-------------------------------------------------------------------------
* Function: H5G_component
*
* Purpose: Returns the pointer to the first component of the
@@ -67,7 +327,7 @@ static hbool_t interface_initialize_g = FALSE;
* Failure: Ptr to the null terminator of NAME.
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 11 1997
*
* Modifications:
@@ -102,7 +362,7 @@ H5G_component (const char *name, size_t *size_p)
* Failure: Ptr to the null terminator of NAME.
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 11 1997
*
* Modifications:
@@ -122,7 +382,7 @@ H5G_basename (const char *name, size_t *size_p)
while (s>name && '/'!=s[-1]) --s; /*skip past base name*/
/*
- * If the input was the name of the root directory `/' (or
+ * If the input was the name of the root group `/' (or
* equivalent) then return the null string.
*/
if ('/'==*s) {
@@ -142,42 +402,43 @@ H5G_basename (const char *name, size_t *size_p)
* Purpose: (Partially) translates a name to a symbol table entry.
*
* Given a name (absolute or relative) return the symbol table
- * entry for that name and for the directory that contains the
- * base name. These entries (DIR_ENT and BASE_ENT) are returned
+ * entry for that name and for the group that contains the
+ * base name. These entries (GRP_ENT and BASE_ENT) are returned
* through memory passed into the function by the caller. Either
* or both pointers may be null. Absolute names are looked up
- * relative to the root directory of file F while relative
- * names are traversed beginning at the CWD argument.
+ * relative to the root group of file F while relative
+ * names are traversed beginning at the CWG argument.
*
* Consecutive slash characters are treated like single
* slash characters. Trailing slashes are ignored. The
- * component `.' is recognized as the current directory
- * during the traversal (initially CWD), but the component
+ * component `.' is recognized as the current group
+ * during the traversal (initially CWG), but the component
* `..' is not internally recognized (it is recognized if
* such a name appears in the symbol table).
*
* If the name cannot be fully resolved, then REST will
* point to the part of NAME where the traversal failed
* (REST will always point to a relative name) and this
- * function will return null. DIR_ENT will be initialized with
- * information about the directory (or other object) at which
+ * function will return null. GRP_ENT will be initialized with
+ * information about the group (or other object) at which
* the traversal failed. However, if the name can be fully
* resolved, then REST points to the null terminator of NAME.
*
* As a special case, if the NAME is the name `/' (or
- * equivalent) then DIR_ENT is initialized to all zero
+ * equivalent) then GRP_ENT is initialized to all zero
* and a pointer to the root symbol table entry is returned.
*
* As a special case, if the NAME is the string `/foo' (or
* equivalent) and the root symbol table entry points to a
- * non-directory object with a name message with the value
- * `foo' then DIR_ENT is initialized to all zero and a pointer
+ * non-group object with a name message with the value
+ * `foo' then GRP_ENT is initialized to all zero and a pointer
* to the root symbol table entry is returned.
*
* Errors:
- * DIRECTORY COMPLEN Component is too long.
- * DIRECTORY NOTFOUND Component not found.
- * DIRECTORY NOTFOUND Root not found.
+ * SYM COMPLEN Component is too long.
+ * SYM NOTFOUND Component not found.
+ * SYM NOTFOUND No root group.
+ * SYM NOTFOUND Root not found.
*
* Return: Success: Pointer to a cached symbol table entry if the
* name can be fully resolved. The pointer is
@@ -185,11 +446,11 @@ H5G_basename (const char *name, size_t *size_p)
* is called.
*
* Failure: Null if the name could not be fully resolved.
- * REST and DIR_ENT are initialized (possibly to
+ * REST and GRP_ENT are initialized (possibly to
* zero if the failure occurred soon enough).
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 11 1997
*
* Modifications:
@@ -197,10 +458,10 @@ H5G_basename (const char *name, size_t *size_p)
*-------------------------------------------------------------------------
*/
static H5G_entry_t *
-H5G_namei (H5F_t *f, H5G_entry_t *cwd, const char *name,
- const char **rest, H5G_entry_t *dir_ent)
+H5G_namei (H5F_t *f, H5G_entry_t *cwg, const char *name,
+ const char **rest, H5G_entry_t *grp_ent)
{
- H5G_entry_t dir; /*entry for current directory */
+ H5G_entry_t grp; /*entry for current group */
size_t nchars; /*component name length */
char comp[1024]; /*component name buffer */
hbool_t aside = FALSE; /*did we look at a name message?*/
@@ -208,7 +469,7 @@ H5G_namei (H5F_t *f, H5G_entry_t *cwd, const char *name,
/* clear output args before FUNC_ENTER() in case it fails */
if (rest) *rest = name;
- if (dir_ent) memset (dir_ent, 0, sizeof(H5G_entry_t));
+ if (grp_ent) memset (grp_ent, 0, sizeof(H5G_entry_t));
FUNC_ENTER (H5G_namei, NULL, NULL);
@@ -216,18 +477,19 @@ H5G_namei (H5F_t *f, H5G_entry_t *cwd, const char *name,
assert (f);
assert (f->shared->root_sym);
assert (name && *name);
- assert (cwd || '/'==*name);
+ assert (cwg || '/'==*name);
/* starting point */
if ('/'==*name) {
if (f->shared->root_sym->header<=0) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, NULL);
+ /* No root group */
+ HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, NULL);
}
ret_value = f->shared->root_sym;
- dir = *(f->shared->root_sym);
+ grp = *(f->shared->root_sym);
} else {
- ret_value = cwd;
- dir = *cwd;
+ ret_value = cwg;
+ grp = *cwg;
}
/* traverse the name */
@@ -241,7 +503,7 @@ H5G_namei (H5F_t *f, H5G_entry_t *cwd, const char *name,
/*
* Advance to the next component of the name.
*/
- dir = *ret_value;
+ grp = *ret_value;
ret_value = NULL;
if (rest) *rest = name;
@@ -251,23 +513,23 @@ H5G_namei (H5F_t *f, H5G_entry_t *cwd, const char *name,
*/
if (nchars+1 > sizeof(comp)) {
/* component is too long */
- if (dir_ent) *dir_ent = dir;
- HRETURN_ERROR (H5E_DIRECTORY, H5E_COMPLEN, NULL);
+ if (grp_ent) *grp_ent = grp;
+ HRETURN_ERROR (H5E_SYM, H5E_COMPLEN, NULL);
}
HDmemcpy (comp, name, nchars);
comp[nchars] = '\0';
- if (NULL==(ret_value=H5G_stab_find (f, NO_ADDR, &dir, comp))) {
+ if (NULL==(ret_value=H5G_stab_find (f, NO_ADDR, &grp, comp))) {
/*
* Component was not found in the current symbol table, possibly
- * because DIR isn't a symbol table. If it is the root symbol then
+ * because GRP isn't a symbol table. If it is the root symbol then
* see if it has the appropriate name field. The ASIDE variable
* prevents us from saying `/foo/foo' where the root object has
* the name `foo'.
*/
H5O_name_t mesg={0};
- if (!aside && dir.header==f->shared->root_sym->header &&
- H5O_read (f, dir.header, &dir, H5O_NAME, 0, &mesg) &&
+ if (!aside && grp.header==f->shared->root_sym->header &&
+ H5O_read (f, grp.header, &grp, H5O_NAME, 0, &mesg) &&
!HDstrcmp (mesg.s, comp)) {
H5O_reset (H5O_NAME, &mesg);
ret_value = f->shared->root_sym;
@@ -275,8 +537,8 @@ H5G_namei (H5F_t *f, H5G_entry_t *cwd, const char *name,
} else {
/* component not found */
H5O_reset (H5O_NAME, &mesg);
- if (dir_ent) *dir_ent = dir;
- HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, NULL);
+ if (grp_ent) *grp_ent = grp;
+ HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, NULL);
}
}
@@ -286,17 +548,17 @@ H5G_namei (H5F_t *f, H5G_entry_t *cwd, const char *name,
/* output parameters */
if (rest) *rest = name; /*final null*/
- if (dir_ent) {
+ if (grp_ent) {
if (ret_value->header == f->shared->root_sym->header) {
- HDmemset (dir_ent, 0, sizeof(H5G_entry_t)); /*root has no parent*/
+ HDmemset (grp_ent, 0, sizeof(H5G_entry_t)); /*root has no parent*/
} else {
- *dir_ent = dir;
+ *grp_ent = grp;
}
}
/* Perhaps the root object doesn't even exist! */
if (ret_value->header<=0) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, NULL); /*root not found*/
+ HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, NULL); /*root not found*/
}
FUNC_LEAVE (ret_value);
@@ -306,10 +568,10 @@ H5G_namei (H5F_t *f, H5G_entry_t *cwd, const char *name,
/*-------------------------------------------------------------------------
* Function: H5G_mkroot
*
- * Purpose: Creates the root directory if it doesn't exist; otherwise
+ * Purpose: Creates the root group if it doesn't exist; otherwise
* nothing happens. If the root symbol table entry previously
- * pointed to something other than a directory, then that object
- * is made a member of the root directory and is given a name
+ * pointed to something other than a group, then that object
+ * is made a member of the root group and is given a name
* corresponding to the object's name message (the name message
* is removed). If the root object doesn't have a name message
* then the name `Root Object' is used.
@@ -317,19 +579,21 @@ H5G_namei (H5F_t *f, H5G_entry_t *cwd, const char *name,
* Warning: This function has a few subtleties. Be warned!
*
* Errors:
- * DIRECTORY CANTINIT Can't create root.
- * DIRECTORY CANTINIT Can't insert old root object in
- * new root directory.
- * DIRECTORY EXISTS Root directory already exists.
+ * SYM CANTINIT Can't open root object.
+ * SYM CANTINIT Can't reinsert old root object.
+ * SYM CANTINIT Cant create root.
+ * SYM EXISTS Root group already exists.
+ * SYM LINK Bad link count on old root object.
+ * SYM LINK Cant create root.
*
* Return: Success: SUCCEED
*
* Failure: FAIL. This function returns -2 if the
- * failure is because a root directory already
+ * failure is because a root group already
* exists.
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 11 1997
*
* Modifications:
@@ -356,20 +620,21 @@ H5G_mkroot (H5F_t *f, size_t size_hint)
/*
* If we already have a root object, then open it and get it's name. The
- * root object had better not already be a directory. Once the old root
+ * root object had better not already be a group. Once the old root
* object is opened and we have a HANDLE, set the dirty bit on the handle.
* This causes the handle data to be written back into f->root_sym by
* H5G_close() if something goes wrong before the old root object is
- * re-inserted back into the directory hierarchy. We might leak file
+ * re-inserted back into the group directed graph. We might leak file
* memory, but at least we don't loose the original root object.
*/
if (f->shared->root_sym->header>0) {
if (H5O_read (f, NO_ADDR, f->shared->root_sym, H5O_STAB, 0, &stab)) {
- /* root directory already exists */
- HGOTO_ERROR (H5E_DIRECTORY, H5E_EXISTS, -2);
- } else if (NULL==(handle=H5G_shadow_open (f, NULL, f->shared->root_sym))) {
+ /* root group already exists */
+ HGOTO_ERROR (H5E_SYM, H5E_EXISTS, -2);
+ } else if (NULL==(handle=H5G_shadow_open (f, NULL,
+ f->shared->root_sym))) {
/* can't open root object */
- HGOTO_ERROR (H5E_DIRECTORY, H5E_CANTINIT, FAIL);
+ HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
} else if (NULL==H5O_read (f, NO_ADDR, handle, H5O_NAME, 0, &name)) {
obj_name = "Root Object";
} else {
@@ -379,15 +644,15 @@ H5G_mkroot (H5F_t *f, size_t size_hint)
}
/*
- * Create the new root directory directly into the file descriptor. If
+ * Create the new root group directly into the file descriptor. If
* something goes wrong at this step, closing the `handle' will rewrite
* info back into f->root_sym because we set the dirty bit.
*/
if (H5G_stab_new (f, f->shared->root_sym, size_hint)<0) {
- HGOTO_ERROR (H5E_DIRECTORY, H5E_CANTINIT, FAIL); /*cant create root*/
+ HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL); /*cant create root*/
}
if (1!=H5O_link (f, f->shared->root_sym, 1)) {
- HGOTO_ERROR (H5E_DIRECTORY, H5E_LINK, FAIL);
+ HGOTO_ERROR (H5E_SYM, H5E_LINK, FAIL);
}
/*
@@ -397,11 +662,13 @@ H5G_mkroot (H5F_t *f, size_t size_hint)
*/
if (obj_name) {
if (1!=H5O_link (f, handle, 0)) {
- HGOTO_ERROR (H5E_DIRECTORY, H5E_LINK, FAIL);
+ /* Bad link count on old root object */
+ HGOTO_ERROR (H5E_SYM, H5E_LINK, FAIL);
}
if (NULL==(ent_ptr=H5G_stab_insert (f, f->shared->root_sym, obj_name,
handle))) {
- HGOTO_ERROR (H5E_DIRECTORY, H5E_CANTINIT, FAIL);
+ /* Can't reinsert old root object */
+ HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
}
/*
@@ -418,10 +685,10 @@ H5G_mkroot (H5F_t *f, size_t size_hint)
done:
/*
* If the handle is closed before the H5G_stab_insert() call that
- * reinserts the root object into the directory hierarchy, then
+ * reinserts the root object into the group directed graph, then
* H5G_close() will reset f->root_sym to point to the old root symbol and
- * the new root directory (if it was created) will be unlinked from the
- * directory hierarchy (and memory leaked).
+ * the new root group (if it was created) will be unlinked from the
+ * group directed graph (and memory leaked).
*/
if (handle) H5G_close (f, handle);
H5O_reset (H5O_NAME, &name);
@@ -431,32 +698,33 @@ H5G_mkroot (H5F_t *f, size_t size_hint)
/*-------------------------------------------------------------------------
- * Function: H5G_mkdir
+ * Function: H5G_new
*
- * Purpose: Creates a new empty directory with the specified name,
+ * Purpose: Creates a new empty group with the specified name,
* opening it as an object. The name is either an absolute name
- * or is relative to the current working directory.
+ * or is relative to the current working group.
*
- * A root directory is created implicitly by this function
+ * A root group is created implicitly by this function
* when necessary. Calling this function with the name "/"
* (or any equivalent name) will result in an H5E_EXISTS
* failure.
*
* Errors:
- * DIRECTORY CANTINIT Can't create dir.
- * DIRECTORY CANTINIT Can't insert.
- * DIRECTORY CANTINIT Lookup failed.
- * DIRECTORY COMPLEN Component is too long.
- * DIRECTORY EXISTS Already exists.
- * DIRECTORY NOTFOUND Missing component.
- *
- * Return: Success: A handle to the open directory. Please call
+ * SYM CANTINIT Can't create grp.
+ * SYM CANTINIT Can't create root group.
+ * SYM CANTINIT Can't insert.
+ * SYM CANTINIT Can't open.
+ * SYM COMPLEN Component is too long.
+ * SYM EXISTS Already exists.
+ * SYM NOTFOUND Missing component.
+ *
+ * Return: Success: A handle to the open group. Please call
* H5G_close() when you're done with it.
*
* Failure: NULL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 11 1997
*
* Modifications:
@@ -464,42 +732,43 @@ H5G_mkroot (H5F_t *f, size_t size_hint)
*-------------------------------------------------------------------------
*/
H5G_entry_t *
-H5G_mkdir (H5F_t *f, const char *name, size_t size_hint)
+H5G_new (H5F_t *f, const char *name, size_t size_hint)
{
const char *rest=NULL; /*the base name */
- H5G_entry_t *cwd=NULL; /*current working directory */
- H5G_entry_t dir_ent; /*directory containing new dir */
- H5G_entry_t ent; /*new directory entry */
- H5G_entry_t *ent_ptr=NULL; /*ptr to new directory entry */
+ H5G_entry_t *cwg=NULL; /*current working group */
+ H5G_entry_t grp_ent; /*group containing new group */
+ H5G_entry_t ent; /*new group entry */
+ H5G_entry_t *ent_ptr=NULL; /*ptr to new group entry */
H5G_entry_t *ret_value=NULL; /*handle return value */
char _comp[1024]; /*name component */
size_t nchars; /*number of characters in compon*/
herr_t status; /*function return status */
- FUNC_ENTER (H5G_mkdir, NULL, NULL);
+ FUNC_ENTER (H5G_new, NULL, NULL);
/* check args */
assert (f);
assert (name && *name);
#ifndef LATER
- /* Get current working directory */
+ /* Get current working group */
H5G_shadow_sync (f->shared->root_sym);
- cwd = f->shared->root_sym;
+ cwg = f->shared->root_sym;
#endif
- assert (cwd || '/'==*name);
+ assert (cwg || '/'==*name);
/*
- * Try to create the root directory. Ignore the error if this function
- * fails because the root directory already exists.
+ * Try to create the root group. Ignore the error if this function
+ * fails because the root group already exists.
*/
if ((status=H5G_mkroot (f, H5G_SIZE_HINT))<0 && -2!=status) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL);
+ /* Can't create root group */
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, NULL);
}
H5ECLEAR;
/* lookup name */
- if (H5G_namei (f, cwd, name, &rest, &dir_ent)) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_EXISTS, NULL); /*already exists*/
+ if (H5G_namei (f, cwg, name, &rest, &grp_ent)) {
+ HRETURN_ERROR (H5E_SYM, H5E_EXISTS, NULL); /*already exists*/
}
H5ECLEAR; /*it's OK that we didn't find it*/
@@ -509,10 +778,10 @@ H5G_mkdir (H5F_t *f, const char *name, size_t size_hint)
if (rest[nchars]) {
if (H5G_component (rest+nchars, NULL)) {
/* missing component */
- HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, NULL);
+ HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, NULL);
} else if (nchars+1 > sizeof _comp) {
/* component is too long */
- HRETURN_ERROR (H5E_DIRECTORY, H5E_COMPLEN, NULL);
+ HRETURN_ERROR (H5E_SYM, H5E_COMPLEN, NULL);
} else {
/* null terminate */
HDmemcpy (_comp, rest, nchars);
@@ -521,19 +790,19 @@ H5G_mkdir (H5F_t *f, const char *name, size_t size_hint)
}
}
- /* create directory */
+ /* create group */
if (H5G_stab_new (f, &ent, size_hint)<0) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL); /*can't create dir*/
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, NULL); /*can't create grp*/
}
/* insert child name into parent */
- if (NULL==(ent_ptr=H5G_stab_insert (f, &dir_ent, rest, &ent))) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL); /*can't insert*/
+ if (NULL==(ent_ptr=H5G_stab_insert (f, &grp_ent, rest, &ent))) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, NULL); /*can't insert*/
}
- /* open the directory */
- if (NULL==(ret_value=H5G_shadow_open (f, &dir_ent, ent_ptr))) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL); /*can't open*/
+ /* open the group */
+ if (NULL==(ret_value=H5G_shadow_open (f, &grp_ent, ent_ptr))) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, NULL); /*can't open*/
}
FUNC_LEAVE (ret_value);
@@ -542,9 +811,121 @@ H5G_mkdir (H5F_t *f, const char *name, size_t size_hint)
/*-------------------------------------------------------------------------
- * Function: H5G_pushd
+ * Function: H5G_set
+ *
+ * Purpose: Sets the current working group to be the specified name.
+ * This affects only the top item on the group stack for the
+ * specified file as accessed through this file handle. If the
+ * file is opened multiple times, then the current working group
+ * for this file handle is the only one that is changed.
*
- * Purpose: Pushes a new current working directory onto the stack.
+ * Errors:
+ * SYM CWG Can't open group.
+ * SYM CWG Couldn't close previous c.w.g.
+ * SYM CWG Not a group.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, September 24, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_set (H5F_t *f, const char *name)
+{
+ H5G_entry_t *handle=NULL;
+ H5O_stab_t stab_mesg;
+ herr_t ret_value=FAIL;
+
+ FUNC_ENTER (H5G_set, NULL, FAIL);
+
+ if (NULL==(handle=H5G_open (f, name))) {
+ /* Can't open group */
+ HGOTO_ERROR (H5E_SYM, H5E_CWG, FAIL);
+ }
+ if (NULL==H5O_read (f, NO_ADDR, handle, H5O_NAME, 0, &stab_mesg)) {
+ /* Not a group */
+ HGOTO_ERROR (H5E_SYM, H5E_CWG, FAIL);
+ }
+
+ /*
+ * If there is no stack then create one, otherwise close the current
+ * working group.
+ */
+ if (!f->cwg_stack) {
+ f->cwg_stack = H5MM_xcalloc (1, sizeof(H5G_cwgstk_t));
+ f->cwg_stack->handle = handle;
+ } else {
+ if (H5G_close (f, f->cwg_stack->handle)<0) {
+ /* Couldn't close previous c.w.g. */
+ HGOTO_ERROR (H5E_SYM, H5E_CWG, FAIL);
+ }
+ f->cwg_stack->handle = handle;
+ }
+ ret_value = SUCCEED;
+
+ done:
+ if (ret_value<0 && handle) {
+ H5G_close (f, handle);
+ }
+
+ FUNC_LEAVE (ret_value);
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_getcwg
+ *
+ * Purpose: Returns a handle for the current working group. If there
+ * is no current working group then a pointer to the root
+ * symbol is returned but that object is not opened (and it
+ * might not even be a group).
+ *
+ * Return: Success: Ptr to open group handle with exceptions
+ * noted above.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, September 24, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5G_entry_t *
+H5G_getcwg (H5F_t *f)
+{
+ H5G_entry_t *handle=NULL;
+
+ FUNC_ENTER (H5G_getcwg, NULL, NULL);
+
+ if (f->cwg_stack && f->cwg_stack->handle) {
+ handle = f->cwg_stack->handle;
+ } else {
+ H5G_shadow_sync (f->shared->root_sym);
+ handle = f->shared->root_sym;
+ }
+
+ FUNC_LEAVE (handle);
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_push
+ *
+ * Purpose: Pushes a new current working group onto the stack.
+ *
+ * Errors:
+ * SYM CWG Can't open group.
+ * SYM CWG Not a group.
*
* Return: Success: SUCCEED
*
@@ -558,31 +939,54 @@ H5G_mkdir (H5F_t *f, const char *name, size_t size_hint)
*-------------------------------------------------------------------------
*/
herr_t
-H5G_pushd (H5F_t *f, const char *name)
+H5G_push (H5F_t *f, const char *name)
{
+ H5G_entry_t *handle=NULL;
+ H5G_cwgstk_t *stack=NULL;
+ H5O_stab_t stab_mesg;
+ herr_t ret_value = FAIL;
+
FUNC_ENTER (H5G_pushd, NULL, FAIL);
-#ifndef LATER
+ if (NULL==(handle=H5G_open (f, name))) {
+ /* Can't open group */
+ HGOTO_ERROR (H5E_SYM, H5E_CWG, FAIL);
+ }
+ if (NULL==H5O_read (f, NO_ADDR, handle, H5O_NAME, 0, &stab_mesg)) {
+ /* Not a group */
+ HGOTO_ERROR (H5E_SYM, H5E_CWG, FAIL);
+ }
+
/*
- * Current working directories are not implemented yet.
+ * Push a new entry onto the stack.
*/
- if (strcmp (name, "/")) {
- HRETURN_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL);
+ stack = H5MM_xcalloc (1, sizeof(H5G_cwgstk_t));
+ stack->handle = handle;
+ stack->next = f->cwg_stack;
+ f->cwg_stack = stack;
+ ret_value = SUCCEED;
+
+ done:
+ if (ret_value<0 && handle) {
+ H5G_close (f, handle);
}
-#endif
-
+
FUNC_LEAVE (SUCCEED);
}
/*-------------------------------------------------------------------------
- * Function: H5G_popd
+ * Function: H5G_pop
*
- * Purpose: Pops the top current working directory off the stack.
+ * Purpose: Pops the top current working group off the stack.
+ *
+ * Errors:
+ * SYM CWG Can't close current working group.
+ * SYM CWG Stack is empty.
*
* Return: Success: SUCCEED
*
- * Failure: FAIL
+ * Failure: FAIL if the stack is empty.
*
* Programmer: Robb Matzke
* Friday, September 19, 1997
@@ -592,13 +996,24 @@ H5G_pushd (H5F_t *f, const char *name)
*-------------------------------------------------------------------------
*/
herr_t
-H5G_popd (H5F_t *f)
+H5G_pop (H5F_t *f)
{
- FUNC_ENTER (H5G_popd, NULL, FAIL);
+ H5G_cwgstk_t *stack=NULL;
+
+ FUNC_ENTER (H5G_pop, NULL, FAIL);
-#ifndef LATER
- /* CWD is not implemented yet. */
-#endif
+ if ((stack=f->cwg_stack)) {
+ if (H5G_close (f, stack->handle)<0) {
+ /* Can't close current working group */
+ HRETURN_ERROR (H5E_SYM, H5E_CWG, FAIL);
+ }
+ f->cwg_stack = stack->next;
+ stack->handle = NULL;
+ H5MM_xfree (stack);
+ } else {
+ /* Stack is empty */
+ HRETURN_ERROR (H5E_SYM, H5E_CWG, FAIL);
+ }
FUNC_LEAVE (SUCCEED);
}
@@ -612,6 +1027,21 @@ H5G_popd (H5F_t *f)
* object. The initial size of the object header can be
* supplied with the OHDR_HINT argument.
*
+ * Errors:
+ * SYM CANTINIT Bad link count.
+ * SYM CANTINIT Can't create header.
+ * SYM CANTINIT Can't create root group.
+ * SYM CANTINIT Can't insert.
+ * SYM CANTINIT Can't open object.
+ * SYM CANTINIT Cannot add/change name message.
+ * SYM CANTINIT Create the object header.
+ * SYM COMPLEN Component is too long.
+ * SYM EXISTS Already exists.
+ * SYM EXISTS Root exists.
+ * SYM LINK Bad link count.
+ * SYM LINK Link inc failure.
+ * SYM NOTFOUND Component not found.
+ *
* Return: Success: A handle for the object. Be sure to
* eventually close it.
*
@@ -629,9 +1059,9 @@ H5G_create (H5F_t *f, const char *name, size_t ohdr_hint)
{
H5G_entry_t ent; /*entry data for the new object */
H5G_entry_t *ent_ptr; /*ptr into symbol node for entry*/
- H5G_entry_t *cwd=NULL; /*ptr to CWD handle */
+ H5G_entry_t *cwg=NULL; /*ptr to c.w.g. handle */
const char *rest = NULL; /*part of name not existing yet */
- H5G_entry_t dir; /*entry for dir to contain obj */
+ H5G_entry_t grp; /*entry for group to contain obj*/
H5G_entry_t *ret_value=NULL; /*the object handle */
size_t nchars; /*number of characters in name */
char _comp[1024]; /*name component */
@@ -644,18 +1074,15 @@ H5G_create (H5F_t *f, const char *name, size_t ohdr_hint)
HDmemset (&ent, 0, sizeof(H5G_entry_t));
/*
- * Get the current working directory.
+ * Get the current working group.
*/
-#ifndef LATER
- H5G_shadow_sync (f->shared->root_sym);
- cwd = f->shared->root_sym;
-#endif
+ cwg = H5G_getcwg (f);
/*
* Look up the name -- it shouldn't exist yet.
*/
- if (H5G_namei (f, cwd, name, &rest, &dir)) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_EXISTS, NULL); /*already exists*/
+ if (H5G_namei (f, cwg, name, &rest, &grp)) {
+ HRETURN_ERROR (H5E_SYM, H5E_EXISTS, NULL); /*already exists*/
}
H5ECLEAR; /*it's OK that we didn't find it*/
rest = H5G_component (rest, &nchars);
@@ -667,18 +1094,18 @@ H5G_create (H5F_t *f, const char *name, size_t ohdr_hint)
* it already has as a message.
*/
if (f->shared->root_sym->header>0) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_EXISTS, NULL); /*root exists*/
+ HRETURN_ERROR (H5E_SYM, H5E_EXISTS, NULL); /*root exists*/
}
if ((ent.header = H5O_new (f, 0, ohdr_hint))<0) {
/* can't create header */
- HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL);
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, NULL);
}
if (1!=H5O_link (f, &ent, 1)) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_LINK, NULL); /*bad link count*/
+ HRETURN_ERROR (H5E_SYM, H5E_LINK, NULL); /*bad link count*/
}
*(f->shared->root_sym) = ent;
- if (NULL==(ret_value=H5G_shadow_open (f, &dir, f->shared->root_sym))) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL);
+ if (NULL==(ret_value=H5G_shadow_open (f, &grp, f->shared->root_sym))) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, NULL);
}
HRETURN (ret_value);
}
@@ -690,10 +1117,10 @@ H5G_create (H5F_t *f, const char *name, size_t ohdr_hint)
if (rest[nchars]) {
if (H5G_component (rest+nchars, NULL)) {
/* component not found */
- HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, NULL);
+ HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, NULL);
} else if (nchars+1 > sizeof _comp) {
/* component is too long */
- HRETURN_ERROR (H5E_DIRECTORY, H5E_COMPLEN, NULL);
+ HRETURN_ERROR (H5E_SYM, H5E_COMPLEN, NULL);
} else {
/* null terminate */
HDmemcpy (_comp, rest, nchars);
@@ -706,7 +1133,7 @@ H5G_create (H5F_t *f, const char *name, size_t ohdr_hint)
* Create the object header.
*/
if ((ent.header = H5O_new (f, 0, ohdr_hint))<0) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL);
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, NULL);
}
@@ -721,28 +1148,29 @@ H5G_create (H5F_t *f, const char *name, size_t ohdr_hint)
name_mesg.s = rest;
if (H5O_modify (f, NO_ADDR, &ent, H5O_NAME, 0, &name_mesg)<0) {
/* cannot add/change name message */
- HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL);
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, NULL);
}
if (1!=H5O_link (f, &ent, 1)) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_LINK, NULL); /*bad link count*/
+ HRETURN_ERROR (H5E_SYM, H5E_LINK, NULL); /*bad link count*/
}
*(f->shared->root_sym) = ent;
- if (NULL==(ret_value=H5G_shadow_open (f, &dir, f->shared->root_sym))) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL);
+ if (NULL==(ret_value=H5G_shadow_open (f, &grp, f->shared->root_sym))) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, NULL);
}
HRETURN (ret_value);
} else {
/*
- * Make sure the root directory exists. Ignore the failure if it's
- * because the directory already exists.
+ * Make sure the root group exists. Ignore the failure if it's
+ * because the group already exists.
*/
- hbool_t update_dir = (dir.header==f->shared->root_sym->header);
+ hbool_t update_grp = (grp.header==f->shared->root_sym->header);
herr_t status = H5G_mkroot (f, H5G_SIZE_HINT);
if (status<0 && -2!=status) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL);
+ /* Can't create root group */
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, NULL);
}
H5ECLEAR;
- if (update_dir) dir = *(f->shared->root_sym);
+ if (update_grp) grp = *(f->shared->root_sym);
}
/*
@@ -750,13 +1178,13 @@ H5G_create (H5F_t *f, const char *name, size_t ohdr_hint)
* entry into a symbol table.
*/
if (H5O_link (f, &ent, 1)<0) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_LINK, NULL); /*link inc failure*/
+ HRETURN_ERROR (H5E_SYM, H5E_LINK, NULL); /*link inc failure*/
}
- if (NULL==(ent_ptr=H5G_stab_insert (f, &dir, rest, &ent))) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL); /*can't insert*/
+ if (NULL==(ent_ptr=H5G_stab_insert (f, &grp, rest, &ent))) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, NULL); /*can't insert*/
}
- if (NULL==(ret_value=H5G_shadow_open (f, &dir, ent_ptr))) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL); /*can't open object*/
+ if (NULL==(ret_value=H5G_shadow_open (f, &grp, ent_ptr))) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, NULL); /*can't open object*/
}
FUNC_LEAVE (ret_value);
}
@@ -776,6 +1204,11 @@ H5G_create (H5F_t *f, const char *name, size_t ohdr_hint)
* structs. The structs that are returned should be
* released by calling H5G_close().
*
+ * Errors:
+ * SYM BADVALUE Check args.
+ * SYM CANTOPENOBJ Can't open obj.
+ * SYM NOTFOUND Object not found.
+ *
* Return: Success: Ptr to a handle for the object.
*
* Failure: NULL
@@ -792,32 +1225,29 @@ H5G_open (H5F_t *f, const char *name)
{
H5G_entry_t *ent=NULL;
H5G_entry_t *ret_value=NULL;
- H5G_entry_t dir;
- H5G_entry_t *cwd=NULL;
+ H5G_entry_t grp;
+ H5G_entry_t *cwg=NULL;
FUNC_ENTER (H5G_open, NULL, NULL);
/* check args */
assert (f);
if (!name || !*name) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_BADVALUE, NULL);
+ HRETURN_ERROR (H5E_SYM, H5E_BADVALUE, NULL);
}
- /* Get CWD */
-#ifndef LATER
- H5G_shadow_sync (f->shared->root_sym);
- cwd = f->shared->root_sym;
-#endif
- assert (cwd || '/'==*name);
+ /* Get CWG */
+ cwg = H5G_getcwg (f);
+ assert (cwg || '/'==*name);
if (f->shared->root_sym->header<=0) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, NULL); /*object not found*/
+ HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, NULL); /*object not found*/
}
- if (NULL==(ent=H5G_namei (f, cwd, name, NULL, &dir))) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, NULL); /*object not found*/
+ if (NULL==(ent=H5G_namei (f, cwg, name, NULL, &grp))) {
+ HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, NULL); /*object not found*/
}
- if (NULL==(ret_value=H5G_shadow_open (f, &dir, ent))) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTOPENOBJ, NULL);
+ if (NULL==(ret_value=H5G_shadow_open (f, &grp, ent))) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTOPENOBJ, NULL); /*can't open obj*/
}
FUNC_LEAVE (ret_value);
@@ -830,6 +1260,9 @@ H5G_open (H5F_t *f, const char *name)
*
* Purpose: Closes an object that was open for modification.
*
+ * Errors:
+ * SYM CANTFLUSH Can't close object.
+ *
* Return: Success: SUCCEED
*
* Failure: FAIL
@@ -849,6 +1282,7 @@ H5G_close (H5F_t *f, H5G_entry_t *ent)
assert (f);
if (ent && H5G_shadow_close (f, ent)<0) {
+ /* Can't close object */
HRETURN_ERROR (H5E_SYM, H5E_CANTFLUSH, FAIL);
}
@@ -861,22 +1295,21 @@ H5G_close (H5F_t *f, H5G_entry_t *ent)
*
* Purpose: Finds an object with the specified NAME in file F. If
* the name is relative then it is interpretted relative
- * to CWD, a symbol table entry for a symbol table. On
- * successful return, DIR_ENT (if non-null) will be
- * initialized with the symbol table information for the
- * directory in which the object appears (or all zero if
- * the returned object is the root object) and ENT will
- * be initialized with the symbol table entry for the
- * object (ENT is optional when the caller is interested
- * only in the existence of the object).
+ * to the current working group. On successful return,
+ * GRP_ENT (if non-null) will be initialized with the symbol
+ * table information for the group in which the object
+ * appears (or all zero if the returned object is the root
+ * object) and ENT will be initialized with the symbol table
+ * entry for the object (ENT is optional when the caller is
+ * interested only in the existence of the object).
*
* This function will fail if the root object is
* requested and there is none.
*
* Errors:
- * DIRECTORY NOTFOUND Object not found.
+ * SYM NOTFOUND Object not found.
*
- * Return: Success: SUCCEED with DIR_ENT and ENT initialized. ENT
+ * Return: Success: SUCCEED with GRP_ENT and ENT initialized. ENT
* is intended for immediate read-only access.
* If the object that ENT refers to is open
* through the ENT entry (see H5G_open()) then
@@ -888,7 +1321,7 @@ H5G_close (H5F_t *f, H5G_entry_t *ent)
* Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 12 1997
*
* Modifications:
@@ -896,23 +1329,25 @@ H5G_close (H5F_t *f, H5G_entry_t *ent)
*-------------------------------------------------------------------------
*/
herr_t
-H5G_find (H5F_t *f, H5G_entry_t *cwd, H5G_entry_t *dir_ent,
- const char *name, H5G_entry_t *ent)
+H5G_find (H5F_t *f, const char *name, H5G_entry_t *grp_ent, H5G_entry_t *ent)
{
H5G_entry_t *ent_p = NULL;
+ H5G_entry_t *cwg = NULL;
+
FUNC_ENTER (H5G_find, NULL, FAIL);
/* check args */
assert (f);
assert (name && *name);
- assert (cwd || '/'==*name);
+ cwg = H5G_getcwg (f);
+ assert (cwg || '/'==*name);
if (f->shared->root_sym->header<=0) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, FAIL); /*object not found*/
+ HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL); /*object not found*/
}
- if (NULL==(ent_p=H5G_namei (f, cwd, name, NULL, dir_ent))) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, FAIL); /*object not found*/
+ if (NULL==(ent_p=H5G_namei (f, cwg, name, NULL, grp_ent))) {
+ HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL); /*object not found*/
}
if (ent) *ent = *ent_p;
diff --git a/src/H5Gent.c b/src/H5Gent.c
index f9ca290..b5cddce 100644
--- a/src/H5Gent.c
+++ b/src/H5Gent.c
@@ -410,7 +410,7 @@ H5G_ent_encode (H5F_t *f, uint8 **pp, H5G_entry_t *ent)
* Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 29 1997
*
* Modifications:
diff --git a/src/H5Gnode.c b/src/H5Gnode.c
index 84dc0e5..58c924c 100644
--- a/src/H5Gnode.c
+++ b/src/H5Gnode.c
@@ -39,29 +39,32 @@
#define PABLO_MASK H5G_node_mask
/* PRIVATE PROTOTYPES */
-static herr_t H5G_node_decode_key (H5F_t *f, uint8 *raw, void *_key);
-static herr_t H5G_node_encode_key (H5F_t *f, uint8 *raw, void *_key);
+static herr_t H5G_node_decode_key (H5F_t *f, H5B_t *bt, uint8 *raw,
+ void *_key);
+static herr_t H5G_node_encode_key (H5F_t *f, H5B_t *bt, uint8 *raw,
+ void *_key);
static size_t H5G_node_size (H5F_t *f);
static haddr_t H5G_node_new (H5F_t *f, void *_lt_key, void *_udata,
void *_rt_key);
static herr_t H5G_node_flush (H5F_t *f, hbool_t destroy, haddr_t addr,
H5G_node_t *sym);
-static H5G_node_t *H5G_node_load (H5F_t *f, haddr_t addr, void *_data);
+static H5G_node_t *H5G_node_load (H5F_t *f, haddr_t addr, void *_udata1,
+ void *_udata2);
static intn H5G_node_cmp (H5F_t *f, void *_lt_key, void *_udata,
void *_rt_key);
static herr_t H5G_node_found (H5F_t *f, haddr_t addr,
const void *_lt_key, void *_udata,
const void *_rt_key);
-static haddr_t H5G_node_insert (H5F_t *f, haddr_t addr, intn *anchor,
+static haddr_t H5G_node_insert (H5F_t *f, haddr_t addr, H5B_ins_t *anchor,
void *_lt_key, hbool_t *lt_key_changed,
void *_md_key, void *_udata,
void *_rt_key, hbool_t *rt_key_changed);
static herr_t H5G_node_list (H5F_t *f, haddr_t addr, void *_udata);
-static size_t H5G_node_sizeof_rkey (H5F_t *f);
+static size_t H5G_node_sizeof_rkey (H5F_t *f, const void *_udata);
/* H5G inherits cache-like properties from H5AC */
const H5AC_class_t H5AC_SNODE[1] = {{
- (void*(*)(H5F_t*,haddr_t,void*))H5G_node_load,
+ (void*(*)(H5F_t*,haddr_t,void*,void*))H5G_node_load,
(herr_t(*)(H5F_t*,hbool_t,haddr_t,void*))H5G_node_flush,
}};
@@ -74,6 +77,8 @@ H5B_class_t H5B_SNODE[1] = {{
H5G_node_cmp, /*cmp */
H5G_node_found, /*found */
H5G_node_insert, /*insert */
+ TRUE, /*follow min branch? */
+ TRUE, /*follow max branch? */
H5G_node_list, /*list */
H5G_node_decode_key, /*decode */
H5G_node_encode_key, /*encode */
@@ -102,7 +107,7 @@ static intn interface_initialize_g = FALSE;
*-------------------------------------------------------------------------
*/
static size_t
-H5G_node_sizeof_rkey (H5F_t *f)
+H5G_node_sizeof_rkey (H5F_t *f, const void *udata __attribute__((unused)))
{
return H5F_SIZEOF_OFFSET(f);
}
@@ -126,7 +131,7 @@ H5G_node_sizeof_rkey (H5F_t *f)
*-------------------------------------------------------------------------
*/
static herr_t
-H5G_node_decode_key (H5F_t *f, uint8 *raw, void *_key)
+H5G_node_decode_key (H5F_t *f, H5B_t *bt, uint8 *raw, void *_key)
{
H5G_node_key_t *key = (H5G_node_key_t *)_key;
@@ -160,7 +165,7 @@ H5G_node_decode_key (H5F_t *f, uint8 *raw, void *_key)
*-------------------------------------------------------------------------
*/
static herr_t
-H5G_node_encode_key (H5F_t *f, uint8 *raw, void *_key)
+H5G_node_encode_key (H5F_t *f, H5B_t *bt, uint8 *raw, void *_key)
{
H5G_node_key_t *key = (H5G_node_key_t *)_key;
@@ -378,12 +383,12 @@ H5G_node_flush (H5F_t *f, hbool_t destroy, haddr_t addr, H5G_node_t *sym)
*-------------------------------------------------------------------------
*/
static H5G_node_t *
-H5G_node_load (H5F_t *f, haddr_t addr, void *_udata)
+H5G_node_load (H5F_t *f, haddr_t addr, void *_udata1, void *_udata2)
{
H5G_node_t *sym = NULL;
size_t size = 0;
uint8 *buf = NULL, *p = NULL;
- H5G_ac_ud1_t *ac_udata = (H5G_ac_ud1_t*)_udata;
+ H5G_ac_ud1_t *ac_udata = (H5G_ac_ud1_t*)_udata1;
H5G_node_t *ret_value = NULL; /*for error handling*/
FUNC_ENTER (H5G_node_load, NULL, NULL);
@@ -394,6 +399,7 @@ H5G_node_load (H5F_t *f, haddr_t addr, void *_udata)
assert (f);
assert (addr>=0);
assert (ac_udata);
+ assert (NULL==_udata2);
/*
* Initialize variables.
@@ -453,21 +459,21 @@ H5G_node_load (H5F_t *f, haddr_t addr, void *_udata)
/*-------------------------------------------------------------------------
* Function: H5G_node_cmp
*
- * Purpose: Compares two keys from a B-tree node (LEFT and RIGHT)
+ * Purpose: Compares two keys from a B-tree node (LT_KEY and RT_KEY)
* against another key (not necessarily the same type)
* pointed to by UDATA.
*
* Return: Success: negative if the UDATA key is less than
- * or equal to the LEFT key.
+ * or equal to the LT_KEY
*
* positive if the UDATA key is greater
- * than the RIGHT key.
+ * than the RT_KEY.
*
* zero if the UDATA key falls between
- * the LEFT key (exclusive) and the
- * RIGHT key (inclusive).
+ * the LT_KEY (exclusive) and the
+ * RT_KEY (inclusive).
*
- * Failure: FAIL (same as LT < RT)
+ * Failure: FAIL (same as UDATA < LT_KEY)
*
* Programmer: Robb Matzke
* matzke@llnl.gov
@@ -551,13 +557,13 @@ H5G_node_found (H5F_t *f, haddr_t addr, const void *_lt_key,
assert (addr>=0);
assert (bt_udata);
- ac_udata.dir_addr = bt_udata->dir_addr;
+ ac_udata.grp_addr = bt_udata->grp_addr;
ac_udata.heap_addr = bt_udata->heap_addr;
/*
* Load the symbol table node for exclusive access.
*/
- if (NULL==(sn=H5AC_protect (f, H5AC_SNODE, addr, &ac_udata))) {
+ if (NULL==(sn=H5AC_protect (f, H5AC_SNODE, addr, &ac_udata, NULL))) {
HGOTO_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
}
@@ -656,7 +662,7 @@ done:
*-------------------------------------------------------------------------
*/
static haddr_t
-H5G_node_insert (H5F_t *f, haddr_t addr, intn *anchor,
+H5G_node_insert (H5F_t *f, haddr_t addr, H5B_ins_t *anchor,
void *_lt_key, hbool_t *lt_key_changed,
void *_md_key, void *_udata,
void *_rt_key, hbool_t *rt_key_changed)
@@ -693,19 +699,11 @@ H5G_node_insert (H5F_t *f, haddr_t addr, intn *anchor,
bt_udata->entry_ptr = NULL;
/*
- * Symbol tables are always split so the new symbol table node is
- * to the right of the old one.
- */
- *anchor = H5B_ANCHOR_LT;
- *lt_key_changed = FALSE;
- *rt_key_changed = FALSE;
-
- /*
* Load the symbol node.
*/
- ac_udata.dir_addr = bt_udata->dir_addr;
+ ac_udata.grp_addr = bt_udata->grp_addr;
ac_udata.heap_addr = bt_udata->heap_addr;
- if (NULL==(sn=H5AC_protect (f, H5AC_SNODE, addr, &ac_udata))) {
+ if (NULL==(sn=H5AC_protect (f, H5AC_SNODE, addr, &ac_udata, NULL))) {
HGOTO_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
}
@@ -746,12 +744,13 @@ H5G_node_insert (H5F_t *f, haddr_t addr, intn *anchor,
* node and return the address of the new right node (the
* left node is at the same address as the original node).
*/
+ *anchor = H5B_INS_RIGHT;
/* The right node */
if ((new_node = H5G_node_new (f, NULL, NULL, NULL))<0) {
HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
}
- if (NULL==(snrt=H5AC_find (f, H5AC_SNODE, new_node, &ac_udata))) {
+ if (NULL==(snrt=H5AC_find (f, H5AC_SNODE, new_node, &ac_udata, NULL))) {
HGOTO_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
}
HDmemcpy (snrt->entry, sn->entry + H5G_NODE_K(f),
@@ -789,6 +788,7 @@ H5G_node_insert (H5F_t *f, haddr_t addr, intn *anchor,
} else {
/* Where to insert the new entry? */
+ *anchor = H5B_INS_NOOP;
sn->dirty = TRUE;
insert_into = sn;
insert_addr = addr;
@@ -809,7 +809,7 @@ H5G_node_insert (H5F_t *f, haddr_t addr, intn *anchor,
H5G_shadow_move (f, bt_udata->entry.shadow,
bt_udata->name,
insert_into->entry + idx,
- bt_udata->dir_addr);
+ bt_udata->grp_addr);
}
/* Move entries */
@@ -837,7 +837,8 @@ done:
if (H5AC_unprotect (f, H5AC_SNODE, addr, sn)<0) {
HRETURN_ERROR (H5E_SYM, H5E_PROTECT, FAIL);
}
- if (NULL==(sn=H5AC_protect (f, H5AC_SNODE, insert_addr, &ac_udata))) {
+ if (NULL==(sn=H5AC_protect (f, H5AC_SNODE, insert_addr, &ac_udata,
+ NULL))) {
HGOTO_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
}
assert (sn==bt_udata->node_ptr);
@@ -852,7 +853,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5G_node_list
*
- * Purpose: This function gets called during a directory list operation.
+ * Purpose: This function gets called during a group list operation.
* It should fill in data in the UDATA struct.
*
* Return: Success: SUCCEED
@@ -886,9 +887,9 @@ H5G_node_list (H5F_t *f, haddr_t addr, void *_udata)
assert (addr>=0);
assert (bt_udata);
- ac_udata.dir_addr = bt_udata->dir_addr;
+ ac_udata.grp_addr = bt_udata->grp_addr;
ac_udata.heap_addr = bt_udata->heap_addr;
- if (NULL==(sn=H5AC_protect (f, H5AC_SNODE, addr, &ac_udata))) {
+ if (NULL==(sn=H5AC_protect (f, H5AC_SNODE, addr, &ac_udata, NULL))) {
HGOTO_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
}
@@ -978,21 +979,21 @@ H5G_node_debug (H5F_t *f, haddr_t addr, FILE *stream, intn indent,
* We have absolutely no idea where the object header for the symbol table
* to which this node belongs is located. In fact, if the file is corrupt,
* there may not even be an object header for that symbol table. So we
- * supply `-1' as the directory address which causes no open objects to be
+ * supply `-1' as the group address which causes no open objects to be
* associated with the node. For that reason, we flush this node from the
* cache when we're done so if some later caller knows the header address
* they'll be able to access the open objects.
*/
- ac_udata.dir_addr = -1;
+ ac_udata.grp_addr = -1;
ac_udata.heap_addr = heap;
/*
* If we couldn't load the symbol table node, then try loading the
* B-tree node.
*/
- if (NULL==(sn=H5AC_find(f, H5AC_SNODE, addr, &ac_udata))) {
+ if (NULL==(sn=H5AC_find(f, H5AC_SNODE, addr, &ac_udata, NULL))) {
H5ECLEAR; /*discard that error*/
- status = H5B_debug (f, addr, stream, indent, fwidth, H5B_SNODE);
+ status = H5B_debug (f, addr, stream, indent, fwidth, H5B_SNODE, NULL);
if (status<0) HRETURN_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
HRETURN (SUCCEED);
}
diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h
index e0d6f8d..9421541 100644
--- a/src/H5Gpkg.h
+++ b/src/H5Gpkg.h
@@ -20,7 +20,7 @@
#include <H5Gprivate.h>
#define H5G_NODE_VERS 1 /*symbol table node version number */
-#define H5G_SIZE_HINT 1024 /*default root dir size hint */
+#define H5G_SIZE_HINT 1024 /*default root grp size hint */
#define H5G_NODE_K(F) ((F)->shared->file_create_parms.sym_leaf_k)
#define H5G_NODE_SIZEOF_HDR(F) (H5G_NODE_SIZEOF_MAGIC + 4)
#define H5G_DEFAULT_ROOT_SIZE 32
@@ -44,7 +44,7 @@ struct H5G_entry_t {
* A symbol table node is a collection of symbol table entries. It can
* be thought of as the lowest level of the B-link tree that points to
* a collection of symbol table entries that belong to a specific symbol
- * table or directory.
+ * table or group.
*/
typedef struct H5G_node_t {
hbool_t dirty; /*has cache been modified? */
@@ -61,7 +61,7 @@ typedef struct H5G_node_t {
*/
struct H5G_shadow_t {
char *name; /*name for this entry */
- haddr_t dir_addr; /*hdr addr for dir containing shadow */
+ haddr_t grp_addr; /*hdr addr for group containing shadow */
uintn nrefs; /*reference counter */
H5G_entry_t entry; /*local copy of symbol table entry */
H5G_entry_t *main; /*main entry in stab node if cached */
@@ -78,6 +78,16 @@ typedef struct H5G_node_key_t {
} H5G_node_key_t;
/*
+ * Each file has a stack of open groups with the latest entry on the
+ * stack the current working group. If the stack is empty then the
+ * current working group is the root object.
+ */
+typedef struct H5G_cwgstk_t {
+ H5G_entry_t *handle; /*a handle to an open group */
+ struct H5G_cwgstk_t *next; /*next item (earlier) on stack */
+} H5G_cwgstk_t;
+
+/*
* These operations can be passed down from the H5G_stab layer to the
* H5G_node layer through the B-tree layer.
*/
@@ -96,7 +106,7 @@ typedef struct H5G_bt_ud1_t {
/* downward */
H5G_oper_t operation; /*what operation to perform */
const char *name; /*points to temporary memory */
- haddr_t dir_addr; /*symbol table header address */
+ haddr_t grp_addr; /*symbol table header address */
haddr_t heap_addr; /*symbol table heap address */
/* downward for INSERT */
@@ -119,7 +129,7 @@ typedef struct H5G_bt_ud2_t {
H5G_entry_t *entry; /*array of entries, alloc'd by caller */
char **name; /*array of string ptrs, allocd by caller*/
intn maxentries; /*size of the ADDR and NAME arrays */
- haddr_t dir_addr; /*symbol table header address */
+ haddr_t grp_addr; /*symbol table header address */
haddr_t heap_addr; /*heap address */
/* upward */
@@ -137,15 +147,15 @@ extern H5B_class_t H5B_SNODE[1];
*/
typedef struct H5G_ac_ud1_t {
haddr_t heap_addr;
- haddr_t dir_addr;
+ haddr_t grp_addr;
} H5G_ac_ud1_t;
/* The cache subclass */
extern const H5AC_class_t H5AC_SNODE[1];
/*
- * Functions that understand symbol tables but not directories. The
- * functions that understand directories are exported to the rest of
+ * Functions that understand symbol tables but not names. The
+ * functions that understand names are exported to the rest of
* the library and appear in H5Gprivate.h.
*/
haddr_t H5G_stab_new (H5F_t *f, H5G_entry_t *self, size_t init);
@@ -160,7 +170,7 @@ intn H5G_stab_list (H5F_t *f, H5G_entry_t *self, intn maxentries,
* Functions that understand shadow entries.
*/
herr_t H5G_shadow_sync (H5G_entry_t *ent);
-H5G_entry_t *H5G_shadow_open (H5F_t *f, H5G_entry_t *dir,
+H5G_entry_t *H5G_shadow_open (H5F_t *f, H5G_entry_t *grp,
H5G_entry_t *ent);
herr_t H5G_shadow_close (H5F_t *f, H5G_entry_t *ent);
hbool_t H5G_shadow_p (H5G_entry_t *ent);
@@ -170,7 +180,7 @@ herr_t H5G_shadow_assoc_node (H5F_t *f, H5G_node_t *sym,
H5G_shadow_t *H5G_shadow_list (H5F_t *f, haddr_t stab_header_addr);
herr_t H5G_shadow_move (H5F_t *f, H5G_shadow_t *shadow,
const char *new_name, H5G_entry_t *new_entry,
- haddr_t dir_addr);
+ haddr_t grp_addr);
/*
* Functions that understand symbol table entries.
diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h
index 79666e7..4641d90 100644
--- a/src/H5Gprivate.h
+++ b/src/H5Gprivate.h
@@ -82,14 +82,15 @@ typedef struct H5G_entry_t H5G_entry_t;
* Library prototypes... These are the ones that other packages routinely
* call.
*/
-H5G_entry_t *H5G_mkdir (H5F_t *f, const char *name, size_t size_hint);
-herr_t H5G_pushd (H5F_t *f, const char *name);
-herr_t H5G_popd (H5F_t *f);
+H5G_entry_t *H5G_new (H5F_t *f, const char *name, size_t size_hint);
+herr_t H5G_set (H5F_t *f, const char *name);
+herr_t H5G_push (H5F_t *f, const char *name);
+herr_t H5G_pop (H5F_t *f);
H5G_entry_t *H5G_create (H5F_t *f, const char *name, size_t ohdr_hint);
H5G_entry_t *H5G_open (H5F_t *f, const char *name);
herr_t H5G_close (H5F_t *f, H5G_entry_t *ent);
-herr_t H5G_find (H5F_t *f, H5G_entry_t *cwd, H5G_entry_t *dir_ent,
- const char *name, H5G_entry_t *ent);
+herr_t H5G_find (H5F_t *f, const char *name, H5G_entry_t *grp_ent,
+ H5G_entry_t *ent);
herr_t H5G_ent_encode (H5F_t *f, uint8 **pp, H5G_entry_t *ent);
herr_t H5G_ent_decode (H5F_t *f, uint8 **pp, H5G_entry_t *ent);
diff --git a/src/H5Gpublic.h b/src/H5Gpublic.h
index 049c823..e546e6d 100644
--- a/src/H5Gpublic.h
+++ b/src/H5Gpublic.h
@@ -19,15 +19,19 @@
#define _H5Gpublic_H
/* Public headers needed by this file */
+#include <sys/types.h>
#include <H5public.h>
-
-/* Default root directory size */
-#define H5G_DEFAULT_ROOT SIZE 256
+#include <H5Apublic.h>
#ifdef __cplusplus
extern "C" {
#endif
+herr_t H5Gnew (hid_t file, const char *name, size_t size_hint);
+herr_t H5Gset (hid_t file, const char *name);
+herr_t H5Gpush (hid_t file, const char *name);
+herr_t H5Gpop (hid_t file);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/H5Gshad.c b/src/H5Gshad.c
index 9bf80d8..875f880 100644
--- a/src/H5Gshad.c
+++ b/src/H5Gshad.c
@@ -29,7 +29,7 @@
static hbool_t interface_initialize_g = FALSE;
typedef struct H5G_hash_t {
- haddr_t dir_addr;
+ haddr_t grp_addr;
H5G_shadow_t *head;
struct H5G_hash_t *next;
struct H5G_hash_t *prev;
@@ -81,15 +81,15 @@ H5G_shadow_check (H5F_t *f)
shadow_error = TRUE;
}
- /* Valid directory addresses */
- if (shadow->dir_addr<0 || (shadow->dir_addr==0 && idx!=0)) {
- fprintf (stderr, "dir_addr=%lu, ",
- (unsigned long)(shadow->dir_addr));
+ /* Valid group addresses */
+ if (shadow->grp_addr<0 || (shadow->grp_addr==0 && idx!=0)) {
+ fprintf (stderr, "grp_addr=%lu, ",
+ (unsigned long)(shadow->grp_addr));
shadow_error = TRUE;
- } else if (shadow->dir_addr!=hash->dir_addr) {
- fprintf (stderr, "dir_addr=%lu (not %lu), ",
- (unsigned long)(shadow->dir_addr),
- (unsigned long)(hash->dir_addr));
+ } else if (shadow->grp_addr!=hash->grp_addr) {
+ fprintf (stderr, "grp_addr=%lu (not %lu), ",
+ (unsigned long)(shadow->grp_addr),
+ (unsigned long)(hash->grp_addr));
}
/* Linked to symbol table entry */
@@ -107,9 +107,9 @@ H5G_shadow_check (H5F_t *f)
/* If an error occurred then print other info */
if (shadow_error) {
- fprintf (stderr, "idx=%u, shadow=0x%08lx, dir_addr=%lu\n",
+ fprintf (stderr, "idx=%u, shadow=0x%08lx, grp_addr=%lu\n",
idx, (unsigned long)shadow,
- (unsigned long)(shadow->dir_addr));
+ (unsigned long)(shadow->grp_addr));
nerrors++;
}
}
@@ -247,7 +247,7 @@ H5G_shadow_sync (H5G_entry_t *ent)
* Function: H5G_shadow_list
*
* Purpose: Returns a doubly linked list of shadows for the symbol
- * table whose header address is DIR_ADDR.
+ * table whose header address is GRP_ADDR.
*
* Return: Success: Ptr shadow list or null.
*
@@ -261,15 +261,15 @@ H5G_shadow_sync (H5G_entry_t *ent)
*-------------------------------------------------------------------------
*/
H5G_shadow_t *
-H5G_shadow_list (H5F_t *f, haddr_t dir_addr)
+H5G_shadow_list (H5F_t *f, haddr_t grp_addr)
{
- uintn idx = dir_addr % f->shared->nshadows;
+ uintn idx = grp_addr % f->shared->nshadows;
H5G_hash_t *bucket = NULL;
FUNC_ENTER (H5G_shadows, NULL, NULL);
for (bucket=f->shared->shadow[idx]; bucket; bucket=bucket->next) {
- if (bucket->dir_addr==dir_addr) {
+ if (bucket->grp_addr==grp_addr) {
HRETURN (bucket->head);
}
}
@@ -317,7 +317,7 @@ H5G_shadow_assoc_node (H5F_t *f, H5G_node_t *sym, H5G_ac_ud1_t *ac_udata)
H5G_shadow_check (f);
#endif
- if ((shadow=H5G_shadow_list (f, ac_udata->dir_addr))) {
+ if ((shadow=H5G_shadow_list (f, ac_udata->grp_addr))) {
heap_addr = ac_udata->heap_addr;
while (i<sym->nsyms && shadow) {
@@ -352,7 +352,7 @@ H5G_shadow_assoc_node (H5F_t *f, H5G_node_t *sym, H5G_ac_ud1_t *ac_udata)
* object, open the object (again) and return a handle
* to it.
*
- * DIR can be the null pointer if `ent' is the root entry.
+ * GRP can be the null pointer if `ent' is the root entry.
*
* Return: Success: Handle to open object
*
@@ -366,7 +366,7 @@ H5G_shadow_assoc_node (H5F_t *f, H5G_node_t *sym, H5G_ac_ud1_t *ac_udata)
*-------------------------------------------------------------------------
*/
H5G_entry_t *
-H5G_shadow_open (H5F_t *f, H5G_entry_t *dir, H5G_entry_t *ent)
+H5G_shadow_open (H5F_t *f, H5G_entry_t *grp, H5G_entry_t *ent)
{
H5G_shadow_t *shadow = NULL;
H5O_stab_t stab;
@@ -376,15 +376,15 @@ H5G_shadow_open (H5F_t *f, H5G_entry_t *dir, H5G_entry_t *ent)
uintn idx;
H5O_name_t name_mesg = {NULL};
H5G_entry_t *ret_value = NULL;
- haddr_t dir_addr;
+ haddr_t grp_addr;
FUNC_ENTER (H5G_shadow_open, NULL, NULL);
/* check args */
assert (f);
- assert (ent==f->shared->root_sym || dir);
+ assert (ent==f->shared->root_sym || grp);
assert (ent);
- dir_addr = dir ? dir->header : 0;
+ grp_addr = grp ? grp->header : 0;
if ((shadow = ent->shadow)) {
/*
@@ -396,7 +396,7 @@ H5G_shadow_open (H5F_t *f, H5G_entry_t *dir, H5G_entry_t *ent)
shadow = H5MM_xcalloc (1, sizeof(H5G_shadow_t));
- if (ent==f->shared->root_sym && 0==dir_addr) {
+ if (ent==f->shared->root_sym && 0==grp_addr) {
/*
* We're opening the root entry.
*/
@@ -411,7 +411,7 @@ H5G_shadow_open (H5F_t *f, H5G_entry_t *dir, H5G_entry_t *ent)
/*
* Some entry other than the root.
*/
- if (NULL==H5O_read (f, NO_ADDR, dir, H5O_STAB, 0, &stab)) {
+ if (NULL==H5O_read (f, NO_ADDR, grp, H5O_STAB, 0, &stab)) {
HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, NULL);
}
if (NULL==(s=H5H_peek (f, stab.heap_addr, ent->name_off))) {
@@ -428,18 +428,18 @@ H5G_shadow_open (H5F_t *f, H5G_entry_t *dir, H5G_entry_t *ent)
shadow->nrefs = 1;
shadow->entry = *ent;
shadow->entry.dirty = FALSE;
- shadow->dir_addr = dir_addr;
+ shadow->grp_addr = grp_addr;
/*
* Link it into the shadow heap
*/
- idx = dir_addr % f->shared->nshadows;
+ idx = grp_addr % f->shared->nshadows;
for (hash=f->shared->shadow[idx]; hash; hash=hash->next) {
- if (hash->dir_addr==dir_addr) break;
+ if (hash->grp_addr==grp_addr) break;
}
if (!hash) {
hash = H5MM_xcalloc (1, sizeof(H5G_hash_t));
- hash->dir_addr = dir_addr;
+ hash->grp_addr = grp_addr;
hash->next = f->shared->shadow[idx];
f->shared->shadow[idx] = hash;
if (hash->next) hash->next->prev = hash;
@@ -524,7 +524,7 @@ H5G_shadow_close (H5F_t *f, H5G_entry_t *ent)
/* clean the shadow */
if (1==shadow->nrefs && ent->dirty) {
if (!shadow->main &&
- NULL==H5G_stab_find (f, shadow->dir_addr, NULL, shadow->name)) {
+ NULL==H5G_stab_find (f, shadow->grp_addr, NULL, shadow->name)) {
HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL);
}
assert (shadow->main);
@@ -540,9 +540,9 @@ H5G_shadow_close (H5F_t *f, H5G_entry_t *ent)
H5G_shadow_dissociate (ent);
/* find symtabs shadow list */
- idx = shadow->dir_addr % f->shared->nshadows;
+ idx = shadow->grp_addr % f->shared->nshadows;
for (hash=f->shared->shadow[idx]; hash; hash=hash->next) {
- if (hash->dir_addr==shadow->dir_addr) break;
+ if (hash->grp_addr==shadow->grp_addr) break;
}
assert (hash);
@@ -577,7 +577,7 @@ H5G_shadow_close (H5F_t *f, H5G_entry_t *ent)
* Function: H5G_shadow_move
*
* Purpose: Moves the SHADOW for some entry to correspond to a
- * NEW_ENTRY. The DIR_ADDR is the address for the directory
+ * NEW_ENTRY. The GRP_ADDR is the address for the group
* which contains NEW_ENTRY.
*
* Return: Success: SUCCEED
@@ -593,7 +593,7 @@ H5G_shadow_close (H5F_t *f, H5G_entry_t *ent)
*/
herr_t
H5G_shadow_move (H5F_t *f, H5G_shadow_t *shadow, const char *new_name,
- H5G_entry_t *new_entry, haddr_t dir_addr)
+ H5G_entry_t *new_entry, haddr_t grp_addr)
{
H5G_hash_t *hash;
uintn idx;
@@ -602,29 +602,29 @@ H5G_shadow_move (H5F_t *f, H5G_shadow_t *shadow, const char *new_name,
assert (shadow);
assert (new_entry);
- assert (dir_addr>0);
+ assert (grp_addr>0);
- if (0==shadow->dir_addr) {
+ if (0==shadow->grp_addr) {
/*
* We're moving the shadow for the root object. This simplifies things
* greatly since it implies that this is the only shadow currently
* defined for the entire file.
*/
- idx = dir_addr % f->shared->nshadows;
+ idx = grp_addr % f->shared->nshadows;
assert (NULL==f->shared->shadow[idx]); /*Nothing at new idx... */
hash = f->shared->shadow[0];
assert (hash); /*..but root idx has something. */
- assert (0==hash->dir_addr); /*..and it's the root something */
+ assert (0==hash->grp_addr); /*..and it's the root something */
assert (NULL==hash->next); /*..and just that */
assert (hash->head==shadow); /*..and exactly that */
/* Move root entry to new hash bucket */
f->shared->shadow[idx] = hash;
f->shared->shadow[0] = NULL;
- hash->dir_addr = dir_addr;
+ hash->grp_addr = grp_addr;
/* Associate SHADOW with NEW_ENTRY */
- shadow->dir_addr = dir_addr;
+ shadow->grp_addr = grp_addr;
shadow->main = new_entry;
new_entry->shadow = shadow;
@@ -636,7 +636,7 @@ H5G_shadow_move (H5F_t *f, H5G_shadow_t *shadow, const char *new_name,
/*
* Other shadows never move.
*/
- assert (shadow->dir_addr==dir_addr);
+ assert (shadow->grp_addr==grp_addr);
shadow->main = new_entry;
new_entry->shadow = shadow;
}
@@ -682,7 +682,7 @@ H5G_shadow_flush (H5F_t *f, hbool_t invalidate)
*/
if (shadow->entry.dirty) {
if (!shadow->main &&
- NULL==H5G_stab_find (f, shadow->dir_addr, NULL,
+ NULL==H5G_stab_find (f, shadow->grp_addr, NULL,
shadow->name)) {
HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL);
}
@@ -698,12 +698,12 @@ H5G_shadow_flush (H5F_t *f, hbool_t invalidate)
* some object before closing the file. Since this is hard to
* debug, we'll be nice and print the names here. We don't know
* the full name, but we'll print the file address (relative to
- * the boot block) of the object header for the directory that
+ * the boot block) of the object header for the group that
* contains the open object.
*/
if (invalidate) {
- fprintf (stderr, "Open object <%lu>/%s",
- (unsigned long)(shadow->dir_addr),
+ fprintf (stderr, "Warning: open object <%lu>/%s",
+ (unsigned long)(shadow->grp_addr),
shadow->name);
if (shadow->nrefs>1) {
fprintf (stderr, " (%d times)", shadow->nrefs);
diff --git a/src/H5Gstab.c b/src/H5Gstab.c
index b600e90..7acaa13 100644
--- a/src/H5Gstab.c
+++ b/src/H5Gstab.c
@@ -87,14 +87,14 @@ H5G_stab_new (H5F_t *f, H5G_entry_t *self, size_t init)
}
/* Create the B-tree */
- if ((stab.btree_addr = H5B_new (f, H5B_SNODE))<0) {
+ if ((stab.btree_addr = H5B_new (f, H5B_SNODE, NULL))<0) {
HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL); /*can't create B-tree*/
}
/*
* Create symbol table object header. It has a zero link count
* since nothing refers to it yet. The link count will be
- * incremented if the object is added to the directory hierarchy.
+ * incremented if the object is added to the group directed graph.
*/
if ((addr = H5O_new (f, 0, 4+2*H5F_SIZEOF_OFFSET(f)))<0) {
HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL); /*can't create header*/
@@ -169,7 +169,7 @@ H5G_stab_find (H5F_t *f, haddr_t addr, H5G_entry_t *self,
udata.operation = H5G_OPER_FIND;
udata.name = name;
udata.heap_addr = stab.heap_addr;
- udata.dir_addr = addr;
+ udata.grp_addr = addr;
udata.node_ptr = NULL;
/* search the B-tree */
@@ -245,7 +245,7 @@ H5G_stab_insert (H5F_t *f, H5G_entry_t *self, const char *name,
udata.operation = H5G_OPER_INSERT;
udata.name = name;
udata.heap_addr = stab.heap_addr;
- udata.dir_addr = self->header;
+ udata.grp_addr = self->header;
udata.entry = *ent;
udata.entry.name_off = -1;
udata.node_ptr = NULL;
@@ -326,7 +326,7 @@ H5G_stab_list (H5F_t *f, H5G_entry_t *self, intn maxentries,
}
udata.entry = entries;
udata.name = names;
- udata.dir_addr = self->header;
+ udata.grp_addr = self->header;
udata.heap_addr = stab.heap_addr;
udata.maxentries = maxentries;
udata.nsyms = 0;
diff --git a/src/H5H.c b/src/H5H.c
index 7724045..64809e4 100644
--- a/src/H5H.c
+++ b/src/H5H.c
@@ -45,14 +45,14 @@ typedef struct H5H_t {
} H5H_t;
/* PRIVATE PROTOTYPES */
-static H5H_t *H5H_load (H5F_t *f, haddr_t addr, void *udata);
+static H5H_t *H5H_load (H5F_t *f, haddr_t addr, void *udata1, void *udata2);
static herr_t H5H_flush (H5F_t *f, hbool_t dest, haddr_t addr, H5H_t *heap);
/*
* H5H inherits cache-like properties from H5AC
*/
static const H5AC_class_t H5AC_HEAP[1] = {{
- (void*(*)(H5F_t*,haddr_t,void*))H5H_load,
+ (void*(*)(H5F_t*,haddr_t,void*,void*))H5H_load,
(herr_t(*)(H5F_t*,hbool_t,haddr_t,void*))H5H_flush,
}};
@@ -161,7 +161,7 @@ H5H_new (H5F_t *f, H5H_type_t heap_type, size_t size_hint)
*-------------------------------------------------------------------------
*/
static H5H_t *
-H5H_load (H5F_t *f, haddr_t addr, void *udata)
+H5H_load (H5F_t *f, haddr_t addr, void *udata1, void *udata2)
{
uint8 hdr[20], *p;
H5H_t *heap=NULL;
@@ -175,7 +175,8 @@ H5H_load (H5F_t *f, haddr_t addr, void *udata)
assert (f);
assert (addr>0);
assert (H5H_SIZEOF_HDR(f) <= sizeof hdr);
- assert (!udata);
+ assert (!udata1);
+ assert (!udata2);
if (H5F_block_read (f, addr, H5H_SIZEOF_HDR(f), hdr)<0) {
HRETURN_ERROR (H5E_HEAP, H5E_READERROR, NULL);
@@ -395,7 +396,7 @@ H5H_read (H5F_t *f, haddr_t addr, off_t offset, size_t size, void *buf)
assert (addr>0);
assert (offset>=0);
- if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL))) {
+ if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL, NULL))) {
HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, NULL);
}
assert (offset<heap->mem_alloc);
@@ -455,7 +456,7 @@ H5H_peek (H5F_t *f, haddr_t addr, off_t offset)
assert (addr>0);
assert (offset>=0);
- if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL))) {
+ if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL, NULL))) {
HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, NULL);
}
assert (offset<heap->mem_alloc);
@@ -536,7 +537,7 @@ H5H_insert (H5F_t *f, haddr_t addr, size_t buf_size, const void *buf)
need = buf_size;
H5H_ALIGN (need);
- if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL))) {
+ if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL, NULL))) {
HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, FAIL);
}
heap->dirty += 1;
@@ -686,7 +687,7 @@ H5H_write (H5F_t *f, haddr_t addr, off_t offset, size_t size,
assert (offset>=0);
assert (buf);
- if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL))) {
+ if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL, NULL))) {
HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, FAIL);
}
assert (offset<heap->mem_alloc);
@@ -748,7 +749,7 @@ H5H_remove (H5F_t *f, haddr_t addr, off_t offset, size_t size)
assert (offset>=0);
assert (size>0);
- if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL))) {
+ if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL, NULL))) {
HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, FAIL);
}
assert (offset<heap->mem_alloc);
@@ -864,7 +865,7 @@ H5H_debug (H5F_t *f, haddr_t addr, FILE *stream, intn indent, intn fwidth)
assert (indent>=0);
assert (fwidth>=0);
- if (NULL==(h=H5AC_find (f, H5AC_HEAP, addr, NULL))) {
+ if (NULL==(h=H5AC_find (f, H5AC_HEAP, addr, NULL, NULL))) {
HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, FAIL);
}
diff --git a/src/H5O.c b/src/H5O.c
index 24edf84..9130de3 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -26,7 +26,7 @@
/* PRIVATE PROTOTYPES */
static herr_t H5O_flush (H5F_t *f, hbool_t destroy, haddr_t addr, H5O_t *oh);
-static H5O_t *H5O_load (H5F_t *f, haddr_t addr, void *_data);
+static H5O_t *H5O_load (H5F_t *f, haddr_t addr, void *_udata1, void *_udata2);
static intn H5O_find_in_ohdr (H5F_t *f, haddr_t addr,
const H5O_class_t **type_p, intn sequence);
static intn H5O_alloc (H5F_t *f, H5O_t *oh, const H5O_class_t *type,
@@ -36,7 +36,7 @@ static intn H5O_alloc_new_chunk (H5F_t *f, H5O_t *oh, size_t size);
/* H5O inherits cache-like properties from H5AC */
static const H5AC_class_t H5AC_OHDR[1] = {{
- (void*(*)(H5F_t*,haddr_t,void*))H5O_load,
+ (void*(*)(H5F_t*,haddr_t,void*,void*))H5O_load,
(herr_t(*)(H5F_t*,hbool_t,haddr_t,void*))H5O_flush,
}};
@@ -45,17 +45,17 @@ static intn interface_initialize_g = FALSE;
/* ID to type mapping */
static const H5O_class_t *const message_type_g[] = {
- H5O_NULL, /*0x0000 Null */
- H5O_SIM_DIM, /*0x0001 Simple dimensionality */
+ H5O_NULL, /*0x0000 Null */
+ H5O_SIM_DIM, /*0x0001 Simple dimensionality */
NULL, /*0x0002 Data space (fiber bundle?) */
- H5O_SIM_DTYPE, /*0x0003 Simple data type */
+ H5O_SIM_DTYPE, /*0x0003 Simple data type */
NULL, /*0x0004 Compound data type */
- H5O_STD_STORE, /*0x0005 Data storage -- standard object */
+ H5O_STD_STORE, /*0x0005 Data storage -- standard object */
NULL, /*0x0006 Data storage -- compact object */
NULL, /*0x0007 Data storage -- external object */
- NULL, /*0x0008 Data storage -- indexed object */
- NULL, /*0x0009 Data storage -- chunked object */
- NULL, /*0x000A Data storage -- sparse object */
+ H5O_ISTORE, /*0x0008 Data storage -- indexed object */
+ NULL, /*0x0009 Not assigned */
+ NULL, /*0x000A Not assigned */
NULL, /*0x000B Data storage -- compressed object */
NULL, /*0x000C Attribute list */
H5O_NAME, /*0x000D Object name */
@@ -105,7 +105,7 @@ H5O_new (H5F_t *f, intn nlink, size_t size_hint)
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL);
}
- /* allocate the object header in fill in header fields */
+ /* allocate the object header and fill in header fields */
oh = H5MM_xcalloc (1, sizeof(H5O_t));
oh->dirty = TRUE;
oh->version = H5O_VERSION;
@@ -165,7 +165,7 @@ H5O_new (H5F_t *f, intn nlink, size_t size_hint)
*-------------------------------------------------------------------------
*/
static H5O_t *
-H5O_load (H5F_t *f, haddr_t addr, void *_data)
+H5O_load (H5F_t *f, haddr_t addr, void *_udata1, void *_udata2)
{
H5O_t *oh = NULL;
H5O_t *ret_value = (void*)1; /*kludge for HGOTO_ERROR*/
@@ -182,7 +182,8 @@ H5O_load (H5F_t *f, haddr_t addr, void *_data)
/* check args */
assert (f);
assert (addr>=0);
- assert (!_data);
+ assert (!_udata1);
+ assert (!_udata2);
/* allocate ohdr and init chunk list */
oh = H5MM_xcalloc (1, sizeof(H5O_t));
@@ -454,7 +455,7 @@ H5O_flush (H5F_t *f, hbool_t destroy, haddr_t addr, H5O_t *oh)
* Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 12 1997
*
* Modifications:
@@ -513,7 +514,7 @@ H5O_link (H5F_t *f, H5G_entry_t *ent, intn adjust)
addr = H5G_ent_addr (ent);
/* get header */
- if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL))) {
+ if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL, NULL))) {
HRETURN_ERROR (H5E_OHDR, H5E_CANTLOAD, FAIL);
}
@@ -600,7 +601,7 @@ H5O_read (H5F_t *f, haddr_t addr, H5G_entry_t *ent,
#endif
/* copy the message to the user-supplied buffer */
- if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL))) {
+ if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL, NULL))) {
HRETURN_ERROR (H5E_OHDR, H5E_CANTLOAD, NULL);
}
retval = (type->copy)(oh->mesg[idx].native, mesg);
@@ -643,7 +644,7 @@ H5O_find_in_ohdr (H5F_t *f, haddr_t addr, const H5O_class_t **type_p,
assert (type_p);
/* load the object header */
- if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL))) {
+ if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL, NULL))) {
HRETURN_ERROR (H5E_OHDR, H5E_CANTLOAD, FAIL);
}
@@ -710,7 +711,7 @@ H5O_peek (H5F_t *f, haddr_t addr, const H5O_class_t *type, intn sequence)
if ((idx = H5O_find_in_ohdr (f, addr, &type, sequence))<0) {
HRETURN_ERROR (H5E_OHDR, H5E_NOTFOUND, NULL);
}
- if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL))) {
+ if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL, NULL))) {
HRETURN_ERROR (H5E_OHDR, H5E_CANTLOAD, NULL);
}
@@ -767,7 +768,7 @@ H5O_modify (H5F_t *f, haddr_t addr, H5G_entry_t *ent,
assert (mesg);
if (addr<=0) addr = H5G_ent_addr (ent);
- if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL))) {
+ if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL, NULL))) {
HRETURN_ERROR (H5E_OHDR, H5E_CANTLOAD, FAIL);
}
@@ -842,7 +843,7 @@ H5O_modify (H5F_t *f, haddr_t addr, H5G_entry_t *ent,
* Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 28 1997
*
* Modifications:
@@ -865,7 +866,7 @@ H5O_remove (H5F_t *f, haddr_t addr, H5G_entry_t *ent,
if (addr<=0) addr = H5G_ent_addr (ent);
/* load the object header */
- if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL))) {
+ if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL, NULL))) {
HRETURN_ERROR (H5E_OHDR, H5E_CANTLOAD, FAIL);
}
@@ -1309,7 +1310,7 @@ H5O_debug (H5F_t *f, haddr_t addr, FILE *stream, intn indent, intn fwidth)
assert (indent>=0);
assert (fwidth>=0);
- if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL))) {
+ if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL, NULL))) {
HRETURN_ERROR (H5E_OHDR, H5E_CANTLOAD, FAIL);
}
diff --git a/src/H5Oistore.c b/src/H5Oistore.c
new file mode 100644
index 0000000..1ed275e
--- /dev/null
+++ b/src/H5Oistore.c
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 1997 NCSA
+ * All rights reserved.
+ *
+ * Programmer: Robb Matzke <matzke@llnl.gov>
+ * Wednesday, October 8, 1997
+ */
+#include <H5private.h>
+#include <H5Eprivate.h>
+#include <H5MMprivate.h>
+#include <H5Oprivate.h>
+
+#define PABLO_MASK H5O_istore_mask
+
+/* PRIVATE PROTOTYPES */
+static void *H5O_istore_decode (H5F_t *f, size_t raw_size, const uint8 *p);
+static herr_t H5O_istore_encode (H5F_t *f, size_t size, uint8 *p,
+ const void *_mesg);
+static void *H5O_istore_copy (const void *_mesg, void *_dest);
+static size_t H5O_istore_size (H5F_t *f, const void *_mesg);
+static herr_t H5O_istore_debug (H5F_t *f, const void *_mesg, FILE *stream,
+ intn indent, intn fwidth);
+
+/* This message derives from H5O */
+const H5O_class_t H5O_ISTORE[1] = {{
+ H5O_ISTORE_ID, /*message id number */
+ "istore", /*message name for debugging */
+ sizeof(H5O_istore_t), /*native message size */
+ H5G_NOTHING_CACHED, /*symtab entry `type' field */
+ H5O_istore_decode, /*decode message */
+ H5O_istore_encode, /*encode message */
+ NULL, /*get messsage from stab entry */
+ NULL, /*put message into stab entry */
+ H5O_istore_copy, /*copy the native value */
+ H5O_istore_size, /*size of message on disk */
+ NULL, /*reset method */
+ H5O_istore_debug, /*debug the message */
+}};
+
+/* Is the interface initialized? */
+static hbool_t interface_initialize_g = FALSE;
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_istore_decode
+ *
+ * Purpose: Decode an indexed storage message and return a pointer to a
+ * new one created with malloc().
+ *
+ * Return: Success: Ptr to new message in native order.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, October 8, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_istore_decode (H5F_t *f, size_t raw_size, const uint8 *p)
+{
+ H5O_istore_t *mesg = NULL;
+ intn i;
+
+ FUNC_ENTER (H5O_istore_decode, NULL, NULL);
+
+ /* check args */
+ assert (f);
+ assert (p);
+
+ /* decode */
+ mesg = H5MM_xcalloc (1, sizeof(H5O_istore_t));
+ H5F_decode_offset (f, p, mesg->btree_addr);
+ mesg->ndims = *p++;
+ assert (raw_size == H5O_istore_size (f, mesg));
+
+ /* Reserved bytes */
+ p += 7;
+
+ /* Read the min_corner, max_corner, and alignment values */
+ for (i=0; i<mesg->ndims; i++) {
+ UINT32DECODE (p, mesg->alignment[i]);
+ }
+
+ FUNC_LEAVE (mesg);
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_istore_encode
+ *
+ * Purpose: Encodes a message.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, October 8, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_istore_encode (H5F_t *f, size_t raw_size, uint8 *p, const void *_mesg)
+{
+ const H5O_istore_t *mesg = (const H5O_istore_t *)_mesg;
+ int i;
+
+ FUNC_ENTER (H5O_istore_encode, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (mesg);
+ assert (mesg->ndims>0 && mesg->ndims<=H5O_ISTORE_NDIMS);
+ assert (raw_size == H5O_istore_size (f, _mesg));
+ assert (p);
+
+ /* encode B-tree offset */
+ H5F_encode_offset (f, p, mesg->btree_addr);
+
+ /* number of dimensions */
+ *p++ = mesg->ndims;
+
+ /* reserved bytes should be zero */
+ for (i=0; i<7; i++) *p++ = 0;
+
+ /* min_corner, max_corner, and alignment */
+ for (i=0; i<mesg->ndims; i++) {
+ UINT32ENCODE (p, mesg->alignment[i]);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_istore_copy
+ *
+ * Purpose: Copies a message from _MESG to _DEST, allocating _DEST if
+ * necessary.
+ *
+ * Return: Success: Ptr to _DEST
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, October 8, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_istore_copy (const void *_mesg, void *_dest)
+{
+ const H5O_istore_t *mesg = (const H5O_istore_t *)_mesg;
+ H5O_istore_t *dest = (H5O_istore_t *)_dest;
+
+ FUNC_ENTER (H5O_istore_copy, NULL, NULL);
+
+ /* check args */
+ assert (mesg);
+ if (!dest) dest = H5MM_xcalloc (1, sizeof(H5O_istore_t));
+
+ /* copy */
+ *dest = *mesg;
+
+ FUNC_LEAVE ((void*)dest);
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_istore_size
+ *
+ * Purpose: Returns the size of the raw message in bytes not counting the
+ * message type or size fields, but only the data fields. This
+ * function doesn't take into account message alignment.
+ *
+ * Return: Success: Message data size in bytes
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, October 8, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static size_t
+H5O_istore_size (H5F_t *f, const void *_mesg)
+{
+ const H5O_istore_t *mesg = (const H5O_istore_t *)_mesg;
+ size_t ret_value = FAIL;
+
+ FUNC_ENTER (H5O_istore_size, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (mesg);
+ assert (mesg->ndims>0 && mesg->ndims<=H5O_ISTORE_NDIMS);
+
+ ret_value = H5F_SIZEOF_OFFSET (f) + /* B-tree address */
+ 1 + /* max dimension index */
+ 7 + /* reserved bytes */
+ mesg->ndims * 4; /* alignment */
+
+ FUNC_LEAVE (ret_value);
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_istore_debug
+ *
+ * Purpose: Prints debugging info for a message.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, October 8, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_istore_debug (H5F_t *f, const void *_mesg, FILE *stream, intn indent,
+ intn fwidth)
+{
+ const H5O_istore_t *mesg = (const H5O_istore_t *)_mesg;
+ intn i;
+
+ FUNC_ENTER (H5O_istore_debug, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (mesg);
+ assert (stream);
+ assert (indent>=0);
+ assert (fwidth>=0);
+
+ fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
+ "B-tree address:",
+ (unsigned long)(mesg->btree_addr));
+ fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
+ "Number of dimensions:",
+ (unsigned long)(mesg->ndims));
+
+ /* Alignment */
+ fprintf (stream, "%*s%-*s {", indent, "", fwidth,
+ "Alignment:");
+ for (i=0; i<mesg->ndims; i++) {
+ fprintf (stream, "%s%lu", i?", ":"",
+ (unsigned long)(mesg->alignment[i]));
+ }
+ fprintf (stream, "}\n");
+
+ FUNC_LEAVE (SUCCEED);
+}
+
diff --git a/src/H5Oname.c b/src/H5Oname.c
index 7d76fa5..9d8aa09 100644
--- a/src/H5Oname.c
+++ b/src/H5Oname.c
@@ -6,7 +6,7 @@
*
* Created: H5Oname.c
* Aug 12 1997
- * Robb Matzke <robb@maya.nuance.com>
+ * Robb Matzke <matzke@llnl.gov>
*
* Purpose: Object name message.
*
@@ -62,7 +62,7 @@ static hbool_t interface_initialize_g = FALSE;
* Failure: NULL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 12 1997
*
* Modifications:
@@ -101,7 +101,7 @@ H5O_name_decode (H5F_t *f, size_t raw_size, const uint8 *p)
* Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 12 1997
*
* Modifications:
@@ -144,7 +144,7 @@ H5O_name_encode (H5F_t *f, size_t raw_size, uint8 *p, const void *_mesg)
* Failure: NULL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 12 1997
*
* Modifications:
@@ -184,7 +184,7 @@ H5O_name_copy (const void *_mesg, void *_dest)
* Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 12 1997
*
* Modifications:
@@ -219,7 +219,7 @@ H5O_name_size (H5F_t *f, const void *_mesg)
* Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 12 1997
*
* Modifications:
@@ -253,7 +253,7 @@ H5O_name_reset (void *_mesg)
* Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 12 1997
*
* Modifications:
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index 94dd764..c4ad1cb 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -115,10 +115,23 @@ typedef h5_atomic_type_t H5O_sim_dtype_t;
#define H5O_STD_STORE_ID 0x0005
extern const H5O_class_t H5O_STD_STORE[1];
-typedef struct H5O_std_store {
- haddr_t off;
- haddr_t len;
- } H5O_std_store_t;
+typedef struct H5O_std_store_t {
+ haddr_t off;
+ haddr_t len;
+} H5O_std_store_t;
+
+/*
+ * Indexed Data Storage message.
+ */
+#define H5O_ISTORE_ID 0x0008
+#define H5O_ISTORE_NDIMS 32
+extern const H5O_class_t H5O_ISTORE[1];
+
+typedef struct H5O_istore_t {
+ haddr_t btree_addr; /*file address of B-tree */
+ uintn ndims; /*num dimensions in stored data */
+ size_t alignment[H5O_ISTORE_NDIMS]; /*algn in logical space */
+} H5O_istore_t;
/*
* Object name message.
diff --git a/src/H5Osdtyp.c b/src/H5Osdtyp.c
index 367af17..0800e30 100644
--- a/src/H5Osdtyp.c
+++ b/src/H5Osdtyp.c
@@ -205,7 +205,7 @@ H5O_sim_dtype_fast (const H5G_cache_t *cache, void *mesg)
method is required for simple datatypes, as they can be cached in the
symbol-table entry)
--------------------------------------------------------------------------*/
-static herr_t
+static hbool_t
H5O_sim_dtype_cache (H5G_type_t *cache_type, H5G_cache_t *cache,
const void *mesg)
{
diff --git a/src/H5config.h.in b/src/H5config.h.in
index 20da7a1..07a0615 100644
--- a/src/H5config.h.in
+++ b/src/H5config.h.in
@@ -1,5 +1,11 @@
/* src/H5config.h.in. Generated automatically from configure.in by autoheader. */
+/* Define to empty if the keyword does not work. */
+#undef const
+
+/* Define as __inline if that's what the C compiler calls it. */
+#undef inline
+
/* Define to `long' if <sys/types.h> doesn't define. */
#undef off_t
@@ -13,6 +19,12 @@
byte first (like Motorola and SPARC, unlike Intel and VAX). */
#undef WORDS_BIGENDIAN
+/* Define if the __attribute__(()) extension is present */
+/* #define HAVE_ATTRIBUTE */
+
+/* Define if the compiler understands the __FUNCTION__ keyword. */
+/* #define HAVE_FUNCTION */
+
/* The number of bytes in a double. */
#undef SIZEOF_DOUBLE
diff --git a/src/H5private.h b/src/H5private.h
index f13ff59..58db166 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -63,8 +63,19 @@
#define MACIO 2
#define WINNTIO 3
#define PAGEBUFIO 4
-#define FILELIB POSIXBUFIO
+#ifndef FILELIB
+# define FILELIB POSIXBUFIO
+#endif
+
+/* Does the compiler support the __attribute__(()) syntax? */
+#ifndef HAVE_ATTRIBUTE
+# define __attribute__(X) /*void*/
+#endif
+/* Does the compiler expand __FUNCTION__? */
+#ifndef HAVE_FUNCTION
+# define __FUNCTION__ "NoFuntionName"
+#endif
/* number of members in an array */
#ifndef NELMTS
@@ -359,6 +370,7 @@ typedef off_t haddr_t;
/*
* And now for a couple non-Posix functions...
*/
+extern char *strdup (const char *s);
#define HDstrdup(S) strdup(S)
/*-------------------------------------------------------------------------
diff --git a/src/Makefile.in b/src/Makefile.in
index cebf3c1..8776376 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -14,10 +14,10 @@ LIB=libhdf5.a
PROGS=debug
# Source and object files for the library (lexicographically)...
-LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5C.c H5D.c H5Dconv.c H5E.c H5F.c H5G.c \
- H5Gent.c H5Gnode.c H5Gshad.c H5Gstab.c H5H.c H5M.c H5MF.c H5MM.c \
- H5O.c H5Ocont.c H5Oname.c H5Onull.c H5Osdtyp.c H5Osdim.c H5Ostab.c \
- H5Ostdst.c H5P.c H5T.c
+LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5C.c H5D.c H5Dconv.c H5E.c H5F.c H5Fistore.c \
+ H5G.c H5Gent.c H5Gnode.c H5Gshad.c H5Gstab.c H5H.c H5M.c H5MF.c \
+ H5MM.c H5O.c H5Ocont.c H5Oistore.c H5Oname.c H5Onull.c H5Osdtyp.c \
+ H5Osdim.c H5Ostab.c H5Ostdst.c H5P.c H5T.c H5V.c
LIB_OBJ=$(LIB_SRC:.c=.o)
@@ -35,7 +35,7 @@ PUB_HDR=H5public.h H5Apublic.h H5ACpublic.h H5Bpublic.h H5Cpublic.h \
PRIVATE_HDR=H5private.h H5Aprivate.h H5ACprivate.h H5Bprivate.h \
H5Cprivate.h H5Dprivate.h H5Eprivate.h H5Fprivate.h H5Gprivate.h \
H5Gpkg.h H5Hprivate.h H5Mprivate.h H5MFprivate.h H5MMprivate.h \
- H5Oprivate.h H5Pprivate.h H5Tprivate.h
+ H5Oprivate.h H5Pprivate.h H5Tprivate.h H5Vprivate.h
# How to build the programs...
debug: debug.o $(LIB)