public IEnumerable <KeyValuePair <IData, IData> > Backward(IData to, bool hasTo, IData from, bool hasFrom) { if (hasFrom && hasTo && Locator.KeyComparer.Compare(from, to) > 0) { throw new ArgumentException("from > to"); } from = hasFrom ? from : default(IData); to = hasTo ? to : default(IData); List <KeyValuePair <IData, IData> > records = null; IData nextKey = null; var operation = new BackwardOperation(PageCapacity, to, from, null); Execute(operation); records = operation.List; nextKey = records != null && records.Count == PageCapacity ? records[records.Count - 1].Key : null; while (records != null) { Task task = null; List <KeyValuePair <IData, IData> > _records = null; int returnCount = nextKey != null ? records.Count - 1 : records.Count; if (nextKey != null) { task = Task.Factory.StartNew(() => { var _operation = new BackwardOperation(PageCapacity, nextKey, from, null); Execute(_operation); _records = _operation.List; nextKey = _records != null && _records.Count == PageCapacity ? _records[_records.Count - 1].Key : null; }); } for (int i = 0; i < returnCount; i++) { yield return(records[i]); } records = null; if (task != null) { task.Wait(); } if (_records != null) { records = _records; } } }
private void WriteBackwardOperation(BinaryWriter writer, BackwardOperation operation) { writer.Write(operation.PageCount); writer.Write(operation.FromKey != null); if (operation.FromKey != null) { KeyPersist.Write(writer, operation.FromKey); } writer.Write(operation.ToKey != null); if (operation.ToKey != null) { KeyPersist.Write(writer, operation.ToKey); } writer.Write(operation.List != null); if (operation.List != null) { SerializeList(writer, operation.List, operation.List.Count); } }
private void PacketExecute(object state) { try { KeyValuePair <ServerConnection, Packet> order = (KeyValuePair <ServerConnection, Packet>)state; BinaryReader reader = new BinaryReader(order.Value.Request); Message msgRequest = Message.Deserialize(reader); MemoryStream ms = new MemoryStream(); BinaryWriter writer = new BinaryWriter(ms); IOperationCollection asyncOperations = new OperationCollection(msgRequest.Locator, msgRequest.Operations.Count); IOperationCollection resultsOperations = new OperationCollection(msgRequest.Locator, 1); var index = StorageEngine.OpenXIndex(msgRequest.Locator.KeyDescriptor, msgRequest.Locator.RecordDescriptor, msgRequest.Locator.Name); foreach (var operation in msgRequest.Operations) { try { if (!operation.IsSynchronous) { asyncOperations.Add(operation); } else { StorageEngine.Execute(asyncOperations); asyncOperations.Clear(); switch (operation.Code) { case OperationCode.TRY_GET: { IData record = null; index.TryGet(operation.FromKey, out record); resultsOperations.Add(new TryGetOperation(operation.FromKey, record)); } break; case OperationCode.FORWARD: { var op = (ForwardOperation)operation; List <KeyValuePair <IData, IData> > forward = index.Forward(op.FromKey, op.FromKey != null, op.ToKey, op.ToKey != null).Take(op.PageCount).ToList(); ForwardOperation opResult = new ForwardOperation(0, op.FromKey, op.ToKey, forward); resultsOperations.Add(opResult); } break; case OperationCode.BACKWARD: { var op = (BackwardOperation)operation; List <KeyValuePair <IData, IData> > backward = index.Backward(op.FromKey, op.FromKey != null, op.ToKey, op.ToKey != null).Take(op.PageCount).ToList(); BackwardOperation opResult = new BackwardOperation(0, op.FromKey, op.ToKey, backward); resultsOperations.Add(opResult); } break; case OperationCode.COUNT: { resultsOperations.Add(new CountOperation(index.Count())); } break; case OperationCode.FIND_NEXT: { var kv = index.FindNext(operation.FromKey); resultsOperations.Add(new FindNextOperation(operation.FromKey, kv)); } break; case OperationCode.FIND_AFTER: { var kv = index.FindAfter(operation.FromKey); resultsOperations.Add(new FindAfterOperation(operation.FromKey, kv)); } break; case OperationCode.FIND_PREV: { var kv = index.FindPrev(operation.FromKey); resultsOperations.Add(new FindPrevOperation(operation.FromKey, kv)); } break; case OperationCode.FIND_BEFORE: { var kv = index.FindBefore(operation.FromKey); resultsOperations.Add(new FindBeforeOperation(operation.FromKey, kv)); } break; case OperationCode.FIRST_ROW: { var kv = index.FirstRow; resultsOperations.Add(new FirstRowOperation(kv)); } break; case OperationCode.LAST_ROW: { var kv = index.LastRow; resultsOperations.Add(new LastRowOperation(kv)); } break; case OperationCode.STORAGE_ENGINE_COMMIT: { StorageEngine.Commit(); resultsOperations.Add(new StorageEngineCommitOperation()); } break; } } } catch (Exception exc) { resultsOperations.Add(new ExceptionOperation(exc.Message)); } } if (asyncOperations.Count > 0) { StorageEngine.Execute(asyncOperations); } index.Flush(); Message msgResponse = new Message(resultsOperations); msgResponse.Serialize(writer); ms.Position = 0; order.Value.Response = ms; order.Key.PendingPackets.Add(order.Value); } catch (Exception exc) { TcpServer.LogError(exc); } }