示例#1
0
        /// <summary>
        /// Reads a cluster centre from a binary file.
        /// </summary>
        /// <param name="fileIn">The input file.</param>
        /// <param name="coordCount">The number of vertex coordinates to read.</param>
        /// <returns>Returns the read centre.</returns>
        public static Centre ReadBinary(System.IO.BinaryReader fileIn, ushort coordCount)
        {
            // check that we are loading the right types
            System.Diagnostics.Debug.Assert(FileAddressSize == sizeof(long));
            System.Diagnostics.Debug.Assert(ChildrenCountSize == sizeof(int));

            // create the cluster centre
            Centre c = new Centre();

            // read the vertex coordinates
            c.vertex = Vertex.ReadBinary(fileIn, coordCount);

            // read children information
            c.childrenFileStart = fileIn.ReadInt64();
            c.childrenCount     = fileIn.ReadInt32();

            return(c);
        }
示例#2
0
        /// <summary>
        /// Loads all members of the given cluster.
        /// </summary>
        /// <param name="level">The level from where to load the members (one level lower than the cluster centre).</param>
        /// <param name="startIndex">Index of the first cluster member.</param>
        /// <param name="count">Number of the cluster members.</param>
        /// <returns>Returns an array of cluster vertices.</returns>
        public Centre[] ExpandCluster(int level, long startIndex, int count)
        {
            // open input file
            string       fileName = GetNumberedFileName(level);
            FileStream   streamIn = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
            BinaryReader fileIn   = new BinaryReader(streamIn);

            // read the number of coordinates each vertex has
            ushort coordCount = fileIn.ReadUInt16();

            // seek to the appropriate cluster
            streamIn.Seek(startIndex, SeekOrigin.Begin);

            // prepare memory
            Centre[] clusterMembers = new Centre[count];

            // load the cluster members
            if (level > 0)
            {
                for (int i = 0; i < count; i++)
                {
                    clusterMembers[i] = Centre.ReadBinary(fileIn, coordCount);
                }
            }
            else
            {
                for (int i = 0; i < count; i++)
                {
                    clusterMembers[i] = Centre.ReadBinaryJustCoords(fileIn, coordCount);
                }
            }

            // close input file
            fileIn.Close();
            streamIn.Close();

            return(clusterMembers);
        }
        /// <summary>
        /// Adds more centres for clustering.
        /// </summary>
        /// <param name="centres">The centres to add.</param>
        /// <param name="level">The level where to add.</param>
        private void PushVertices(Centre[] centres, int level)
        {
            if (finished)
            {
                throw new ApplicationException("The input stream has already been finished.");
            }

            // get the appropriate clustering level
            ClusteringLevel cl = clusteringLevels[level];

            // is there enough free space?
            if (centres.Length <= cl.FreeSpace)
            {
                // yes, add all the vertices right away
                cl.PushVertices(centres);
            }
            else
            {
                // no, add the vertices by pieces
                int remainToPush  = centres.Length;
                int alreadyPushed = 0;

                int free = cl.FreeSpace;
                // prepare the first piece
                Centre[] pieceToPush = new Centre[free];
                Array.Copy(centres, alreadyPushed, pieceToPush, 0, free);

                // push the first piece
                cl.PushVertices(pieceToPush);
                remainToPush  -= free;
                alreadyPushed += free;

                // process the full block
                ProcessLevel(level);

                pieceToPush = new Centre[blockSize];
                // push further pieces
                while (remainToPush > blockSize)
                {
                    // prepare a single piece
                    Array.Copy(centres, alreadyPushed, pieceToPush, 0, blockSize);

                    // push the piece
                    cl.PushVertices(pieceToPush);
                    remainToPush  -= blockSize;
                    alreadyPushed += blockSize;

                    // process the full block
                    ProcessLevel(level);
                }

                // copy the last remaining piece
                pieceToPush = new Centre[remainToPush];
                Array.Copy(centres, alreadyPushed, pieceToPush, 0, remainToPush);

                // push the last remaining piece
                cl.PushVertices(pieceToPush);
            }

            // check whether there is still some space for further vertices
            if (cl.FreeSpace == 0)
            {
                // no, the level is exactly full, let's process it
                ProcessLevel(level);
            }
        }