Example #1
0
        // Reserves an oid so it can't be used later.
        public void Reserve(long oid)
        {
            // Add a empty block for the reserved data.
            GObjectBlock reservedBlock = new GObjectBlock();
            reservedBlock.Blocks = new long[]{};
            reservedBlock.OID = oid;
            reservedBlock.CountBytes = 0;
            m_objectBlocks.Add(oid, reservedBlock);

            m_lastOID = Math.Max(oid, m_lastOID);
        }
Example #2
0
        // (05.04.2007 10:19)
        // Saves oid internally in the file.
        public void SaveOIDs()
        {
            lock (m_dummy)
            {
                m_oidPos = 0;
                m_oidPosIndex = 0;

                if (SaveChanges != null)
                    SaveChanges(this, new EventArgs());

                // Free the blocks of the structure, but
                // do not allow use of root block.
                Delete(0);
                m_deletedPos.RemoveAt(0);

                // (02.07.2007 09:01)
                // Remove all deleted blocks at the end of file.
                long lastPos = LastDataBlockPos();
                int c = this.m_deletedPos.Count;
                long deletedpos;
                for (int k = c - 1; k >= 0; k--)
                {
                    deletedpos = (long)this.m_deletedPos.GetByIndex(k);
                    if (deletedpos > lastPos)
                        this.m_deletedPos.Remove(deletedpos);
                    else
                        break;
                }
                // (01.07.2007 13:43)
                // Set the length to be shortest as possible.
                this.m_stream.SetLength(lastPos + BLOCK_SIZE);

                // Make sure the file length ends at a block.
                long rest = m_stream.Length % BLOCK_SIZE;
                if (rest != 0)
                    this.m_stream.SetLength(m_stream.Length + BLOCK_SIZE - m_stream.Length % BLOCK_SIZE);

                m_stream.Seek(0, System.IO.SeekOrigin.Begin);
                BinaryWriter w = new BinaryWriter(m_stream);

                // Repair the delete index if a block is in use
                // but marked as deleted.
                ICollection oids = m_objectBlocks.Values;
                foreach (GObjectBlock objectBlock in oids)
                {
                    foreach (long pos in objectBlock.Blocks)
                    {
                        if (m_deletedPos.Contains(pos))
                            m_deletedPos.Remove(pos);
                    }
                }

                ArrayList oidBlocks = new ArrayList();
                oidBlocks.Add(0L);

                // Write number of object blocks.
                WriteOIDInt32(m_objectBlocks.Count, w, oidBlocks);
                int i = 0;
                foreach (GObjectBlock objectBlock in oids)
                {
                    if (objectBlock.OID != 0)
                    {
                        /*
                        // Stop if invalid object block.
                        System.Diagnostics.Debug.Assert(objectBlock.OID != -1, "Invalid Object Block", "The OID of this Object Block is not set.");

                        // Stop if the number of bytes is not correct.
                        System.Diagnostics.Debug.Assert(objectBlock.CountBytes <= objectBlock.Blocks.Length * BLOCK_SIZE && objectBlock.CountBytes >= (objectBlock.Blocks.Length - 1) * BLOCK_SIZE, "Invalid object size", "The size of object in bytes is larger than\n the number of blocks multiplied the block size");
                        */

                        WriteOIDInt64(objectBlock.OID, w, oidBlocks);
                        WriteOIDInt32(objectBlock.CountBytes, w, oidBlocks);

                        // Write block positions.
                        WriteOIDInt32(objectBlock.Blocks.Length, w, oidBlocks);
                        int j = 0;
                        foreach (long pos in objectBlock.Blocks)
                        {
                            /*
                            // Stop if invalid block pos.
                            System.Diagnostics.Debug.Assert(pos - m_stream.Length <= BLOCK_SIZE * 4194304, "Invalid Block Position", "The block position was invalid because it points to a position 1 GB after the end of file.");
                            */

                            WriteOIDInt64(pos, w, oidBlocks);
                            j++;
                        }

                        i++;
                    }
                }

                // Write number of deleted object blocks.
                WriteOIDInt32(this.m_deletedPos.Count, w, oidBlocks);
                ICollection positions = m_deletedPos.Values;
                long[] positionsTable = new long[positions.Count];
                positions.CopyTo(positionsTable, 0);
                foreach (long pos in positionsTable)
                {
                    WriteOIDInt64(pos, w, oidBlocks);
                }

                GObjectBlock oidBlock = new GObjectBlock();
                oidBlock.Blocks = new long[oidBlocks.Count];
                oidBlocks.CopyTo(oidBlock.Blocks, 0);
                oidBlock.OID = 0L;
                oidBlock.CountBytes = oidBlock.Blocks.Length * BLOCK_SIZE;
                m_objectBlocks.Add(oidBlock.OID, oidBlock);
            }
        }
Example #3
0
        // (05.04.2007 10:19)
        // Reads oids internally in the file.
        public void ReadOIDs()
        {
            m_oidPos = 0;
            // Make sure the file length ends at a block.
            long rest = m_stream.Length % BLOCK_SIZE;
            if (rest != 0)
                this.m_stream.SetLength(m_stream.Length + BLOCK_SIZE - m_stream.Length % BLOCK_SIZE);
            this.m_stream.Seek(0, System.IO.SeekOrigin.Begin);
            this.m_objectBlocks.Clear();
            this.m_deletedPos.Clear();

            GObjectBlock oidBlock = new GObjectBlock();
            if (m_stream.Length == 0)
            {
                oidBlock.OID = 0L;
                oidBlock.CountBytes = BLOCK_SIZE;
                oidBlock.Blocks = new long[]{0};
                m_objectBlocks.Add(0L, oidBlock);
                return;
            }

            BinaryReader r = new BinaryReader(m_stream);
            ArrayList oidBlocks = new ArrayList();
            oidBlocks.Add(0L);

            int countObjectBlocks = ReadOIDInt32(r, oidBlocks);
            long readPos = 0;
            for (int i = 0; i < countObjectBlocks; i++)
            {
                GObjectBlock objectBlock = new GObjectBlock();
                objectBlock.OID = ReadOIDInt64(r, oidBlocks);
                if (objectBlock.OID != 0)
                {
                    if (objectBlock.OID > m_lastOID)
                        m_lastOID = objectBlock.OID;
                    objectBlock.CountBytes = ReadOIDInt32(r, oidBlocks);

                    // Read block positions.
                    int blockCount = ReadOIDInt32(r, oidBlocks);

                    // Stop if the number of bytes is not correct.
                    System.Diagnostics.Debug.Assert(objectBlock.CountBytes <= blockCount * BLOCK_SIZE && objectBlock.CountBytes >= (blockCount - 1) * BLOCK_SIZE, "Invalid object size", "The size of object in bytes is larger than\n the number of blocks multiplied the block size");

                    objectBlock.Blocks = new long[blockCount];

                    for (int j = 0; j < blockCount; j++)
                    {
                        readPos = ReadOIDInt64(r, oidBlocks);

                        // Repear delete index if the block is used.
                        if (this.m_deletedPos.Contains(readPos))
                            this.m_deletedPos.Remove(readPos);

                        objectBlock.Blocks[j] = readPos;
                    }

                    // Add object block.
                    m_objectBlocks.Add(objectBlock.OID, objectBlock);
                }
            }

            // Read deleted block positions.
            int deletedBlocks = ReadOIDInt32(r, oidBlocks);
            for (int i = 0; i < deletedBlocks; i++)
            {
                long pos = ReadOIDInt64(r, oidBlocks);
                if (!m_deletedPos.Contains(pos))
                    m_deletedPos.Add(pos, pos);
            }

            oidBlock.Blocks = new long[oidBlocks.Count];
            oidBlocks.CopyTo(oidBlock.Blocks, 0);
            oidBlock.OID = 0L;
            oidBlock.CountBytes = oidBlock.Blocks.Length * BLOCK_SIZE;
            m_objectBlocks.Add(oidBlock.OID, oidBlock);
        }
Example #4
0
 // Create an empty object block,
 // prepared for stream writing.
 public GObjectBlock GetEmptyBlock(long oid)
 {
     GObjectBlock objectBlock = new GObjectBlock();
     objectBlock.OID = oid;
     objectBlock.CountBytes = 0;
     objectBlock.Blocks = new long[]{};
     this.m_objectBlocks.Add(oid, objectBlock);
     return objectBlock;
 }
Example #5
0
 public OdbStream(GODB odb, long oid)
 {
     m_odb = odb;
     if (!m_odb.ReadOnly && !m_odb.Contains(oid))
         m_objectBlock = m_odb.GetEmptyBlock(oid);
     else
         m_objectBlock = m_odb.GetObjectBlock(oid);
 }
Example #6
0
        private void ReserveOID(int bytesLength)
        {
            long oid = 0L;
            // Write block on new position.
            GObjectBlock objectBlock = new GObjectBlock();
            objectBlock.OID = oid;
            objectBlock.CountBytes = bytesLength;

            // Delete old object block.
            Delete(oid);

            // Compute the number of blocks needed.
            int countBlocks = (int)Math.Ceiling(objectBlock.CountBytes / (double)BLOCK_SIZE);
            objectBlock.Blocks = this.FindNewOIDPos(countBlocks);

            // Add new object block.
            m_objectBlocks.Add(oid, objectBlock);

            if (oid > m_lastOID)
                m_lastOID = oid;
        }
Example #7
0
        /// <summary>
        /// Saves bytes.
        /// If the OID writed has larger value than
        /// the automatically created OID, the next
        /// generated OID will follow the writed OID.
        /// </summary>
        /// <param name="oid">The OID (object identifier).</param>
        /// <param name="bytes">The bytes to write.</param>
        public void Write(long oid, byte[] bytes)
        {
            lock (m_dummy)
            {
                // Write block on new position.
                GObjectBlock objectBlock = new GObjectBlock();
                objectBlock.OID = oid;
                objectBlock.CountBytes = bytes.Length;

                // Delete old object block.
                Delete(oid);

                // Compute the number of blocks needed.
                int countBlocks = (int)Math.Ceiling(objectBlock.CountBytes / (double)BLOCK_SIZE);
                objectBlock.Blocks = this.FindNewPos(countBlocks);
                for (long i = 0; i < countBlocks; i++)
                {
                    long pos = i * BLOCK_SIZE;
                    m_stream.Seek(objectBlock.Blocks[i], System.IO.SeekOrigin.Begin);
                    m_stream.Write(bytes, (int)pos, (int)(Math.Min(BLOCK_SIZE, bytes.Length - pos)));
                }

                // Add new object block.
                m_objectBlocks.Add(oid, objectBlock);

                if (oid > m_lastOID)
                    m_lastOID = oid;
            }
        }