Esempio n. 1
0
        private int depth_first(HObject parentObject, int nTotal)
        {
            Hdf5Utils.LogInfo?.Invoke($"depth_first({parentObject}): start");

            int    nelems;
            string fullPath = null;
            string ppath    = null;
            long   gid      = -1;

            H5Group pgroup = (H5Group)parentObject;

            ppath = pgroup.getPath();

            if (ppath == null)
            {
                fullPath = HObject.SEPARATOR;
            }
            else
            {
                fullPath = ppath + pgroup.getName() + HObject.SEPARATOR;
            }

            nelems = 0;
            try
            {
                gid = pgroup.open();
                var info = new H5G.info_t();
                H5G.get_info(gid, ref info);
                nelems = (int)info.nlinks;
            }
            catch (Exception ex)
            {
                nelems = -1;
                Hdf5Utils.LogError?.Invoke($"depth_first({parentObject}): H5Gget_info(gid {gid}) failure: {ex}");
            }

            if (nelems <= 0)
            {
                pgroup.close(gid);
                Hdf5Utils.LogInfo?.Invoke($"depth_first({parentObject}): nelems <= 0");
                Hdf5Utils.LogInfo?.Invoke($"depth_first({parentObject}): finish");
                return(nTotal);
            }

            // since each call of H5.H5Gget_objname_by_idx() takes about one second.
            // 1,000,000 calls take 12 days. Instead of calling it in a loop,
            // we use only one call to get all the information, which takes about
            // two seconds
            int[] objTypes = new int[nelems];
            //long[] fNos = new long[nelems];
            //long[] objRefs = new long[nelems];
            string[]     objNames = new string[nelems];
            H5L.info_t[] infos    = new H5L.info_t[nelems];
            try
            {
                int i = 0;
                int callback(long group, IntPtr name, ref H5L.info_t info, IntPtr op_data)
                {
                    string realName = Marshal.PtrToStringAuto(name);

                    objTypes[i] = (int)info.type;
                    objNames[i] = realName;
                    infos[i]    = info;

                    return(i++);
                }

                ulong pos = 0;
                H5L.iterate(gid, indexType, indexOrder, ref pos, callback, IntPtr.Zero);

                //for (ulong i = 0; i < (ulong)nelems; i++)
                //{


                //    H5G.info_t info = new H5G.info_t();
                //    H5G.get_info_by_idx(fid, fullPath, indexType, indexOrder, i, ref info);
                //    infos[i] = info;


                //}

                // H5.H5Gget_obj_info_full(fid, fullPath, objNames, objTypes, null, fNos, objRefs, indexType, indexOrder);
            }
            catch (Exception ex)
            {
                Hdf5Utils.LogError?.Invoke($"depth_first({parentObject}): failure: {ex}");
                Hdf5Utils.LogError?.Invoke($"depth_first({parentObject}): finish");
                return(nTotal);
            }

            int nStart = getStartMembers();
            int nMax   = getMaxMembers();

            string obj_name;
            int    obj_type;

            // Iterate through the file to see members of the group
            for (int i = 0; i < nelems; i++)
            {
                obj_name = objNames[i];
                obj_type = objTypes[i];
                Hdf5Utils.LogInfo?.Invoke($"depth_first({parentObject}): obj_name={obj_name}, obj_type={obj_type}");

                if (obj_name == null)
                {
                    Hdf5Utils.LogInfo?.Invoke($"depth_first({parentObject}): continue after null obj_name");
                    continue;
                }

                nTotal++;

                if (nMax > 0)
                {
                    if ((nTotal - nStart) >= nMax)
                    {
                        break; // loaded enough objects
                    }
                }

                bool skipLoad = (nTotal > 0) && (nTotal < nStart);

                // create a new group
                if (obj_type == HDF5Constants.H5O_TYPE_GROUP)
                {
                    H5Group g = new H5Group(this, obj_name, fullPath, pgroup);

                    pgroup.addToMemberList(g);

                    // detect and stop loops
                    // a loop is detected if there exists object with the same
                    // object ID by tracing path back up to the root.
                    bool    hasLoop = false;
                    H5Group tmpObj  = (H5Group)parentObject;

                    while (tmpObj != null)
                    {
                        if (tmpObj.equalsOID(new IntPtr((int)infos[i].u.address)) && (tmpObj.getPath() != null))
                        {
                            hasLoop = true;
                            break;
                        }
                        else
                        {
                            tmpObj = (H5Group)tmpObj.getParent();
                        }
                    }

                    // recursively go through the next group
                    // stops if it has loop.
                    if (!hasLoop)
                    {
                        nTotal = depth_first(g, nTotal);
                    }
                }
                else if (skipLoad)
                {
                    continue;
                }
                else if (obj_type == HDF5Constants.H5O_TYPE_DATASET)
                {
                    long        did    = -1;
                    long        tid    = -1;
                    H5T.class_t tclass = H5T.class_t.NO_CLASS;
                    try
                    {
                        did = H5D.open(fid, fullPath + obj_name, HDF5Constants.H5P_DEFAULT);
                        if (did >= 0)
                        {
                            tid = H5D.get_type(did);

                            tclass = H5T.get_class(tid);
                            if ((tclass == HDF5Constants.H5T_ARRAY) || (tclass == HDF5Constants.H5T_VLEN))
                            {
                                // for ARRAY, the type is determined by the base type
                                long btid = H5T.get_super(tid);

                                tclass = H5T.get_class(btid);

                                try
                                {
                                    H5T.close(btid);
                                }
                                catch (Exception ex)
                                {
                                    Hdf5Utils.LogInfo?.Invoke($"depth_first({parentObject})[{i}] dataset {obj_name} H5Tclose(btid {btid}) failure: {ex}");
                                }
                            }
                        }
                        else
                        {
                            Hdf5Utils.LogError?.Invoke($"depth_first({parentObject})[{i}] {obj_name} dataset open failure");
                        }
                    }
                    catch (Exception ex)
                    {
                        Hdf5Utils.LogError?.Invoke($"depth_first({parentObject})[{i}] {obj_name} dataset access failure: {ex}");
                    }
                    finally
                    {
                        try
                        {
                            H5T.close(tid);
                        }
                        catch (Exception ex)
                        {
                            Hdf5Utils.LogError?.Invoke($"depth_first({parentObject})[{i}] dataset {obj_name} H5Tclose(tid {tid}) failure: {ex}");
                        }
                        try
                        {
                            H5D.close(did);
                        }
                        catch (Exception ex)
                        {
                            Hdf5Utils.LogInfo?.Invoke($"depth_first({parentObject})[{i}] dataset {obj_name} H5Dclose(did {did}) failure: {ex}");
                        }
                    }
                    //todo:
                    //Dataset d = null;
                    //if (tclass == HDF5Constants.H5T_COMPOUND)
                    //{
                    //    // create a new compound dataset
                    //    d = new H5CompoundDS(this, obj_name, fullPath, oid); // deprecated!
                    //}
                    //else
                    //{
                    //    // create a new scalar dataset
                    //    d = new H5ScalarDS(this, obj_name, fullPath, oid); // deprecated!
                    //}

                    // pgroup.addToMemberList(d);
                }
                else if (obj_type == HDF5Constants.H5O_TYPE_NAMED_DATATYPE)
                {
                    //Datatype t = new H5Datatype(this, obj_name, fullPath, oid); // deprecated!

                    //pgroup.addToMemberList(t);
                }
                else if (obj_type == HDF5Constants.H5O_TYPE_UNKNOWN)
                {
                    //H5Link link = new H5Link(this, obj_name, fullPath, oid);

                    // pgroup.addToMemberList(link);
                    continue; // do the next one, if the object is not identified.
                }
            } // ( i = 0; i < nelems; i++)

            pgroup.close(gid);

            Hdf5Utils.LogInfo?.Invoke($"depth_first({parentObject}): finish");
            return(nTotal);
        }