/// <summary>枝要素の分割を行う。</summary>
            /// <param name="element">追加する要素。</param>
            /// <param name="idx">追加位置。</param>
            /// <param name="parent">木構造。</param>
            /// <param name="manage">処理結果。</param>
            private void Split(IBParts element, int idx, BPlusTree <T> parent, ref ManageResult manage)
            {
                var tmpNext = new BBranch(parent.bracketSize);

                if (idx < parent.mSize + 1)
                {
                    // 後半部分はコピー
                    tmpNext.Count = parent.mSize + 1;
                    Array.Copy(this.value, parent.mSize, tmpNext.value, 0, parent.mSize + 1);

                    // 前半部は挿入
#if DEBUG
                    Array.Clear(this.value, parent.mSize, this.value.Length - parent.mSize);
#endif
                    this.Count = parent.mSize + 1;
                    if (parent.mSize + 1 > idx)
                    {
                        Array.Copy(this.value, idx, this.value, idx + 1, (parent.mSize + 1) - idx);
                    }
                    this.value[idx] = element;
                }
                else
                {
                    // 後半部分に挿入
                    int ptr = idx - (parent.mSize + 1);
                    tmpNext.Count = parent.mSize + 1;
                    if (ptr > 0)
                    {
                        Array.Copy(this.value, parent.mSize + 1, tmpNext.value, 0, ptr);
                    }
                    Array.Copy(this.value, idx, tmpNext.value, ptr + 1, parent.bracketSize - idx);
                    tmpNext.value[ptr] = element;

                    // 前半部分は変更なし
#if DEBUG
                    Array.Clear(this.value, parent.mSize + 1, this.value.Length - (parent.mSize + 1));
#endif
                    this.Count = parent.mSize + 1;
                }

                // 検索キー参照変更
                tmpNext.headerLeaf = tmpNext.TraverseLeaf;

                // 新しく生成した要素を返す
                manage.newParts = tmpNext;
            }
            //---------------------------------------------------------------------
            // 削除
            //---------------------------------------------------------------------
            /// <summary>指定要素を取得する。</summary>
            /// <param name="item">削除する要素。</param>
            /// <param name="parent">木構造。</param>
            /// <param name="remove">削除状態。</param>
            /// <returns>バランス調整が必要ならば真。</returns>
            public bool Remove(T item, BPlusTree <T> parent, ref RemoveResult remove)
            {
                int lf = 0;
                int rt = this.Count - 1;
                int md;

                // 削除要素の検索
                while (lf < rt)
                {
                    md = lf + (rt - lf) / 2 + 1;

                    if (parent.defComp.Compare(this.value[md].HeaderItem, item) >= 0)
                    {
                        rt = md - 1;
                    }
                    else
                    {
                        lf = md;
                    }
                }

                // 要素を削除する
                if (this.value[lf].Remove(item, parent, ref remove))
                {
                    if (this.value[lf].Count <= parent.mSize)
                    {
                        this.BalanceChangeOfBParts(parent, lf);
                    }
                    return(true);
                }
                else if (lf + 1 < this.Count &&
                         parent.defComp.Compare(this.value[lf + 1].HeaderItem, item) == 0 &&
                         this.value[lf + 1].Remove(item, parent, ref remove))
                {
                    if (this.value[lf + 1].Count <= parent.mSize)
                    {
                        this.BalanceChangeOfBParts(parent, lf + 1);
                    }
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
Beispiel #3
0
            //---------------------------------------------------------------------
            // 削除
            //---------------------------------------------------------------------
            /// <summary>指定要素を取得する。</summary>
            /// <param name="item">削除する要素。</param>
            /// <param name="parent">木構造。</param>
            /// <param name="remove">削除状態。</param>
            /// <returns>バランス調整が必要ならば真。</returns>
            public bool Remove(T item, BPlusTree <T> parent, ref RemoveResult remove)
            {
                int lf = 0;
                int rt = this.Count;
                int md;

                // 位置の検索
                while (lf < rt)
                {
                    md = lf + (rt - lf) / 2;

                    if (parent.defComp.Compare(this.value[md], item) < 0)
                    {
                        lf = md + 1;
                    }
                    else
                    {
                        rt = md;
                    }
                }

                if (lf < this.Count &&
                    parent.defComp.Compare(this.value[lf], item) == 0)
                {
                    if (lf < this.Count - 1)
                    {
                        Array.Copy(this.value, lf + 1, this.value, lf, this.Count - (lf + 1));
                    }
#if DEBUG
                    Array.Clear(this.value, this.Count - 1, 1);
#endif
                    // 項目数を減少
                    this.Count--;
                    parent.Count--;
                    remove.changed = true;
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
Beispiel #4
0
            //---------------------------------------------------------------------
            // 追加
            //---------------------------------------------------------------------
            /// <summary>木要素に要素を追加する。</summary>
            /// <param name="item">追加する項目。</param>
            /// <param name="parent">B+木コレクション。</param>
            /// <param name="manage">処理結果。</param>
            /// <returns>追加できたならば真。</returns>
            public bool Add(T item, BPlusTree <T> parent, ref ManageResult manage)
            {
                if (this.Count <= 0)
                {
                    // 要素が一つもなければ先頭に追加する
                    this.value[0] = item;
                    this.Count++;
                    parent.Count++;
                    manage.changed = true;
                    return(false);
                }
                else
                {
                    // 挿入位置を検索する
                    int idx = BinarySearchOfAdd(item, parent.defComp);

                    if (this.Count < parent.bracketSize)
                    {
                        // 挿入位置に値を挿入
                        if (this.Count > idx)
                        {
                            Array.Copy(this.value, idx, this.value, idx + 1, this.Count - idx);
                        }
                        this.value[idx] = item;

                        this.Count++;
                        parent.Count++;
                        manage.changed = true;
                        return(false);
                    }
                    else
                    {
                        // 領域サイズを超えたので分割する
                        this.Split(item, idx, parent, ref manage);
                        parent.Count++;
                        manage.changed = true;
                        return(true);
                    }
                }
            }
Beispiel #5
0
            /// <summary>リストに指定項目が登録されているか検索し、あれば取得する。</summary>
            /// <param name="item">検索項目。</param>
            /// <param name="resultvalue">取得結果。</param>
            /// <param name="parent">B+木コレクション。</param>
            /// <returns>存在すれば真。</returns>
            public bool TryGetValue(T item, out T resultvalue, BPlusTree <T> parent)
            {
                int lf = 0;
                int rt = this.Count;
                int md;

                // 位置の検索
                while (lf < rt)
                {
                    md = lf + (rt - lf) / 2;

                    if (parent.defComp.Compare(this.value[md], item) < 0)
                    {
                        lf = md + 1;
                    }
                    else
                    {
                        rt = md;
                    }
                }

                if (lf < this.Count &&
                    parent.defComp.Compare(this.value[lf], item) == 0)
                {
                    resultvalue = this.value[lf];
                    return(true);
                }
                else if (this.NextLeaf != null &&
                         parent.defComp.Compare(this.NextLeaf.value[0], item) == 0)
                {
                    resultvalue = this.NextLeaf.value[0];
                    return(true);
                }
                else
                {
                    resultvalue = default(T);
                    return(false);
                }
            }
            //---------------------------------------------------------------------
            // その他
            //---------------------------------------------------------------------
            /// <summary>リストに指定項目が登録されているか検索し、あれば取得する。</summary>
            /// <param name="item">検索項目。</param>
            /// <param name="resultvalue">取得結果。</param>
            /// <param name="parent">B+木コレクション。</param>
            /// <returns>存在すれば真。</returns>
            public bool TryGetValue(T item, out T resultvalue, BPlusTree <T> parent)
            {
                int lf = 0;
                int rt = this.Count - 1;
                int md;

                // 挿入位置の検索
                while (lf < rt)
                {
                    md = lf + (rt - lf) / 2 + 1;

                    if (parent.defComp.Compare(this.value[md].HeaderItem, item) >= 0)
                    {
                        rt = md - 1;
                    }
                    else
                    {
                        lf = md;
                    }
                }

                // 存在を確認する
                return(this.value[lf].TryGetValue(item, out resultvalue, parent));
            }
            /// <summary>指定した項目が最後に見つかったインデックスを取得する。</summary>
            /// <param name="item">検索する要素。</param>
            /// <returns>要素のインデックス。見つからなかったら -1。</returns>
            public int LastIndexOf(T item, BPlusTree <T> parent)
            {
                int lf = 0;
                int rt = this.Count - 1;
                int md;

                // 挿入位置の検索
                while (lf < rt)
                {
                    md = lf + (rt - lf) / 2 + 1;

                    if (parent.defComp.Compare(this.value[md].HeaderItem, item) > 0)
                    {
                        rt = md - 1;
                    }
                    else
                    {
                        lf = md;
                    }
                }

                // 存在を確認する
                return(this.value[lf].LastIndexOf(item, parent));
            }
            /// <summary>指定要素未満のインデックスを検索する。</summary>
            /// <param name="item">検索項目。</param>
            /// <param name="parent">B+木コレクション。</param>
            /// <returns>検索結果。</returns>
            public SearchResult SearchOfLt(T item, BPlusTree <T> parent)
            {
                int lf = 0;
                int rt = this.Count - 1;
                int md;

                // 位置の検索
                while (lf < rt)
                {
                    md = lf + (rt - lf) / 2 + 1;

                    if (parent.defComp.Compare(this.value[md].HeaderItem, item) >= 0)
                    {
                        rt = md - 1;
                    }
                    else
                    {
                        lf = md;
                    }
                }

                // 存在を確認する
                return(this.value[lf].SearchOfLt(item, parent));
            }