コード例 #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PhysicalDatabase"/> class.
        /// </summary>
        /// <param name="journal">The journal.</param>
        public unsafe PhysicalDatabase(IJournal journal, Caching.BlockCache cache, JournalRecovery recovery)
        {
            this.journal = journal;
            this.journal.Startup(cache, recovery);

            // Must make sure we construct the first node if not already there ("default node").
            Block block = journal.ReadService.Read(BlockType.NoCache, 0);

            fixed(byte *p = block.Data)
            {
                DatabaseHeader *header = (DatabaseHeader *)p;

                rootAddress = header->RootObjectAddress;
            }

            // We must initialize it.
            if (rootAddress == 0)
            {
                journal.Execute(new Operations.CreateRootObject());
                block = journal.ReadService.Read(BlockType.NoCache, 0);
                fixed(byte *pp = block.Data)
                {
                    DatabaseHeader *header = (DatabaseHeader *)pp;

                    rootAddress = header->RootObjectAddress;
                }

                Debug.Assert(rootAddress != 0);
            }
        }
コード例 #2
0
ファイル: JournalLog.cs プロジェクト: zigaosolin/SharpMedia
        /// <summary>
        /// Initializes a new instance of the <see cref="JournalLog"/> class.
        /// </summary>
        /// <param name="journal">The journal.</param>
        /// <param name="allocator">The allocator.</param>
        /// <param name="frequency">The frequency.</param>
        public unsafe JournalLog(Allocator allocator)
        {
            this.allocator = allocator;

            byte[] data = allocator.Provider.Read(BlockType.NoCache, 0);
            fixed(byte *p = data)
            {
                DatabaseHeader *header = (DatabaseHeader *)p;

                this.frequency = header->JournalFrequency;
            }
        }
コード例 #3
0
ファイル: Allocator.cs プロジェクト: zigaosolin/SharpMedia
        /// <summary>
        /// Initializes a new instance of the <see cref="Allocator"/> class.
        /// </summary>
        /// <param name="provider">The provider.</param>
        public unsafe Allocator(Caching.BlockCache provider)
        {
            this.provider = provider;
            byte[] data = provider.Read(BlockType.NoCache, 0);
            fixed(byte *p = data)
            {
                DatabaseHeader *header = (DatabaseHeader *)p;

                if (!header->IsValid)
                {
                    throw new DatabaseException("The database header is not valid, not a valid physical database. Must reformat it.");
                }

                blockCount = header->BlockCount;
            }
        }
コード例 #4
0
ファイル: Formatter.cs プロジェクト: zigaosolin/SharpMedia
        /// <summary>
        /// Formats the database with provider.
        /// </summary>
        /// <param name="provider">The provider.</param>
        /// <param name="databaseName">Name of the database, maximum 63 characters long.</param>
        /// <param name="blockCount">The block count.</param>
        /// <param name="journalSectorFreq">The journal frequency.</param>
        /// <param name="journalSize">Size of the journal.</param>
        /// <param name="journalFrequency">The journal frequency, meaning depends on sector frequency.</param>
        /// <returns></returns>
        public unsafe static bool Format(IProvider provider, string databaseName, ulong blockCount,
                                         uint journalFrequency)
        {
            if (databaseName == null || databaseName == string.Empty || databaseName.Length > 63)
            {
                throw new ArgumentException("Database name was either invalid or too long.");
            }

            // 1) We first enlarge the provider (must be at least that long).
            if (!provider.Enlarge(blockCount))
            {
                return(false);
            }

            // 2) We create the header node.
            Block block = new Block(provider.BlockSize);

            fixed(byte *p = block.Data)
            {
                DatabaseHeader *header = (DatabaseHeader *)p;

                header->BlockSize         = provider.BlockSize;
                header->BlockCount        = blockCount;
                header->HeaderMagic1      = DatabaseHeader.Magic1;
                header->HeaderMagic2      = DatabaseHeader.Magic2;
                header->JournalFrequency  = journalFrequency;
                header->RootObjectAddress = 0;

                // Copy the name.
                int i;

                for (i = 0; i < databaseName.Length; i++)
                {
                    header->DatabaseName[i] = databaseName[i];
                }
                header->DatabaseName[i] = '\0';
            }

            // We write it.
            provider.Write(0, block.Data);

            // Make an empty (zero block).
            block.ZeroMemory();

            // The one allocated block.
            Block fullBlock = new Block(provider.BlockSize);

            fullBlock.ZeroMemory();
            BoolArray fullBlockArray = new BoolArray(fullBlock.Data);

            fullBlockArray[0] = true;

            // 3) We clear allocation blocks.
            for (ulong superBlock = BlockHelper.FirstSuperBlockAddress; superBlock != 0;
                 superBlock = BlockHelper.GetNextSuperBlock(provider.BlockSize, superBlock, blockCount))
            {
                provider.Write(superBlock, block.Data);
            }

            for (ulong allocBlock = BlockHelper.FirstSuperBlockAddress + 1; allocBlock != 0;
                 allocBlock = BlockHelper.GetNextAllocationBlock(provider.BlockSize, allocBlock, blockCount))
            {
                if (JournalLog.IsJournalLog(allocBlock + 1, journalFrequency, provider.BlockSize))
                {
                    // We write the allocated.
                    provider.Write(allocBlock, fullBlock.Data);

                    // Next block is filled with header.
                    if (allocBlock + 1 < blockCount)
                    {
                        provider.Write(allocBlock + 1, block.Data);
                    }
                }
                else
                {
                    provider.Write(allocBlock, block.Data);
                }
            }


            return(true);
        }
コード例 #5
0
        public unsafe void Execute(uint stage, IService service)
        {
            string defaultTSType = typeof(object).FullName;

            // 1) We create the node common block.
            ulong     versionAddress = service.AllocationContext.AllocateBlock();
            ulong     commonAddress  = service.AllocationContext.AllocateBlock();
            BPlusTree versionTS      = new BPlusTree(service.AllocationContext.CreateEmptyBTree());

            // Fill common block and write.
            Block commonBlock = new Block(service.BlockSize);

            fixed(byte *p = commonBlock.Data)
            {
                NodeCommonHeader *header = (NodeCommonHeader *)p;

                header->ChildrenBTree         = service.AllocationContext.CreateEmptyBTree();
                header->CurrentVersionAddress = versionAddress;
                header->CurrentVersionNumber  = 0;
                header->HeaderMagic           = NodeCommonHeader.Magic;
                header->ParentAddress         = 0;
                header->VersionsBTree         = versionTS.RootAddress;
            }

            service.Write(BlockType.NodeHeaderBlock, commonAddress, commonBlock);

            // 2) We create the node default typed stream.
            Block tsblock = new Block(service.BlockSize);

            fixed(byte *p = tsblock.Data)
            {
                TypedStreamHeader *header = (TypedStreamHeader *)p;

                header->ObjectsAddress = service.AllocationContext.AllocateBlock();
                header->Options        = StreamOptions.None;
                header->ObjectSize     = 0;

                int i;

                for (i = 0; i < defaultTSType.Length; i++)
                {
                    header->Type[i] = defaultTSType[i];
                }

                // Null terminate it.
                header->Type[i] = '\0';
            }

            ulong tsBlock = service.AllocationContext.AllocateBlock();

            service.Write(BlockType.TypedStreamHeader, tsBlock, tsblock);

            // 3) We create the node version block.
            // Fill version block and write.
            Block versionBlock = new Block(service.BlockSize);

            fixed(byte *pp = versionBlock.Data)
            {
                NodeVersionHeader *header = (NodeVersionHeader *)pp;

                header->CreationTime       = DateTime.Now;
                header->DefaultTypedStream = 0;
                header->HeaderMagic        = NodeVersionHeader.Magic;
                header->ModifiedTime       = DateTime.Now;
                header->NodeCommonAddress  = commonAddress;
                header->StreamCount        = 0; //< Is actually one but NodeHelper changes this.
                header->VersionNumber      = 0;
            }

            // We must add default typed stream to block.
            NodeVersionHelper.AddTypedStream(tsBlock, defaultTSType, versionBlock);
            service.Write(BlockType.NodeHeaderBlock, versionAddress, versionBlock);

            // 4) We must create versions
            VersionTag versionTag = new VersionTag((0).GetHashCode());

            versionTag.Add(0, versionAddress);
            byte[] versionTagData = Common.SerializeToArray(versionTag);

            // Write to stream.
            BlockStream versionTagStream = service.AllocationContext.CreateBlockStream((ulong)versionTagData.LongLength);

            versionTagStream.Write(versionTagData);

            versionTS.Add(service, new ObjectInfo((uint)(0).GetHashCode(),
                                                  (ulong)versionTagData.LongLength, versionTagStream.BaseAddress));

            // 5) We must write to database header.
            Block block = service.Read(BlockType.NoCache, 0);

            fixed(byte *ppp = block.Data)
            {
                DatabaseHeader *header = (DatabaseHeader *)ppp;

                header->RootObjectAddress = commonAddress;
            }

            // Write the header.
            service.Write(BlockType.NoCache, 0, block);
        }