Exemple #1
0
        public void Execute(uint stage, SharpMedia.Database.Physical.Journalling.IService service)
        {
            // 1) We read previous object placement and change it.
            ObjectInfo  info     = childrenTree.Find(service, (uint)prevName.GetHashCode());
            BlockStream stream   = BlockStream.FromBase(info.Address, service);
            ChildTag    childTag = Common.DeserializeFromArray(stream.Read(info.Size)) as ChildTag;

            childTag.Remove(prevName);

            // Remove it if empty.
            if (childTag.IsEmpty)
            {
                childrenTree.Remove(service, (uint)prevName.GetHashCode(), 1, false);
            }
            else
            {
                // Update the entry (now without this child).
                byte[] childTagData = Common.SerializeToArray(childTag);
                stream = service.AllocationContext.CreateBlockStream((ulong)childTagData.LongLength);
                stream.Write(childTagData);

                childrenTree.Replace(service,
                                     new ObjectInfo((uint)prevName.GetHashCode(), (ulong)childTagData.LongLength, stream.BaseAddress));
            }

            // 3) We create new and insert it into tree.
            ObjectInfo info2 = childrenTree.Find(service, (uint)newName.GetHashCode());

            if (info2 == null)
            {
                // We create new tag.
                childTag = new ChildTag();
                childTag.Add(newName, info.Address);
                byte[] childTagData = Common.SerializeToArray(childTag);
                stream = service.AllocationContext.CreateBlockStream((ulong)childTagData.LongLength);
                stream.Write(childTagData);

                // And we add child.
                childrenTree.Add(service,
                                 new ObjectInfo((uint)newName.GetHashCode(), (ulong)childTagData.LongLength, stream.BaseAddress));
            }
            else
            {
                // We append it and release previous tag.
                stream   = BlockStream.FromBase(info2.Address, service);
                childTag = Common.DeserializeFromArray(stream.Read(info2.Size)) as ChildTag;
                stream.Deallocate();

                // We modify and rewrite it.
                childTag.Add(newName, info.Address);
                byte[] childTagData = Common.SerializeToArray(childTag);
                stream = service.AllocationContext.CreateBlockStream((ulong)childTagData.LongLength);
                stream.Write(childTagData);

                // We insert into children tree.
                childrenTree.Replace(service,
                                     new ObjectInfo((uint)newName.GetHashCode(), (ulong)childTagData.LongLength, info.Address));
            }
        }
Exemple #2
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));
        }