From 412e5606a83551629d2a6b15bc89b55d2de6081f Mon Sep 17 00:00:00 2001 From: Robb Matzke Date: Fri, 1 Aug 1997 15:20:33 -0500 Subject: [svn-r6] Added the next layer of symbol table functions. Given a symbol table name, they operate to query or modify the corresponding symbol table entry. They don't understand directory hierarchies (that's the next layer up). Since the object header stuff isn't done yet, they call four stub functions that all return failure: not_implemented_yet__create_object_header() not_implemented_yet__insert_symtab_message() not_implemented_yet__get_symtab_message() not_implemented_yet__update_symtab_message() The interface is: haddr_t H5G_new (file, initial_heap_size) Creates a new symbol table. haddr_t H5G_find (file, symtab_addr, symbol_name, *entry) Returns a symbol table entry given the name. herr_t H5G_modify (file, symtab_addr, symbol_name, *entry) Modifies the symbol table entry for the specified name. herr_t H5G_insert (file, symtab_addr, symbol_name, *entry) Inserts a new name and symbol table entry pair. intn H5G_list (file, symtab_addr, maxentries, names[], entries[]) Returns a list of all names and symbol table entries. --- src/H5Bprivate.h | 2 +- src/H5G.c | 248 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/H5Gnode.c | 98 +++++++++++++++------- src/H5Gprivate.h | 32 +++++-- 4 files changed, 341 insertions(+), 39 deletions(-) diff --git a/src/H5Bprivate.h b/src/H5Bprivate.h index b6e31a8..3a029e4 100644 --- a/src/H5Bprivate.h +++ b/src/H5Bprivate.h @@ -19,7 +19,7 @@ #include "H5Bproto.h" /*API prototypes */ - +#include "H5Fprivate.h" #define H5B_MAGIC "TREE" /* tree node magic number */ #define H5B_HDR_SIZE(F) (8+2*H5F_SIZEOF_OFFSET(F)) diff --git a/src/H5G.c b/src/H5G.c index 1af38f3..3c1f21a 100644 --- a/src/H5G.c +++ b/src/H5G.c @@ -18,13 +18,256 @@ #include "hdf5.h" +#define H5G_INIT_HEAP 8192 + /* Packages needed by this file... */ +#include "H5Bprivate.h" #include "H5Gprivate.h" +#include "H5Hprivate.h" +#include "H5MMprivate.h" /* PRIVATE PROTOTYPES */ /*------------------------------------------------------------------------- + * Function: H5G_new + * + * Purpose: Creates a new empty symbol table (object header, name heap, + * and B-tree). The caller can specify an initial size for the + * name heap. If no size is specified then a default heap is + * created when the first symbol is added to the table. + * + * The B-tree is created when the first symbol is added to + * the table. + * + * In order for the B-tree to operate correctly, the first + * item in the heap is the empty string, and must appear at + * heap offset zero. + * + * Return: Success: Address of new symbol table. + * + * Failure: -1 + * + * Programmer: Robb Matzke + * robb@maya.nuance.com + * Aug 1 1997 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +haddr_t +H5G_new (hdf5_file_t *f, size_t init) +{ + haddr_t addr; /*symtab object header */ + haddr_t heap; /*private heap */ + off_t name; /*offset of "" name */ + + /* Create symbol table private heap */ + if (init>0) { + if ((heap = H5H_new (f, init))<0) return -1; + if ((name = H5H_insert (f, heap, 1, "")<0)) return -1; + assert (0==name); /*or B-tree's won't work*/ + } else { + heap = 0; /*we'll create it later*/ + } + + /* Create symbol table object header */ + addr = not_implemented_yet__create_object_header(); + if (addr<0) return -1; + + /* Insert the heap and B-tree addresses */ + not_implemented_yet__insert_symtab_message (f, addr, heap, 0); + + return addr; +} + + +/*------------------------------------------------------------------------- + * Function: H5G_find + * + * Purpose: Finds a symbol named NAME in the symbol table whose address + * is ADDR and returns a copy of the symbol table entry through + * the ENTRY argument. + * + * Return: Success: Address corresponding to the name. + * + * Failure: -1 + * + * Programmer: Robb Matzke + * robb@maya.nuance.com + * Aug 1 1997 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +haddr_t +H5G_find (hdf5_file_t *f, haddr_t addr, const char *name, H5G_entry_t *entry) +{ + H5G_node_ud1_t udata; /*data to pass through B-tree */ + haddr_t btree; /*address of B-tree */ + + /* set up the udata */ + not_implemented_yet__get_symtab_message (f, addr, &(udata.heap), &btree); + if (btree<=0 || udata.heap<=0) return -1; /*empty symbol table*/ + udata.operation = H5G_OPER_FIND; + udata.name = name; + + /* search the B-tree */ + if (H5B_find (f, H5B_SNODE, btree, &udata)<0) return -1; + + /* return the result */ + if (entry) *entry = udata.entry; + return udata.entry.header; +} + + +/*------------------------------------------------------------------------- + * Function: H5G_modify + * + * Purpose: Modifies the entry for an existing symbol. The name of the + * symbol is NAME in the symbol table whose address is ADDR in + * file F. ENTRY is the new symbol table entry to use for the + * symbol. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * robb@maya.nuance.com + * Aug 1 1997 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5G_modify (hdf5_file_t *f, haddr_t addr, const char *name, H5G_entry_t *entry) +{ + H5G_node_ud1_t udata; /*data to pass through B-tree */ + haddr_t btree; /*address of B-tree */ + + /* set up the udata */ + not_implemented_yet__get_symtab_message (f, addr, &(udata.heap), &btree); + if (btree<=0 || udata.heap<=0) return -1; /*empty symbol table*/ + udata.operation = H5G_OPER_MODIFY; + udata.name = name; + udata.entry = *entry; + + /* search and modify the B-tree */ + if (H5B_find (f, H5B_SNODE, btree, &udata)<0) return -1; + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5G_insert + * + * Purpose: Insert a new symbol into the table whose address is ADDR in + * file F. The name of the new symbol is NAME and its symbol + * table entry is ENTRY. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * robb@maya.nuance.com + * Aug 1 1997 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5G_insert (hdf5_file_t *f, haddr_t addr, const char *name, H5G_entry_t *entry) +{ + haddr_t btree; /*file address of B-tree */ + H5G_node_ud1_t udata; /*data to pass through B-tree */ + off_t offset; /*offset of name within heap */ + + /* make sure we have a B-tree and a heap */ + not_implemented_yet__get_symtab_message (f, addr, &btree, &(udata.heap)); + if (btree<=0 || udata.heap<=0) { + if (btree<=0 && + (btree = H5B_new (f, H5B_SNODE, sizeof(H5G_node_key_t)))<0) { + return -1; + } + if (udata.heap<=0) { + udata.heap = H5H_new (f, MAX(strlen(name)+1, H5G_INIT_HEAP)); + if (udata.heap<0) return -1; + if (0!=(offset = H5H_insert (f, udata.heap, 1, ""))) return -1; + } + not_implemented_yet__update_symtab_message (f, addr, udata.heap, btree); + } + + /* initialize data to pass through B-tree */ + udata.name = name; + udata.entry = *entry; + if (H5B_insert (f, H5B_SNODE, btree, &udata)<0) return -1; + + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5G_list + * + * Purpose: Returns a list of all the symbols in a symbol table. + * The caller allocates an array of pointers which this + * function will fill in with malloc'd names. The caller + * also allocates an array of symbol table entries which will + * be filled in with data from the symbol table. Each of these + * arrays should have at least MAXENTRIES elements. + * + * Return: Success: The total number of symbols in the + * symbol table. This may exceed MAXENTRIES, + * but at most MAXENTRIES values are copied + * into the NAMES and ENTRIES arrays. + * + * Failure: -1, the pointers in NAMES are undefined but + * no memory is allocated. The values in + * ENTRIES are undefined. + * + * Programmer: Robb Matzke + * robb@maya.nuance.com + * Aug 1 1997 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +intn +H5G_list (hdf5_file_t *f, haddr_t addr, int maxentries, + char *names[], H5G_entry_t entries[]) +{ + H5G_node_list_t udata; + haddr_t btree; + intn i; + + not_implemented_yet__get_symtab_message (f, addr, &btree, &(udata.heap)); + if (btree<=0 || udata.heap<=0) return 0; /*empty directory*/ + + udata.entry = entries; + udata.name = names; + udata.maxentries = maxentries; + udata.nsyms = 0; + + if (names) HDmemset (names, 0, maxentries); + if (H5B_list (f, H5B_SNODE, btree, &udata)<0) { + if (names) { + for (i=0; ientry = sn->entry[idx]; + switch (udata->operation) { + case H5G_OPER_FIND: + /* + * The caller is querying the symbol entry. + */ + udata->entry = sn->entry[idx]; + break; + + case H5G_OPER_MODIFY: + /* + * The caller is modifying the symbol entry. + */ + sn->entry[idx] = udata->entry; + sn->dirty += 1; + break; + } + return 0; } @@ -616,46 +637,59 @@ static herr_t H5G_node_list (hdf5_file_t *f, haddr_t addr, void *_udata) { H5G_node_list_t *udata = (H5G_node_list_t *)_udata; - H5G_entry_t *ent; - intn i, nsyms; - const char *s; - H5G_node_t *sn; + H5G_node_t *sn = H5AC_find (f, H5AC_SNODE, addr, NULL); + off_t *offsets = NULL; + intn nsyms, i; + const char *s; - /* - * Read the symbol table and save the entry info. We save it - * in a separate buffer if names are requested because the name - * lookup may invalidate the symbol table. - */ - sn = H5AC_find (f, H5AC_SNODE, addr, NULL); if (!sn) return -1; nsyms = sn->nsyms; - if (udata->name) { - ent = H5MM_xmalloc (nsyms * sizeof(H5G_entry_t)); - HDmemcpy (ent, sn->entry, nsyms*sizeof(H5G_entry_t)); - sn = NULL; - } else { - ent = sn->entry; + + /* + * If we've already overflowed the user-supplied buffer, then just + * keep track of how many names we've seen and don't bother doing + * anything else. + */ + if (udata->nsyms >= udata->maxentries) { + udata->nsyms += nsyms; + return 0; } /* - * Gather the info. + * Save the name offsets because looking up the name may cause the + * symbol table node to be preempted from the cache. */ - if (udata->name || udata->entry) { - for (i=0; inusednentries; i++) { - if (udata->name) { - s = H5H_peek (f, udata->heap, ent[i].name_off); - udata->name[udata->nused] = H5MM_xstrdup (s); - } - if (udata->entry) { - udata->entry[udata->nused] = ent[i]; - } - udata->nused += 1; + if (udata->entry) { + for (i=0; insyms+imaxentries; i++) { + udata->entry[udata->nsyms+i] = sn->entry[i]; + } + } else if (udata->name) { + offsets = H5MM_xmalloc (nsyms * sizeof(off_t)); + for (i=0; insyms+imaxentries; i++) { + offsets[i] = sn->entry[i].name_off; } - } else { - udata->nused += sn->nsyms; } - if (!sn) H5MM_xfree (ent); + /* + * Now strdup() the names. + */ + if (udata->name && udata->entry) { + for (i=0; insyms+imaxentries; i++) { + s = H5H_peek (f, udata->heap, udata->entry[udata->nsyms+i].name_off); + udata->name[udata->nsyms+i] = H5MM_xstrdup (s); + } + } else if (udata->name) { + for (i=0; insyms+imaxentries; i++) { + s = H5H_peek (f, udata->heap, offsets[i]); + udata->name[udata->nsyms+i] = H5MM_xstrdup (s); + } + offsets = H5MM_xfree (offsets); + } + + /* + * Update the number of symbols. + */ + udata->nsyms += nsyms; return 0; } diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h index 4b7930d..73a06ee 100644 --- a/src/H5Gprivate.h +++ b/src/H5Gprivate.h @@ -17,9 +17,12 @@ #ifndef _H5Gprivate_H #define _H5Gprivate_H -#include "H5Gproto.h" /*include public declarations */ +/*include public declarations */ +#include "H5Gproto.h" -#include "H5Fprivate.h" /*include packages needed by this header*/ +/*include packages needed by this header*/ +#include "H5Bprivate.h" +#include "H5Fprivate.h" #define H5G_NODE_MAGIC "SNOD" /*symbol table node magic number */ #define H5G_NODE_VERS 1 /*symbol table node version number */ @@ -83,6 +86,11 @@ typedef struct H5G_node_key_t { off_t offset; /*offset into heap for name */ } H5G_node_key_t; +typedef enum H5G_oper_t { + H5G_OPER_FIND =0, /*find a symbol */ + H5G_OPER_MODIFY =1 /*modify a symbol */ +} H5G_oper_t; + /* * Data exchange structure for symbol table nodes. This structure is * passed through the B-link tree layer to the methods for the objects @@ -91,10 +99,11 @@ typedef struct H5G_node_key_t { typedef struct H5G_node_ud1_t { /* downward */ - char *name; /*points to temporary memory */ + H5G_oper_t operation; /*what operation to perform */ + const char *name; /*points to temporary memory */ haddr_t heap; /*symbol table heap address */ - /* upward */ + /* upward for H5G_OPER_FIND, downward for H5G_OPER_MODIFY */ H5G_entry_t entry; /*symbol table entry */ } H5G_node_ud1_t; @@ -104,17 +113,28 @@ typedef struct H5G_node_list_t { /* downward */ H5G_entry_t *entry; /*array of entries, alloc'd by caller */ char **name; /*array of string ptrs, allocd by caller*/ - intn nentries; /*size of the ADDR and NAME arrays */ + intn maxentries; /*size of the ADDR and NAME arrays */ haddr_t heap; /*heap address */ /* upward */ - intn nused; /*num. symbols processed */ + intn nsyms; /*num. symbols processed */ } H5G_node_list_t; +extern const H5B_class_t H5B_SNODE[1]; + /* * Library prototypes... */ +haddr_t H5G_new (hdf5_file_t *f, size_t init); +haddr_t H5G_find (hdf5_file_t *f, haddr_t addr, const char *name, + H5G_entry_t *entry); +herr_t H5G_modify (hdf5_file_t *f, haddr_t addr, const char *name, + H5G_entry_t *entry); +herr_t H5G_insert (hdf5_file_t *f, haddr_t addr, const char *name, + H5G_entry_t *entry); +intn H5G_list (hdf5_file_t *f, haddr_t addr, int maxentries, + char *names[], H5G_entry_t entries[]); herr_t H5G_decode (hdf5_file_t *f, uint8 **pp, H5G_entry_t *ent); herr_t H5G_decode_vec (hdf5_file_t *f, uint8 **pp, H5G_entry_t *ent, intn n); herr_t H5G_encode (hdf5_file_t *f, uint8 **pp, H5G_entry_t *ent); -- cgit v0.12