Exemplo n.º 1
0
        /// <summary>
        /// Gets the index of the typed stream.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="block">The block.</param>
        /// <param name="service">The service.</param>
        /// <param name="typedStreamBlock">The typed stream block.</param>
        /// <returns></returns>
        public static unsafe uint GetTypedStreamIndex(string name, Block block,
                                                      IReadService service, out Block typedStreamBlock, out ulong address)
        {
            int nameHash = name.GetHashCode();

            fixed(byte *p = block.Data)
            {
                NodeVersionHeader *header = (NodeVersionHeader *)p;
                TSData *           data   = (TSData *)&header->TypedStreamData[0];


                for (uint i = 0; i < header->StreamCount; i++)
                {
                    if (nameHash == data[i].Hash)
                    {
                        // We check it if it is the correct one.
                        typedStreamBlock = service.Read(BlockType.TypedStreamHeader, data[i].Address);

                        if (IsTypedStreamWithType(typedStreamBlock, name))
                        {
                            address = data[i].Address;
                            return(i);
                        }
                    }
                }
            }

            // Noone found.
            typedStreamBlock = null;
            address          = 0;
            return(uint.MaxValue);
        }
Exemplo n.º 2
0
        public unsafe void Prepare(IReadService readService,
                                   out OperationStartupData data)
        {
            // We must make sure we can terminate if too many streams.
            Block block = readService.Read(BlockType.NodeHeaderBlock, versionNode);

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

                if (header->StreamCount + 1 > BlockHelper.MaxTypedStreamsInNode(readService.BlockSize))
                {
                    throw new InvalidOperationException("Number of typed stream in node is more that "
                                                        + BlockHelper.MaxTypedStreamsInNode(readService.BlockSize) + " which is the limit"
                                                        + " at block size " + readService.BlockSize.ToString());
                }
            }

            // We need one allocation if typed stream is single object, otherwise two.
            if ((options & StreamOptions.SingleObject) != 0)
            {
                data = new OperationStartupData(versionNode, 1);
            }
            else
            {
                data = new OperationStartupData(versionNode, 2);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Removes the typed stream index.
        /// </summary>
        /// <param name="index">The index.</param>
        /// <param name="block">The block.</param>
        /// <returns></returns>
        public static unsafe ulong RemoveTypedStream(uint index, Block block)
        {
            ulong toReturn = 0;

            fixed(byte *p = block.Data)
            {
                NodeVersionHeader *header = (NodeVersionHeader *)p;
                TSData *           data   = (TSData *)&header->TypedStreamData[0];

                toReturn = data[index].Address;

                // We check if last, we can simply remove it.
                if (header->StreamCount == index + 1)
                {
                    header->StreamCount--;
                }
                // We replace the last with this.
                else
                {
                    data[index].Address = data[header->StreamCount - 1].Address;
                    data[index].Hash    = data[header->StreamCount - 1].Hash;

                    // We check if default TS was last that was moved.
                    if (header->DefaultTypedStream == header->StreamCount - 1)
                    {
                        header->DefaultTypedStream = index;
                    }
                    header->StreamCount--;
                }
            }

            return(toReturn);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Gets the default type.
        /// </summary>
        /// <param name="block">The block.</param>
        /// <returns></returns>
        public static unsafe ulong GetDefaultTypeBlock(Block block)
        {
            fixed(byte *p = block.Data)
            {
                NodeVersionHeader *header = (NodeVersionHeader *)p;
                TSData *           data   = (TSData *)&header->TypedStreamData[0];

                return(data[header->DefaultTypedStream].Address);
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Gets the typed stream address and hash.
        /// </summary>
        /// <param name="index">The index.</param>
        /// <param name="block">The block.</param>
        /// <param name="hash">The hash.</param>
        /// <returns></returns>
        public static unsafe ulong GetTypedStreamAddress(uint index, Block block, out int hash)
        {
            fixed(byte *p = block.Data)
            {
                NodeVersionHeader *header = (NodeVersionHeader *)p;
                TSData *           data   = (TSData *)&header->TypedStreamData[0];

                // Must watch for overflows.
                hash = data[index].Hash;
                return(data[index].Address);
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Adds the typed stream to node version.
        /// </summary>
        /// <param name="address">The address.</param>
        /// <param name="type">The type.</param>
        /// <param name="data">The data.</param>
        public static unsafe void AddTypedStream(ulong address, string type, Block block)
        {
            fixed(byte *pp = block.Data)
            {
                // We obtain the data.
                NodeVersionHeader *header = (NodeVersionHeader *)pp;
                TSData *           data   = (TSData *)&header->TypedStreamData[0];

                // We write the data.
                data[header->StreamCount].Address = address;
                data[header->StreamCount++].Hash  = type.GetHashCode();
            }
        }
        public unsafe void Execute(uint stage, IService service)
        {
            Debug.Assert(stage == 0);

            // We just change the node header.
            Block block = service.Read(BlockType.NodeHeaderBlock, rootAddress);

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

                header->DefaultTypedStream = newDefaultIndex;
            }

            // We write it.
            service.Write(BlockType.NodeHeaderBlock, rootAddress, block);
        }
Exemplo n.º 8
0
        /// <summary>
        /// Lists all typed streams.
        /// </summary>
        /// <param name="block">The block.</param>
        /// <returns></returns>
        public static unsafe List <ulong> ListAllTypedStreamsAsAddresses(Block block, Journalling.IReadService service)
        {
            List <ulong> collection = new List <ulong>();

            fixed(byte *p = block.Data)
            {
                NodeVersionHeader *header = (NodeVersionHeader *)p;
                TSData *           data   = (TSData *)&header->TypedStreamData[0];

                // We go through all.
                for (uint i = 0; i < header->StreamCount; i++)
                {
                    collection.Add(data[i].Address);
                }
            }

            return(collection);
        }
Exemplo n.º 9
0
        /// <summary>
        /// Lists all typed streams.
        /// </summary>
        /// <param name="block">The block.</param>
        /// <returns></returns>
        public static unsafe StringCollection ListAllTypedStreams(Block block, Journalling.IReadService service)
        {
            StringCollection collection = new StringCollection();

            fixed(byte *p = block.Data)
            {
                NodeVersionHeader *header = (NodeVersionHeader *)p;
                TSData *           data   = (TSData *)&header->TypedStreamData[0];

                // We go through all.
                for (uint i = 0; i < header->StreamCount; i++)
                {
                    Block tsHeader = service.Read(BlockType.TypedStreamHeader, data[i].Address);
                    fixed(byte *pp = tsHeader.Data)
                    {
                        TypedStreamHeader *h = (TypedStreamHeader *)pp;

                        collection.Add(new string(h->Type));
                    }
                }
            }

            return(collection);
        }
Exemplo n.º 10
0
        public unsafe void Execute(uint stage, IService service)
        {
            // 1) We create the node common block.
            versionAddress = service.AllocationContext.AllocateBlock();
            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         = parentAddress;
                header->VersionsBTree         = versionTS.RootAddress;
            }

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

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

            ulong tsBlock = service.AllocationContext.AllocateBlock();

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

                header->ObjectsAddress = (defaultTSOptions & StreamOptions.SingleObject) == 0 ?
                                         service.AllocationContext.CreateEmptyBTree() : 0;
                header->Options    = defaultTSOptions;
                header->ObjectSize = 0;

                int i;

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

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

            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 add to children tree.
            ObjectInfo info = childrenTree.Find(service, (uint)childName.GetHashCode());

            if (info == null)
            {
                // We simply create a new object at address.
                ChildTag childTag = new ChildTag();
                childTag.HashCode = childName.GetHashCode();
                childTag.Add(childName, commonAddress);
                byte[] childData = Common.SerializeToArray(childTag);

                // We write it to block stream.
                BlockStream stream = service.AllocationContext.CreateBlockStream((ulong)childData.LongLength);
                stream.Write(childData);

                // We now add it to B+ tree.
                childrenTree.Add(service, new ObjectInfo((uint)childName.GetHashCode(), (ulong)childData.LongLength, stream.BaseAddress));
            }
            else
            {
                // The index at hash already exists, we must add it, first read it.
                BlockStream stream   = BlockStream.FromBase(info.Address, service);
                ChildTag    childTag = Common.DeserializeFromArray(stream.Read(info.Size)) as ChildTag;

                // Steam not used anymore.
                stream.Deallocate();

                // We modify child tag.
                childTag.Add(childName, commonAddress);
                byte[] childData = Common.SerializeToArray(childTag);

                // We must write it to new address.
                stream = service.AllocationContext.CreateBlockStream((ulong)childData.LongLength);
                stream.Write(childData);

                // Now we replace the data in tree.
                childrenTree.Replace(service,
                                     new ObjectInfo((uint)childName.GetHashCode(), (ulong)childData.LongLength, stream.BaseAddress));
            }

            // 5) Add version to typed stream.
            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));
        }
Exemplo n.º 11
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);
        }
Exemplo n.º 12
0
        public unsafe void Execute(uint stage, IService service)
        {
            ulong versionAddress = service.AllocationContext.AllocateBlock();

            // 1) We first create new version node.
            Block versionBlock = new Block(service.BlockSize);

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

                header->CreationTime       = DateTime.Now;
                header->DefaultTypedStream = 0;
                header->HeaderMagic        = NodeVersionHeader.Magic;
                header->ModifiedTime       = DateTime.Now;
                header->NodeCommonAddress  = commonAddress;
                header->StreamCount        = 0; //< For now 0.
                header->VersionNumber      = version;
            }

            // 2) We create default TS.
            ulong defaultTSAddress = service.AllocationContext.AllocateBlock();
            Block block            = new Block(service.BlockSize);

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

                header->ObjectsAddress = (defaultTSOptions & StreamOptions.SingleObject) != 0
                    ? 0 : service.AllocationContext.CreateEmptyBTree();
                header->ObjectSize = 0;
                header->Options    = defaultTSOptions;

                // Copy the name.
                int i;

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

            service.Write(BlockType.TypedStreamHeader, defaultTSAddress, block);

            // 3) We add the default typed stream and write it.
            NodeVersionHelper.AddTypedStream(defaultTSAddress, defaultTSType, versionBlock);
            service.Write(BlockType.NodeHeaderBlock, versionAddress, versionBlock);

            // 4) And finnaly add to versions.
            ObjectInfo info = versionTree.Find(service, (uint)version.GetHashCode());

            if (info == null)
            {
                // Create block stream.
                VersionTag versionTag = new VersionTag(version.GetHashCode());
                versionTag.Add(version, versionAddress);
                byte[]      versionTagData = Common.SerializeToArray(versionTag);
                BlockStream stream         = service.AllocationContext.CreateBlockStream((ulong)versionTagData.LongLength);

                // Write the stream.
                stream.Write(versionTagData);

                // And to B+ tree.
                versionTree.Add(service, new ObjectInfo((uint)version.GetHashCode(),
                                                        (ulong)versionTagData.LongLength, stream.BaseAddress));;
            }
            else
            {
                // We first create appropriate VersionTag and kill the stream.
                BlockStream stream     = BlockStream.FromBase(info.Address, service);
                VersionTag  versionTag = Common.DeserializeFromArray(stream.Read(info.Size)) as VersionTag;
                versionTag.Add(version, versionAddress);
                stream.Deallocate();

                // We write a new version tag.
                byte[] versionTagData = Common.SerializeToArray(versionTag);
                stream = service.AllocationContext.CreateBlockStream((ulong)versionTagData.LongLength);
                stream.Write(versionTagData);

                // We replace in B+ tree.
                versionTree.Replace(service, new ObjectInfo((uint)version.GetHashCode(),
                                                            (ulong)versionTagData.LongLength, versionAddress));
            }

            // 5) The new version is replaced in common.
            block = service.Read(BlockType.NodeHeaderBlock, commonAddress);
            fixed(byte *p = block.Data)
            {
                NodeCommonHeader *header = (NodeCommonHeader *)p;

                header->CurrentVersionNumber  = version;
                header->CurrentVersionAddress = versionAddress;
            }

            service.Write(BlockType.NodeHeaderBlock, commonAddress, block);
        }