@@ -45,9 +45,8 @@ def __init__(
4545 def _createGroup (self , parent , grp_json , name = None ):
4646 """ create the group and any links it contains """
4747 grp = parent .create_group (name )
48- if "links" in grp_json :
49- grp_links = grp_json ["links" ]
50- self ._createObjects (grp , grp_links )
48+ return grp
49+
5150
5251 def _createDataset (self , parent , dset_json , name = None ):
5352 """ create a dataset object """
@@ -156,58 +155,85 @@ def _createDataset(self, parent, dset_json, name=None):
156155 else :
157156 self .log .info (f"Unexpected filter name: { filter_alias } , ignoring" )
158157
159- parent .create_dataset (name , ** kwargs )
158+ dset = parent .create_dataset (name , ** kwargs )
159+ return dset
160160
161161 def _createDatatype (self , parent , ctype_json , name = None ):
162162 """ create a datatype object """
163163
164164 type_item = ctype_json ["type" ]
165165 dtype = createDataType (type_item )
166166 parent [name ] = dtype
167+ return parent [name ]
167168
168169
169- def _createObjects (self , parent , links_json ):
170+ def _createObjects (self , parent , links_json , visited = set () ):
170171 """ create child object in the given group, recurse for any sub-groups """
172+
171173 for title in links_json :
172- if title in parent :
173- # TBD: this will do the wrong thing if the link tgt has changed
174- continue
174+ # if title in parent:
175+ # # TBD: this will do the wrong thing if the link tgt has changed
176+ # continue
175177 link_json = links_json [title ]
176178 link_class = link_json ["class" ]
177- if link_class == "H5L_TYPE_SOFT" :
179+ if link_class == "H5L_TYPE_SOFT" and title not in parent :
178180 h5path = link_json ["h5path" ]
179181 parent [title ] = h5py .SoftLink (h5path )
180- elif link_class == "H5L_TYPE_EXTERNAL" :
182+ elif link_class == "H5L_TYPE_EXTERNAL" and title not in parent :
181183 h5path = link_json ["h5path" ]
182184 filename = link_json ["file" ]
183185 parent [title ] = h5py .ExternalLink (filename , h5path )
184- elif link_class == "H5L_TYPE_USER_DEFINED" :
186+ elif link_class == "H5L_TYPE_USER_DEFINED" and title not in parent :
185187 self .log .warning ("unable to create user-defined link: {title}" )
186188 elif link_class == "H5L_TYPE_HARD" :
187189 tgt_id = link_json ["id" ]
190+ """
191+ if tgt_id in visited:
192+ # we've already processed this object
193+ if title not in parent:
194+ if tgt_id in self._id_map:
195+ tgt_obj = self._id_map[tgt_id]
196+ parent[title] = tgt_obj
197+ else:
198+ self.log.warning("h5py_writer - expected to find {tgt_id} in id_map")
199+ continue
200+ """
201+
202+ collection = getCollectionForId (tgt_id )
203+
204+ obj_json = self .db .getObjectById (tgt_id )
205+
188206 if tgt_id in self ._id_map :
207+ # object has already been created
189208 tgt_path = self ._id_map [tgt_id ]
190209 tgt_obj = parent [tgt_path ]
191- parent [title ] = tgt_obj
210+ if title not in parent :
211+ parent [title ] = tgt_obj
212+ if collection == "groups" and tgt_id not in visited :
213+ # recurse over sub-objects to pick up any new links
214+ grp_links = obj_json ["links" ]
215+ visited .add (tgt_id )
216+ self ._createObjects (tgt_obj , grp_links , visited = visited )
192217 else :
193- obj_json = self .db .getObjectById (tgt_id )
194218 parent_path = parent .name
195219 if parent_path [- 1 ] != '/' :
196220 parent_path += '/'
197221 self ._id_map [tgt_id ] = parent_path + title
198- collection = getCollectionForId (tgt_id )
199222 kwds = {"name" : title }
200223 if collection == "groups" :
201- tgt_obj = self ._createGroup (parent , obj_json , ** kwds )
224+ tgt_grp = self ._createGroup (parent , obj_json , ** kwds )
225+ if "links" in obj_json :
226+ grp_links = obj_json ["links" ]
227+ visited .add (tgt_id )
228+ self ._createObjects (tgt_grp , grp_links , visited = visited )
202229 elif collection == "datasets" :
203- tgt_obj = self ._createDataset (parent , obj_json , ** kwds )
230+ self ._createDataset (parent , obj_json , ** kwds )
204231 elif collection == "datatypes" :
205- tgt_obj = self ._createDatatype (parent , obj_json , ** kwds )
232+ self ._createDatatype (parent , obj_json , ** kwds )
206233 else :
207234 self .log .warning (f"unexpected collection: { collection } " )
208- tgt_obj = None
209- if tgt_obj :
210- parent [title ] = tgt_obj
235+ visited .add (tgt_id )
236+
211237 else :
212238 self .log .warning (f"unexpected link class: { link_class } " )
213239
@@ -231,7 +257,6 @@ def updateDatasetValues(self, dset_id, dset):
231257
232258 def createAttribute (self , obj , name , attr_json ):
233259 """ add the given attribute to obj """
234- print (f"h5py_writer.createAttribute { obj .name } : { name } " )
235260
236261 dtype = createDataType (attr_json ["type" ])
237262 shape_json = attr_json ["shape" ]
@@ -276,10 +301,11 @@ def flush(self):
276301 root_id = self .db .root_id
277302 self ._id_map [root_id ] = "/"
278303 with h5py .File (self ._filepath , mode = self ._mode ) as f :
279- root_json = self .db .getObjectById (root_id )
280- if "links" in root_json :
281- root_links = root_json ["links" ]
282- self ._createObjects (f , root_links )
304+ if self .db .new_objects :
305+ root_json = self .db .getObjectById (root_id )
306+ if "links" in root_json :
307+ root_links = root_json ["links" ]
308+ self ._createObjects (f , root_links , visited = set (root_id ))
283309 # update attributes, dataset values
284310 for obj_id in self ._id_map :
285311 if self .db .is_dirty (obj_id ):
0 commit comments