/// <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); } }
//--------------------------------------------------------------------- // 削除 //--------------------------------------------------------------------- /// <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); } }
//--------------------------------------------------------------------- // 追加 //--------------------------------------------------------------------- /// <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); } } }
/// <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)); }