public override void Apply(IOperationCollection operations) { Debug.Assert(operations.Count > 0); if (operations.AreAllMonotoneAndPoint) { SequentialApply(operations); //sequential mode optimization IsModified = true; return; } Locator locator = operations.Locator; Range range = Optimizator.FindRange(locator); foreach (var operation in operations) { int firstIndex, lastIndex; switch (operation.Scope) { case OperationScope.Point: { firstIndex = lastIndex = Optimizator.FindIndex(range, locator, operation.FromKey); Debug.Assert(firstIndex >= 0); } break; case OperationScope.Range: { firstIndex = Optimizator.FindIndex(range, locator, operation.FromKey); if (firstIndex < 0) firstIndex = 0; lastIndex = Optimizator.FindIndex(range, locator, operation.ToKey); } break; case OperationScope.Overall: { firstIndex = range.FirstIndex; if (range.IsBaseLocator && range.FirstIndex > 0) firstIndex--; lastIndex = range.LastIndex; } break; default: throw new NotSupportedException(operation.Scope.ToString()); } for (int i = firstIndex; i <= lastIndex; i++) { Branch branch = Branches[i].Value; branch.ApplyToCache(locator, operation); if (branch.NodeState != NodeState.None) HaveChildrenForMaintenance = true; } } IsModified = true; }
private bool SequentialApply(IOperationCollection operations, IOrderedSet<IData, IData> data) { switch (operations.CommonAction) { case OperationCode.REPLACE: case OperationCode.INSERT_OR_IGNORE: { foreach (var operation in operations) { ValueOperation opr = (ValueOperation)operation; data.UnsafeAdd(opr.FromKey, opr.Record); } return true; } case OperationCode.DELETE: { return false; } case OperationCode.DELETE_RANGE: case OperationCode.CLEAR: { throw new Exception("Logical error."); } default: throw new NotSupportedException(); } }
public override void Apply(IOperationCollection operations) { Locator locator = operations.Locator; IOrderedSet<IData, IData> data; if (Container.TryGetValue(locator, out data)) { RecordCount -= data.Count; if (locator.Apply.Leaf(operations, data)) IsModified = true; RecordCount += data.Count; if (data.Count == 0) Container.Remove(locator); } else { data = locator.OrderedSetFactory.Create(); Debug.Assert(data != null); if (locator.Apply.Leaf(operations, data)) IsModified = true; RecordCount += data.Count; if (data.Count > 0) Container.Add(locator, data); } }
public bool Leaf(IOperationCollection operations, IOrderedSet<IData, IData> data) { //sequential optimization if (operations.AreAllMonotoneAndPoint && data.IsInternallyOrdered && (data.Count == 0 || operations.Locator.KeyComparer.Compare(data.Last.Key, operations[0].FromKey) < 0)) return SequentialApply(operations, data); //common action optimization if (operations.CommonAction != OperationCode.UNDEFINED) return CommonApply(operations, data); //standart apply bool isModified = false; foreach (var opr in operations) { switch (opr.Code) { case OperationCode.REPLACE: { data[opr.FromKey] = ((ReplaceOperation)opr).Record; isModified = true; } break; case OperationCode.INSERT_OR_IGNORE: { if (data.ContainsKey(opr.FromKey)) continue; data[opr.FromKey] = ((InsertOrIgnoreOperation)opr).Record; isModified = true; } break; case OperationCode.DELETE: { if (data.Remove(opr.FromKey)) isModified = true; } break; case OperationCode.DELETE_RANGE: { if (data.Remove(opr.FromKey, true, opr.ToKey, true)) isModified = true; } break; case OperationCode.CLEAR: { data.Clear(); isModified = true; } break; default: throw new NotImplementedException(); } } return isModified; }
private bool CommonApply(IOperationCollection operations, IOrderedSet<IData, IData> data) { int commonAction = operations.CommonAction; int changes = 0; switch (commonAction) { case OperationCode.REPLACE: { foreach (var opr in operations) { data[opr.FromKey] = ((ReplaceOperation)opr).Record; changes++; } } break; case OperationCode.INSERT_OR_IGNORE: { foreach (var opr in operations) { if (data.ContainsKey(opr.FromKey)) continue; data[opr.FromKey] = ((InsertOrIgnoreOperation)opr).Record; changes++; } } break; case OperationCode.DELETE: { foreach (var opr in operations) { if (data.Remove(opr.FromKey)) changes++; } } break; case OperationCode.DELETE_RANGE: { foreach (var opr in operations) { if (data.Remove(opr.FromKey, true, opr.ToKey, true)) changes++; } } break; case OperationCode.CLEAR: { foreach (var opr in operations) { data.Clear(); changes++; break; } } break; default: throw new NotImplementedException(); } return changes > 0; }
public bool Internal(IOperationCollection operations) { return false; }
public void ApplyToCache(IOperationCollection operations) { lock (this) Cache.Apply(operations); }
private void SequentialApply(IOperationCollection operations) { Locator locator = operations.Locator; var last = Branches[Branches.Count - 1]; if (Object.ReferenceEquals(last.Key.Locator, locator) && locator.KeyComparer.Compare(last.Key.Key, operations[0].FromKey) <= 0) { Branch branch = last.Value; branch.ApplyToCache(operations); if (branch.NodeState != NodeState.None) HaveChildrenForMaintenance = true; return; } Range range = Optimizator.FindRange(locator); if (!range.IsBaseLocator) { Branch branch = Branches[range.LastIndex].Value; branch.ApplyToCache(operations); if (branch.NodeState != NodeState.None) HaveChildrenForMaintenance = true; return; } int index = 0; for (int i = range.FirstIndex; i <= range.LastIndex; i++) { var key = Branches[i].Key.Key; int idx = operations.BinarySearch(key, index, operations.Count - index); if (idx < 0) idx = ~idx; idx--; int count = idx - index + 1; if (count > 0) { var oprs = count < operations.Count ? operations.Midlle(index, count) : operations; var branch = Branches[i - 1].Value; branch.ApplyToCache(oprs); if (branch.NodeState != NodeState.None) HaveChildrenForMaintenance = true; index += count; } } if (operations.Count - index > 0) { var oprs = index > 0 ? operations.Midlle(index, operations.Count - index) : operations; var branch = Branches[range.LastIndex].Value; Debug.Assert(Branches[range.LastIndex].Key.Locator.Equals(oprs.Locator)); Debug.Assert(oprs.Locator.KeyComparer.Compare(Branches[range.LastIndex].Key.Key, oprs[0].FromKey) <= 0); branch.ApplyToCache(oprs); if (branch.NodeState != NodeState.None) HaveChildrenForMaintenance = true; } }
public abstract void Apply(IOperationCollection operations);
public void Execute(IOperationCollection operations) { if (disposed) throw new ObjectDisposedException("WTree"); lock (RootBranch) { if (!isRootCacheLoaded) LoadRootCache(); RootBranch.ApplyToCache(operations); if (RootBranch.Cache.OperationCount > INTERNAL_NODE_MAX_OPERATIONS_IN_ROOT) Sink(); } }