Пример #1
0
        public void Insert(TableRawDataEntry entry, ILowLevelTransaction tx)
        {
            if (entry.PrimaryKey == null || entry.PrimaryKey.Length == 0)
            {
                throw new ArgumentException("primary key can not be empty!");
            }

            var primaryTree = GetPrimaryTree(tx);

            if (primaryTree == null)
            {
                throw new InvalidOperationException($"load table's primary tree faield,table name:{Name}");
            }

            //if (!IsDefinedSecondaryIndex)
            //{
            //    primaryTree.AddEntry(entry, tx);
            //    return;
            //}

            ////插入聚集索引
            //primaryTree.AddEntry(entry, tx);
            //插入二级索引
            InsertSecondaryIndexEntries(entry, tx);
        }
Пример #2
0
 public void Init(ILowLevelTransaction tx)
 {
     if (_root == null)
     {
         _root = AllocateEntry(tx, TreeNodeFlags.Leaf, null, 0).Page;
     }
 }
Пример #3
0
        public Tree GetPrimaryTree(ILowLevelTransaction tx)
        {
            if (_primaryTree == null)
            {
                _primaryTree = GetTree(_schema.Primary.Name, tx);
            }

            return(_primaryTree);
        }
Пример #4
0
        /// <summary>
        /// </summary>
        /// <param name="tx"></param>
        /// <param name="page"></param>
        /// <returns></returns>
        public static OverflowPage ModifyPage(this ILowLevelTransaction tx, OverflowPage page)
        {
            var newPage = tx.ModifyPage(page.StoreId, page.PageNumber);

            if (newPage == null)
            {
                throw new InvalidOperationException($"modify page failed,pagerid:{page.StoreId},pagenumber:{page.PageNumber}");
            }

            return(newPage.AsOverflow());
        }
Пример #5
0
        public static TreePage[] AllocateTrees(this ILowLevelTransaction tx, int pagerId, uint count)
        {
            var pages     = tx.AllocatePage(pagerId, count);
            var treePages = new TreePage[count];

            for (var i = 0; i < treePages.Length; i++)
            {
                treePages[i] = pages[i].AsTree();
            }

            return(treePages);
        }
Пример #6
0
        public Span <byte> GetValue(ILowLevelTransaction tx, Span <byte> key)
        {
            var cursor = BuildCursor(tx, key);

            if (cursor != null && cursor.Entry != null && cursor.Entry.Page != null)
            {
                cursor.Entry.Search(key);

                return(cursor.Entry.GetNodeData(cursor.Entry.LastMatchIndex));
            }

            return(Span <byte> .Empty);
        }
Пример #7
0
        public void Update(TableRawDataEntry entry, ILowLevelTransaction tx)
        {
            if (entry.PrimaryKey == null || entry.PrimaryKey.Length == 0)
            {
                throw new ArgumentException("primary key can not be empty!");
            }

            var primaryTree = GetPrimaryTree(tx);

            if (primaryTree == null)
            {
                throw new InvalidOperationException($"load table's primary tree faield,table name:{Name}");
            }
        }
Пример #8
0
        //public unsafe void Insert(ILowLevelTransaction tx, TreeNodeDataEntry data)
        //{
        //    var cursor = BuildCursor(tx, data.Key);
        //    var match = SearchForKey(cursor.Entry, data.Key);
        //    if (match == 0 && _isUnique)
        //    {
        //        throw new InvalidCastException($"mulpti key");
        //    }

        //    if (!ModifyEntry(cursor.Entry, tx))
        //    {
        //        throw new InvalidOperationException($"modify page failed!");
        //    }

        //    Insert(tx, cursor.Entry, data);
        //}

        //private unsafe void Insert(ILowLevelTransaction tx, TreePageEntry entry, TreeNodeDataEntry data)
        //{
        //    var size = data.Size;
        //    if (size >= PageEntryMaxDataSize)
        //    {
        //        InsertOverflow(tx, entry, data);
        //        return;
        //    }

        //    if (entry.Allocate(entry.LastMatchIndex, (ushort)size, TreeNodeHeaderFlags.Data, out var pos))
        //    {
        //        entry.InsertDataNode(entry.LastMatchIndex, pos, data, 0l);
        //        return;
        //    }

        //    var index = Balance(tx, entry, data.Key, entry.LastMatchIndex);
        //    if (index <= entry.LastMatchIndex)
        //    {
        //        //add to new right page
        //        entry.LastMatchIndex = entry.LastMatchIndex - index;
        //    }

        //    if (!entry.Allocate(entry.LastMatchIndex, (ushort)size, TreeNodeHeaderFlags.Data, out pos))
        //    {
        //        throw new InvalidOperationException("allocate node space faild!");
        //    }

        //    entry.InsertDataNode(entry.LastMatchIndex, pos, data, 0l);
        //}

        //public void InsertOverflow(ILowLevelTransaction tx, TreePageEntry entry, TreeNodeDataEntry data)
        //{
        //    var size = data.Key.Size;
        //    var dataSize = data.Value.Size;
        //    var overflowPages = AllocateOverflows(tx, dataSize);

        //    for (var i = 0; i < overflowPages.Length; i++)
        //    {
        //        var pageSize = Math.Min(OverflowPage.Capacity, dataSize);

        //        overflowPages[i].Write(Constants.PageHeaderSize, data.Value.Data.Slice(i * OverflowPage.Capacity, pageSize));

        //        dataSize -= pageSize;
        //    }

        //    if (entry.Allocate(entry.LastMatchIndex, (ushort)size, TreeNodeHeaderFlags.Data, out var pos))
        //    {
        //        entry.InsertPageRefNode(entry.LastMatchIndex, pos, data.Key, overflowPages[0].Header.PageNumber);
        //        return;
        //    }

        //    var index = Balance(tx, entry, data.Key, entry.LastMatchIndex);
        //    if (index <= entry.LastMatchIndex)
        //    {
        //        //add to new right page
        //        entry.LastMatchIndex = entry.LastMatchIndex - index;
        //    }

        //    if (!entry.Allocate(entry.LastMatchIndex, (ushort)size, TreeNodeHeaderFlags.Data, out pos))
        //    {
        //        throw new InvalidOperationException("allocate node space faild!");
        //    }

        //    entry.InsertPageRefNode(entry.LastMatchIndex, pos, data.Key, overflowPages[0].Header.PageNumber);
        //}

        //public unsafe int Balance(ILowLevelTransaction tx, TreePageEntry entry, TreeNodeDataSlice key, int midIndex)
        //{
        //    var newEntry = AllocateEntry(tx, entry.Header.NodeFlags, entry.Parent, entry.Index + 1);
        //    if (newEntry == null)
        //    {
        //        throw new InvalidOperationException("allocate new page failed!");
        //    }

        //    var balanceIndex = entry.CopyEntriesToNewPage(midIndex, newEntry.Page);
        //    if (balanceIndex > midIndex)
        //    {
        //        Balance(tx, entry, newEntry, newEntry.MinKey);

        //        return balanceIndex;
        //    }

        //    var index = midIndex - balanceIndex;
        //    var newKey = index > 0 ? newEntry.MinKey : key;

        //    Balance(tx, entry, newEntry, newKey);

        //    entry.Page = newEntry.Page;
        //    entry.Index = newEntry.Index;

        //    return balanceIndex;
        //}

        //public unsafe void Balance(ILowLevelTransaction tx, TreePageEntry curEntry, TreePageEntry newEntry, TreeNodeDataSlice key)
        //{
        //    var parent = curEntry.Parent;
        //    if (parent != null && parent.Page != null)
        //    {
        //        ModifyEntry(parent, tx);
        //        Balance(tx, parent, curEntry, newEntry, key);
        //        return;
        //    }

        //    var entry = AllocateEntry(tx, curEntry.Header.NodeFlags, null, curEntry.Index);
        //    if (entry == null)
        //    {
        //        throw new NullReferenceException(nameof(entry));
        //    }

        //    parent = new TreePageEntry(curEntry.Page, 0, null);

        //    newEntry.Parent = parent;
        //    curEntry.Parent = parent;
        //    curEntry.Page = entry.Page;
        //    curEntry.Index = entry.Index;

        //    parent.Page.CopyTo(entry.Page);
        //    parent.Page.Clear();
        //    parent.Page.Header.NodeFlags = TreeNodeFlags.Branch;

        //    Balance(tx, parent, curEntry, newEntry, key);
        //}

        //public unsafe void Balance(ILowLevelTransaction tx, TreePageEntry parent, TreePageEntry curEntry, TreePageEntry newEntry, TreeNodeDataSlice key)
        //{
        //    var index = curEntry.Index;
        //    if (parent.Page.Header.ItemCount == 0)
        //    {
        //        curEntry.Index = 0;
        //        newEntry.Index = 1;

        //        parent.Allocate(0, (ushort)key.Size, TreeNodeHeaderFlags.PageRef, out var curPos);
        //        parent.Page.Allocate(1, 0, TreeNodeHeaderFlags.PageRef, out var newPos);

        //        parent.InsertPageRefNode(0, curPos, key, curEntry.Header.PageNumber);
        //        parent.InsertPageRefNode(1, newPos, new TreeNodeDataSlice(), newEntry.Header.PageNumber);
        //        return;
        //    }

        //    if (!parent.Allocate(index, (ushort)key.Size, TreeNodeHeaderFlags.PageRef, out var pos))
        //    {
        //        var halfIndex = parent.Header.ItemCount / 2;
        //        var halfKey = parent.GetNodeKey(halfIndex - 1);
        //        var balanceIndex = Balance(tx, parent, halfKey, halfIndex);
        //        if (balanceIndex <= halfIndex && balanceIndex <= curEntry.Index)
        //        {
        //            index = curEntry.Index - balanceIndex;
        //            newEntry.Index = index + 1;
        //        }
        //        else if (balanceIndex > halfIndex && balanceIndex < curEntry.Index)
        //        {
        //            index = curEntry.Index - balanceIndex - 1;
        //            newEntry.Index = index + 1;
        //        }

        //        if (!parent.Page.Allocate(index, (ushort)key.Size, TreeNodeHeaderFlags.PageRef, out pos))
        //        {
        //            throw new InvalidOperationException($"balance page:{parent.Page.Header.PageNumber} failed!");
        //        }
        //    }

        //    parent.Page[index + 1].PageNumber = newEntry.Header.PageNumber;
        //    parent.Page.InsertPageRefNode(index, pos, key, curEntry.Header.PageNumber);
        //}

        private TreeCursor BuildCursor(ILowLevelTransaction tx, Span <byte> key)
        {
            if (_root == null)
            {
                _root = tx.GetPage(0, 0).AsTree();
            }

            var entry = new TreePageEntry(_root, 0, null);

            while (entry.SearchPageIfBranch(tx, key, out var page))
            {
                entry = new TreePageEntry(page, entry.LastMatchIndex, entry);
            }

            return(new TreeCursor(new Memory <byte>(key.ToArray()), tx, entry));
        }
Пример #9
0
        public static OverflowPage[] AllocateOverflows(this ILowLevelTransaction tx, int pagerId, uint count)
        {
            var pages     = tx.AllocatePage(pagerId, count);
            var overflows = new OverflowPage[count];

            for (var i = 0; i < overflows.Length; i++)
            {
                if (i == 0)
                {
                    overflows[i] = pages[i].AsOverflow();
                    continue;
                }

                overflows[i] = pages[i].AsOverflow();
                overflows[i - 1].Header.NextPageNumber = overflows[i].PageNumber;
            }

            return(overflows);
        }
Пример #10
0
        private bool ModifyEntry(TreePageEntry entry, ILowLevelTransaction tx)
        {
            var lastMatch      = entry.LastMatch;
            var lastMatchIndex = entry.LastMatchIndex;

            var newPage = tx.ModifyPage(entry.Page);

            if (newPage == null)
            {
                return(false);
            }

            entry.Page           = newPage;
            entry.LastMatch      = lastMatch;
            entry.LastMatchIndex = lastMatchIndex;

            State.OnChanged(entry.Page, TreePageChangeFlags.Modify);
            return(true);
        }
Пример #11
0
 public void AddEntry(ILowLevelTransaction tx, ValueEncodingByteString key, ValueEncodingByteString value)
 {
     AddEntry(tx, key.Values, value.Values);
 }
Пример #12
0
 /// <summary>
 /// </summary>
 /// <param name="tx"></param>
 /// <param name="page"></param>
 /// <returns></returns>
 public static Page ModifyPage(this ILowLevelTransaction tx, int storeId, long pageNumber)
 {
     return(tx.ModifyPage(new PageNumberInfo(storeId, pageNumber)));
 }
Пример #13
0
 public void CleanEntry(ILowLevelTransaction tx, Span <byte> key)
 {
 }
Пример #14
0
 public void CleanEntry(ILowLevelTransaction tx, ValueEncodingByteString key)
 {
     CleanEntry(tx, key.Values);
 }
Пример #15
0
 public void RemoveEntry(ILowLevelTransaction tx, Span <byte> key)
 {
 }
Пример #16
0
 public void RemoveEntry(ILowLevelTransaction tx, EncodingByteString key)
 {
     RemoveEntry(tx, key.Values);
 }
Пример #17
0
 public void AddEntry(ILowLevelTransaction tx, Span <byte> key, Span <byte> value)
 {
 }
Пример #18
0
 public Tree GetTree(EncodingByteString name, ILowLevelTransaction tx)
 {
     return(_trees.GetOrAdd(name, k => tx.OpenTree(name)));
 }
Пример #19
0
 public TreeCursor Get(ILowLevelTransaction tx, Span <byte> key)
 {
     return(BuildCursor(tx, key));
 }
Пример #20
0
        private unsafe TreePageEntry AllocateEntry(ILowLevelTransaction tx, TreeNodeFlags nodeFlags, TreePageEntry parent, int index)
        {
            var page = tx.AllocateTrees(Id, 1)[0];

            ref var header = ref page.Header;
Пример #21
0
 public TreeCursor(Memory <byte> key, ILowLevelTransaction tx, TreePageEntry entry)
 {
     _key  = key;
     _tx   = tx;
     Entry = entry;
 }
Пример #22
0
 /// <summary>
 /// 插入二级索引项
 /// </summary>
 /// <param name="entry"></param>
 /// <param name="tx"></param>
 private void InsertSecondaryIndexEntries(TableRawDataEntry entry, ILowLevelTransaction tx)
 {
     throw new NotImplementedException();
 }