/// <summary> /// applies an operation tree to the list. this is done wihout reallicating the underlying array (unless it's capcity is exceeded) /// </summary> /// <typeparam name="S"></typeparam> /// <param name="operations">the operation tree</param> /// <param name="convert">converts an item in the operation tree to an item of the list</param> public void ApplyOperations <S>(OperationTree <S> operations, Func <S, T> convert) { int newCount = mCount + operations.IndexBalance; EnsureCapacity(newCount); mWorkQueue.Clear(); int writeIndex = 0; int readIndex = 0; bool hasDequeValue = false; T dequeValue = default(T); OperationTree <S> .OperationNode lastOp = new OperationTree <S> .OperationNode(newCount, default(S), OperationTree <S> .OperationType.EndOp, 1); foreach (OperationTree <S> .OperationNode op in operations.OperationData(lastOp)) { for (; writeIndex < op.Index; writeIndex++, readIndex++) { if (readIndex < mCount) { mWorkQueue.Enqueue(mData[readIndex]); } if (hasDequeValue) { hasDequeValue = false; mData[writeIndex] = dequeValue; if (mWorkQueue.Count > 0) { mWorkQueue.Dequeue(); } } else { if (mWorkQueue.Count > 0) { mData[writeIndex] = mWorkQueue.Dequeue(); } } } switch (op.Operation) { case OperationTree <S> .OperationType.Insert: if (readIndex < mCount) { mWorkQueue.Enqueue(mData[readIndex]); } mData[writeIndex] = convert(op.Value); writeIndex++; readIndex++; break; case OperationTree <S> .OperationType.Set: hasDequeValue = true; dequeValue = convert(op.Value); break; case OperationTree <S> .OperationType.Remove: int i = op.Count; for (; mWorkQueue.Count > 0 && i > 0; --i) { mWorkQueue.Dequeue(); } readIndex += i; break; default: break; } } mCount = newCount; for (int i = mCount; i < mData.Length; i++) { mData[i] = default(T); } }
/// <summary> /// applies an operation tree to the list. this is done wihout reallicating the underlying array (unless it's capcity is exceeded) /// </summary> /// <typeparam name="S"></typeparam> /// <param name="operations">the operation tree</param> public void ApplyOperations(OperationTree <T> operations) { ApplyOperations(operations, x => x); }