/// <summary> /// Универсальный метод привязки ключа к индексу с возвращением его значения /// встраивает элемент в индекс и опционально встраивает ссылку на факт в данные индекса /// </summary> /// <param name="uid"></param> /// <param name="keydata"></param> /// <param name="data">optional - joined sub value ref to fact</param> /// <returns></returns> public void EnsureValue(TKey uid, TKeyData keydata = default(TKeyData), TData[] data = null) { var existed = Values.FirstOrDefault(_ => _.Key.Equals(uid)); if (null != existed) { if (Index.SelfDataOnly && !keydata.Equals(default(TKeyData))) { existed.Value = keydata; } else { if (null != data && 0 != data.Length) { Index.AppendData(existed.Value, data); } } return; } if (IsLeaf) { //если это лист, то в любом случае встаиваем bool wasfull = IsFull; StoreHere(uid, keydata, data); if (wasfull) { // если на момент присоединения лист уже был полон, то сплитим DoSplit(); } } else { DownFallValue(uid, keydata, data); } }
/// <summary> /// Метод встраивания значения в текущий букет - добавляет к набору если отсутствует и переупорядочивает /// </summary> /// <param name="uid"></param> /// <param name="keydata"></param> /// <param name="data"></param> private void StoreHere(TKey uid, TKeyData keydata, TData[] data) { BTreeValue <TKey, TKeyData, TData> value = null; if (Index.SelfDataOnly) { value = new BTreeValue <TKey, TKeyData, TData> { Key = uid, Value = keydata }; } else { value = new BTreeValue <TKey, TKeyData, TData> { Key = uid, Value = Index.CreateDataStorage() }; } value.ContainingBucket = this; int insertIndex = -1; for (var i = 0; i < Values.Count; i++) { if (Values[i].Key.CompareTo(uid) > 0) { insertIndex = i; break; } } if (-1 == insertIndex) { Values.Add(value); } else { Values.Insert(insertIndex, value); } MarkChanged(); if (null != data && 0 != data.Length) { Index.AppendData(value.Value, data); } }