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 void Execute(uint stage, SharpMedia.Database.Physical.Journalling.IService service)
        {
            Debug.Assert(stage == 0);

            // 1) We first write to allocated block stream.
            BlockStream stream = service.AllocationContext.CreateBlockStream((ulong)objectData.LongLength);

            stream.Write(objectData);

            // 2) We may need to delete object at index.
            ObjectInfo data = tree.Find(service, index);

            if (data != null)
            {
                // Deallocate link.
                BlockStream stream2 = BlockStream.FromBase(data.Address, service);
                stream2.Deallocate();

                // We replace the entry (cheaper than delete and rewrite).
                tree.Replace(service, new ObjectInfo(index, (ulong)objectData.LongLength, stream.BaseAddress));
            }
            else
            {
                // 3) We execute insert operation.
                tree.Add(service, new ObjectInfo(index, (ulong)objectData.LongLength, stream.BaseAddress));
            }
        }
Exemple #3
0
        public static IEnumerable <TResult> Join <TKey, TOuter, TInner, TIndex, TResult>(
            IDictionary <TKey, TOuter> outer,
            IDictionary <TKey, TInner> inner,
            Func <TOuter, TIndex> outKeySelector,
            Func <TInner, TIndex> innerKeySelector,
            Func <TOuter, TInner, TResult> resultSelector,
            BPlusTree <TIndex, TKey> btree)
            where TIndex : IComparable <TIndex>
        {
            var outerEnum = outer.GetEnumerator();

            outerEnum.Reset();
            while (outerEnum.MoveNext())
            {
                var item = outerEnum.Current.Value;
                var g    = btree.Find(outKeySelector(item)).Select(id => inner[id]).ToArray();
                if (g != null)
                {
                    for (int i = 0; i < g.Length; i++)
                    {
                        yield return(resultSelector(item, g[i]));
                    }
                }
            }
        }
Exemple #4
0
        /// <summary>
        /// Executes the operation.
        /// </summary>
        /// <param name="service">Service for operation.</param>
        unsafe void ExecuteInternal(IService service)
        {
            ulong childrenTS;
            ulong versionTS;

            // 1) We extract child TS and version TS
            Block block = service.Read(BlockType.NodeHeaderBlock, commonAddress);

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

                childrenTS = header->ChildrenBTree;
                versionTS  = header->VersionsBTree;
            }

            // 2) Can get rid of node.
            service.DeAllocate(commonAddress);

            // 3) We delete children TS, it should be empty (since deletes were already called on nodes).
            service.DeAllocate(childrenTS);

            // 4) We go through versions.
            BPlusTree         versionsTree = new BPlusTree(versionTS);
            List <ObjectInfo> versions     = versionsTree.ListAll(service);

            // 5) We delete each version.
            foreach (ObjectInfo info in versions)
            {
                // a) Read version tag.
                BlockStream versionTagStream = BlockStream.FromBase(info.Address, service);
                VersionTag  versionTag       = Common.DeserializeFromArray(versionTagStream.Read(info.Size)) as VersionTag;
                versionTagStream.Deallocate();

                foreach (KeyValuePair <ulong, ulong> versionToNode in versionTag.VersionAddress)
                {
                    block = service.Read(BlockType.NodeHeaderBlock, versionToNode.Value);

                    List <ulong> typedStreams = NodeVersionHelper.ListAllTypedStreamsAsAddresses(block, service);

                    // b) Delete all typed streams.
                    for (int i = 0; i < typedStreams.Count; i++)
                    {
                        // 1) We delete the typed stream object.
                        block = service.Read(BlockType.TypedStreamHeader, typedStreams[i]);
                        fixed(byte *p = block.Data)
                        {
                            TypedStreamHeader *header = (TypedStreamHeader *)p;

                            // We delete single object.
                            if ((header->Options & StreamOptions.SingleObject) != 0)
                            {
                                if (header->ObjectsAddress != 0)
                                {
                                    BlockStream stream = BlockStream.FromBase(header->ObjectsAddress, service);
                                    stream.Deallocate();
                                }
                            }
                            else
                            {
                                // We delete all children.
                                BPlusTree tree = new BPlusTree(header->ObjectsAddress);
                                foreach (ObjectInfo info2 in tree.ListAll(service))
                                {
                                    BlockStream stream = BlockStream.FromBase(info2.Address, service);
                                    stream.Deallocate();
                                }
                            }
                        }

                        // 2) We also delete the header itself.
                        service.DeAllocate(typedStreams[i]);
                    }

                    // c) We deallocate version block.
                    service.DeAllocate(versionToNode.Value);
                }
            }

            // 6) We delete the tree.
            versionsTree.DeallocateTree(service);

            // 7) We must erase the node from root.
            ObjectInfo  childInfo      = parentChildTree.Find(service, (uint)childName.GetHashCode());
            BlockStream childTagStream = BlockStream.FromBase(childInfo.Address, service);

            byte[]   childTagData = childTagStream.Read(childInfo.Size);
            ChildTag childTag     = Common.DeserializeFromArray(childTagData) as ChildTag;

            childTagStream.Deallocate();

            if (childTag.Children.Count == 1)
            {
                // Simply delete it.
                parentChildTree.Remove(service, (uint)childName.GetHashCode(), 1, false);
            }
            else
            {
                // We have to replace it.
                childTag.Remove(childName);
                childTagData   = Common.SerializeToArray(childTag);
                childTagStream = service.AllocationContext.CreateBlockStream((ulong)childTagData.LongLength);
                childTagStream.Write(childTagData);

                parentChildTree.Replace(service, new ObjectInfo((uint)childName.GetHashCode(),
                                                                (ulong)childTagData.LongLength, childTagStream.BaseAddress));
            }
        }
Exemple #5
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));
        }
Exemple #6
0
        static void Main(string[] args)
        {
            int j = 0;

            Random    rand = new Random();
            Stopwatch sw   = new Stopwatch();

            Console.Write("Enter count: ");
            int count = int.Parse(Console.ReadLine());

            Console.Write("Enter degree: ");
            int degree = int.Parse(Console.ReadLine());

            Console.Write("Enter alpha: ");
            double alpha = double.Parse(Console.ReadLine());


            BPlusTree <int, int> tree = new BPlusTree <int, int>(degree, alpha);



            Console.Clear();

            if (Console.ReadLine().ToLower() == "y")
            {
                sw.Reset();
                sw.Start();
                for (int i = 0; i < count; i++)
                {
                    tree.Add(i * 10, i * 10);
                }
                sw.Stop();
                Console.WriteLine("Adding ascending sequence takes {0:f3} s", (double)sw.ElapsedMilliseconds / 1000);


                sw.Reset();
                sw.Start();
                for (int i = 0; i < count; i++)
                {
                    tree.Find(rand.Next(count), out j);
                }
                sw.Stop();
                Console.WriteLine("Finding in ascending sequence takes {0:f3} s", (double)sw.ElapsedMilliseconds / 1000);

                GetObjectSize(tree);


                sw.Reset();
                sw.Start();
                for (int i = 0; i < count; i++)
                {
                    tree.Remove(i * 10);
                }
                sw.Stop();
                Console.WriteLine("Removing from ascending sequence takes {0:f3} s", (double)sw.ElapsedMilliseconds / 1000);
            }



            if (Console.ReadLine().ToLower() == "y")
            {
                List <int> elements = new List <int>();
                for (int i = 0; i < count; i++)
                {
                    elements.Add(i * 10);
                }

                Sort <int> .SortOut(elements);

                Sort <int> .SortOut(elements);

                Sort <int> .SortOut(elements);

                Sort <int> .SortOut(elements);

                Sort <int> .SortOut(elements);

                sw.Reset();
                sw.Start();
                for (int i = 0; i < count; i++)
                {
                    tree.Add(elements[i], elements[i]);
                }
                sw.Stop();
                Console.WriteLine("Adding random sequence takes {0:f3} s", (double)sw.ElapsedMilliseconds / 1000);


                sw.Reset();
                sw.Start();
                for (int i = 0; i < count; i++)
                {
                    tree.Find(rand.Next(count), out j);
                }
                sw.Stop();
                Console.WriteLine("Finding in ascending sequence takes {0:f3} s", (double)sw.ElapsedMilliseconds / 1000);

                GetObjectSize(tree);


                sw.Reset();
                sw.Start();
                for (int i = 0; i < count; i++)
                {
                    tree.Remove(elements[i]);
                }
                sw.Stop();
                Console.WriteLine("Removing from ascending sequence takes {0:f3} s", (double)sw.ElapsedMilliseconds / 1000);



                Console.ReadLine();
            }
        }
        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);
        }