/// <summary>
        /// Executes batch add or delete operation on table.
        /// </summary>
        /// <param name="batchOperation">Batch operation to be performed.</param>
        /// <param name="rooms">List of rooms.</param>
        /// <returns>Boolean indicating operation result.</returns>
        private async Task <bool> ExecuteBatchOperation(BatchOperation batchOperation, IList <MeetingRoomEntity> rooms)
        {
            try
            {
                TableBatchOperation tableBatchOperation = new TableBatchOperation();
                int count = (int)Math.Ceiling((double)rooms.Count / RoomsPerBatch);
                for (int i = 0; i < count; i++)
                {
                    var roomsBatch = rooms.Skip(i * RoomsPerBatch).Take(RoomsPerBatch);
                    foreach (var room in roomsBatch)
                    {
                        tableBatchOperation.Add(batchOperation == BatchOperation.Insert ? TableOperation.Insert(room) : TableOperation.Delete(room));
                    }
                }

                if (tableBatchOperation.Count > 0)
                {
                    var result = await this.cloudTable.ExecuteBatchAsync(tableBatchOperation).ConfigureAwait(false);

                    return(result?.Count > 0);
                }

                return(false);
            }
            catch (Exception ex)
            {
                this.telemetryClient.TrackException(ex);
                throw;
            }
        }
        private static BatchOperation readFromCommandLine(Solution solution)
        {
            Console.WriteLine("# Batch installation interactive mode");
            Console.WriteLine("# Install multiple nugets to projects using either of the following formats:");
            Console.WriteLine("#    Project: Nuget [, Nuget]");
            Console.WriteLine("#    Nuget: Project [, Project]");
            Console.WriteLine("#");
            Console.WriteLine("# Nuget can be formatted as:");
            Console.WriteLine("#    NugetID");
            Console.WriteLine("#    NugetID/Version");
            Console.WriteLine("#");
            Console.WriteLine("# Enter multiple lines. Type '', 'q', or 'quit' to quit.");

            var    operation = new BatchOperation(solution);
            string line;

            while ((line = Console.ReadLine()) != null)
            {
                line = line.Trim();
                if (line.IsEmpty() || line == "q" || line == "quit")
                {
                    break;
                }

                operation.ReadLine(line);
            }

            return(operation);
        }
        private void verifyTheRequests(params Func <NugetPlanRequest, bool>[] predicates)
        {
            var requests = BatchOperation.Parse(theSolution, theBatchInput).Requests;

            predicates.All(requests.Any).ShouldBeTrue();
            requests.Count().ShouldEqual(predicates.Length);
        }
Esempio n. 4
0
        /// <summary>
        /// Executes batch add or delete operation on Azure table storage.
        /// </summary>
        /// <param name="batchOperation">Batch operation to be performed.</param>
        /// <param name="rooms">List of rooms.</param>
        /// <returns>Returns true if batch operation is successful else throws exception for error.</returns>
        private async Task <bool> ExecuteBatchOperationAsync(BatchOperation batchOperation, IList <UserFavoriteRoomEntity> rooms)
        {
            var tableBatchOperation = new TableBatchOperation();

            try
            {
                int batchCount = (int)Math.Ceiling((double)rooms.Count / RoomsPerBatch);

                for (int i = 0; i < batchCount; i++)
                {
                    tableBatchOperation.Clear();
                    var roomsBatch = rooms.Skip(i * RoomsPerBatch).Take(RoomsPerBatch);
                    foreach (var room in roomsBatch)
                    {
                        tableBatchOperation.Add(batchOperation == BatchOperation.Insert ? TableOperation.Insert(room) : TableOperation.Delete(room));
                    }

                    if (tableBatchOperation.Count > 0)
                    {
                        await this.cloudTable.ExecuteBatchAsync(tableBatchOperation).ConfigureAwait(false);
                    }
                }

                return(true);
            }
            catch (Exception ex)
            {
                this.telemetryClient.TrackException(ex);
                throw;
            }
        }
Esempio n. 5
0
 public BatchOperationsTests(ITestOutputHelper h)
 {
     Setup.Logger(h);
     _store = Substitute.For <IStoreBatchProgress>();
     _sut   = new BatchOperation(_store, CreateReadModelConfig());
     ConfigureStore();
 }
Esempio n. 6
0
        /// <summary>
        /// Begins the async save changes operation
        /// </summary>
        /// <returns></returns>
        public async Task SaveChangesAsync(CancellationToken token = default(CancellationToken))
        {
            using (AsyncTaskHolder())
            {
                if (_asyncDocumentIdGeneration != null)
                {
                    await _asyncDocumentIdGeneration.GenerateDocumentIdsForSaveChanges().WithCancellation(token).ConfigureAwait(false);
                }

                var saveChangesOperation = new BatchOperation(this);

                using (var command = saveChangesOperation.CreateRequest())
                {
                    if (command == null)
                    {
                        return;
                    }

                    if (NoTracking)
                    {
                        throw new InvalidOperationException($"Cannot execute '{nameof(SaveChangesAsync)}' when entity tracking is disabled in session.");
                    }

                    await RequestExecutor.ExecuteAsync(command, Context, _sessionInfo, token).ConfigureAwait(false);

                    UpdateSessionAfterSaveChanges(command.Result);
                    saveChangesOperation.SetResult(command.Result);
                }
            }
        }
        /// <summary>
        /// Add a batch operation
        /// </summary>
        /// <param name="id"></param>
        /// <param name="description"></param>
        /// <param name="uri"></param>
        /// <param name="method"></param>
        /// <param name="headers"></param>
        /// <param name="requestModel"></param>
        /// <returns></returns>
        public BatchRequestBuilder AddOperation <T>(string id, string description, string uri, string method, List <BatchOperationHeader> headers, T requestModel)
        {
            List <BatchOperationHeader> updatedheaders = headers == null ? new List <BatchOperationHeader>() : new List <BatchOperationHeader>(headers);

            updatedheaders.Add(new BatchOperationHeader {
                Name = "Content-Type", Value = "application/vnd.emc.documentum+json"
            });
            updatedheaders.Add(new BatchOperationHeader {
                Name = "Accept", Value = "application/*+json"
            });

            string entity = null;

            if (requestModel != null)
            {
                using (MemoryStream ms = new MemoryStream())
                {
                    JSON_SERIALIZER.WriteObject <T>(ms, requestModel);
                    entity = System.Text.Encoding.Default.GetString(ms.ToArray());
                }
            }

            BatchOperation operation = new BatchOperation
            {
                Id          = id,
                Description = description,
                Request     = new BatchOperationRequest {
                    Uri = uri, Method = method, Headers = updatedheaders, Entity = entity
                }
            };

            operations.Add(operation);
            return(this);
        }
Esempio n. 8
0
 public void GetResults_ShouldThrowArguementException_IfDocumentsNotProvided()
 {
     Should.Throw <InvalidOperationException>(() =>
     {
         var batch        = new BatchOperation();
         var batchResults = _analytics.GetResults(batch);
     }, "No documents have been added to the Batch Operation");
 }
Esempio n. 9
0
 public void SetVersionFrom(BatchOperation other)
 {
     if (other.Version != null &&
         other.Version + 1 == Version)
     {
         Version = other.Version;
     }
 }
Esempio n. 10
0
        public void AddStruct(Slice key, IStructure value, string treeName, ushort?version = null, bool shouldIgnoreConcurrencyExceptions = false)
        {
            var batchOperation = BatchOperation.Add(key, value, version, treeName);

            if (shouldIgnoreConcurrencyExceptions)
            {
                batchOperation.SetIgnoreExceptionOnExecution <ConcurrencyException>();
            }
            AddOperation(batchOperation);
        }
Esempio n. 11
0
 static QueuedCommand()
 {
     if (Voat.Caching.CacheHandler.Instance.CacheEnabled)
     {
         _commands = new CacheBatchOperation <QueuedCommand <T> >("Command", Voat.Caching.CacheHandler.Instance, 10, TimeSpan.FromMinutes(5), ProcessBatch);
     }
     else
     {
         _commands = new MemoryBatchOperation <QueuedCommand <T> >(10, TimeSpan.FromMinutes(5), ProcessBatch);
     }
 }
Esempio n. 12
0
        /// <summary>
        /// 执行批量操作
        /// </summary>
        /// <param name="userID"></param>
        /// <param name="opCode"></param>
        /// <param name="dto"></param>
        /// <returns></returns>
        protected override Result OnBatch(int userID, BatchOperation opCode, IBatchDto dto)
        {
            switch (opCode)
            {
            case BatchOperation.audit:
                return(_Service.BatchAudit(userID, dto));

            default:
                return(base.OnBatch(userID, opCode, dto));
            }
        }
Esempio n. 13
0
        /// <summary>
        /// Saves all the changes to the Raven server.
        /// </summary>
        public void SaveChanges()
        {
            var saveChangesOperation = new BatchOperation(this);

            var command = saveChangesOperation.CreateRequest();

            if (command != null)
            {
                RequestExecuter.Execute(command, Context);
                saveChangesOperation.SetResult(command.Result);
            }
        }
Esempio n. 14
0
        public void Increment(Slice key, long delta, string treeName, ushort?version = null, bool shouldIgnoreConcurrencyExceptions = false)
        {
            AssertValidTreeName(treeName);

            var batchOperation = BatchOperation.Increment(key, delta, version, treeName);

            if (shouldIgnoreConcurrencyExceptions)
            {
                batchOperation.SetIgnoreExceptionOnExecution <ConcurrencyException>();
            }
            AddOperation(batchOperation);
        }
Esempio n. 15
0
        public void Delete(Slice key, string treeName, ushort?version = null, bool shouldIgnoreConcurrencyExceptions = false)
        {
            AssertValidRemove(treeName);

            var batchOperation = BatchOperation.Delete(key, version, treeName);

            if (shouldIgnoreConcurrencyExceptions)
            {
                batchOperation.SetIgnoreExceptionOnExecution <ConcurrencyException>();
            }
            AddOperation(batchOperation);
        }
Esempio n. 16
0
        private void AddOperation(BatchOperation operation)
        {
            var treeName = operation.TreeName;

            if (treeName != null && treeName.Length == 0)
            {
                throw new ArgumentException("treeName must not be empty", "treeName");
            }

            if (treeName == null)
            {
                treeName = Constants.RootTreeName;
            }

            if (operation.Type == BatchOperationType.MultiAdd || operation.Type == BatchOperationType.MultiDelete)
            {
                Dictionary <Slice, List <BatchOperation> > multiTreeOperationsOfTree;
                if (_multiTreeOperations.TryGetValue(treeName, out multiTreeOperationsOfTree) == false)
                {
                    _multiTreeOperations[treeName] =
                        multiTreeOperationsOfTree  = new Dictionary <Slice, List <BatchOperation> >(_sliceEqualityComparer);
                }

                List <BatchOperation> specificMultiTreeOperations;
                if (multiTreeOperationsOfTree.TryGetValue(operation.Key, out specificMultiTreeOperations) == false)
                {
                    multiTreeOperationsOfTree[operation.Key] = specificMultiTreeOperations = new List <BatchOperation>();
                }

                specificMultiTreeOperations.Add(operation);
            }
            else
            {
                Dictionary <Slice, BatchOperation> lastOpsForTree;
                if (_lastOperations.TryGetValue(treeName, out lastOpsForTree) == false)
                {
                    _lastOperations[treeName] = lastOpsForTree = new Dictionary <Slice, BatchOperation>(_sliceEqualityComparer);
                }
                BatchOperation old;
                if (lastOpsForTree.TryGetValue(operation.Key, out old))
                {
                    operation.SetVersionFrom(old);
                    var disposable = old.Value as IDisposable;
                    if (disposable != null)
                    {
                        disposable.Dispose();
                    }
                }
                lastOpsForTree[operation.Key] = operation;
            }
        }
Esempio n. 17
0
        internal QuickBooksBaseModel GetReturnObject <T>(T item, BatchOperation operation) where T : QuickBooksBaseModel
        {
            switch (operation)
            {
            case BatchOperation.Create:
                return(item.CreateReturnObject());

            case BatchOperation.Update:
                return(item.UpdateReturnObject());

            default:
                return(item.DeleteReturnObject());
            }
        }
Esempio n. 18
0
        /// <summary>
        /// 执行批量操作
        /// </summary>
        /// <param name="userID"></param>
        /// <param name="opCode"></param>
        /// <param name="dto"></param>
        /// <returns></returns>
        protected override Result OnBatch(int userID, BatchOperation opCode, IBatchDto dto)
        {
            switch (opCode)
            {
            case BatchOperation.forbidden:
                return(_Service.BatchUpdateStatus(userID, dto, Status.Forbidden));

            case BatchOperation.normal:
                return(_Service.BatchUpdateStatus(userID, dto, Status.Normal));

            default:
                return(base.OnBatch(userID, opCode, dto));
            }
        }
Esempio n. 19
0
        public void GetResults_ShouldNotThrowException_IfDocumentsAndClientProvided()
        {
            Should.NotThrow(() =>
            {
                var documentA = new Document(documentAText);
                var documentB = new Document(documentBText);

                var batch = new BatchOperation();
                batch.AddDocument(documentA);
                batch.AddDocument(documentB);

                var batchResults = _analytics.GetResults(batch);
            });
        }
Esempio n. 20
0
        private void AddOperation(BatchOperation operation)
        {
            var treeName = operation.TreeName;

            AssertValidTreeName(treeName);

            if (treeName == null)
            {
                treeName = Constants.RootTreeName;
            }

            _trees.Add(treeName);

            if (operation.Type == BatchOperationType.MultiAdd || operation.Type == BatchOperationType.MultiDelete)
            {
                Dictionary <Slice, List <BatchOperation> > multiTreeOperationsOfTree;
                if (_multiTreeOperations.TryGetValue(treeName, out multiTreeOperationsOfTree) == false)
                {
                    _multiTreeOperations[treeName] =
                        multiTreeOperationsOfTree  = new Dictionary <Slice, List <BatchOperation> >(_sliceEqualityComparer);
                }

                List <BatchOperation> specificMultiTreeOperations;
                if (multiTreeOperationsOfTree.TryGetValue(operation.Key, out specificMultiTreeOperations) == false)
                {
                    multiTreeOperationsOfTree[operation.Key] = specificMultiTreeOperations = new List <BatchOperation>();
                }

                specificMultiTreeOperations.Add(operation);
            }
            else
            {
                Dictionary <Slice, BatchOperation> lastOpsForTree;
                if (_lastOperations.TryGetValue(treeName, out lastOpsForTree) == false)
                {
                    _lastOperations[treeName] = lastOpsForTree = new Dictionary <Slice, BatchOperation>(_sliceEqualityComparer);
                }
                BatchOperation old;
                if (lastOpsForTree.TryGetValue(operation.Key, out old))
                {
                    operation.SetVersionFrom(old);
                    if (old.ValueStream != null)
                    {
                        old.ValueStream.Dispose();
                    }
                }
                lastOpsForTree[operation.Key] = operation;
            }
        }
Esempio n. 21
0
        /// <summary>
        /// Begins the async save changes operation
        /// </summary>
        /// <returns></returns>
        public async Task SaveChangesAsync(CancellationToken token = default(CancellationToken))
        {
            await asyncDocumentKeyGeneration.GenerateDocumentKeysForSaveChanges().WithCancellation(token).ConfigureAwait(false);

            var saveChangesOeration = new BatchOperation(this);

            var command = saveChangesOeration.CreateRequest();

            if (command != null)
            {
                await RequestExecuter.ExecuteAsync(command, Context, token);

                saveChangesOeration.SetResult(command.Result);
            }
        }
Esempio n. 22
0
        /// <summary>
        /// Saves all the changes to the Raven server.
        /// </summary>
        public void SaveChanges()
        {
            var saveChangesOperation = new BatchOperation(this);

            using (var command = saveChangesOperation.CreateRequest())
            {
                if (command == null)
                {
                    return;
                }

                RequestExecutor.Execute(command, Context, sessionInfo: SessionInfo);
                saveChangesOperation.SetResult(command.Result);
            }
        }
Esempio n. 23
0
        public void Add(Slice key, Slice value, string treeName, ushort?version = null, bool shouldIgnoreConcurrencyExceptions = false)
        {
            AssertValidTreeName(treeName);
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            var batchOperation = BatchOperation.Add(key, value, version, treeName);

            if (shouldIgnoreConcurrencyExceptions)
            {
                batchOperation.SetIgnoreExceptionOnExecution <ConcurrencyException>();
            }
            AddOperation(batchOperation);
        }
Esempio n. 24
0
        public void Add(Slice key, Stream value, string treeName, ushort?version = null, bool shouldIgnoreConcurrencyExceptions = false)
        {
            AssertValidTreeName(treeName);
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }
            if (value.Length > int.MaxValue)
            {
                throw new ArgumentException("Cannot add a value that is over 2GB in size", "value");
            }

            var batchOperation = BatchOperation.Add(key, value, version, treeName);

            if (shouldIgnoreConcurrencyExceptions)
            {
                batchOperation.SetIgnoreExceptionOnExecution <ConcurrencyException>();
            }
            AddOperation(batchOperation);
        }
Esempio n. 25
0
        /// <summary>
        /// Begins the async save changes operation
        /// </summary>
        /// <returns></returns>
        public async Task SaveChangesAsync(CancellationToken token = default(CancellationToken))
        {
            if (_asyncDocumentIdGeneration != null)
            {
                await _asyncDocumentIdGeneration.GenerateDocumentIdsForSaveChanges().WithCancellation(token).ConfigureAwait(false);
            }

            var saveChangesOperation = new BatchOperation(this);

            using (var command = saveChangesOperation.CreateRequest())
            {
                if (command == null)
                {
                    return;
                }

                await RequestExecutor.ExecuteAsync(command, Context, SessionInfo, token).ConfigureAwait(false);

                saveChangesOperation.SetResult(command.Result);
            }
        }
Esempio n. 26
0
        /// <summary>
        /// Saves all the changes to the Raven server.
        /// </summary>
        public void SaveChanges()
        {
            var saveChangesOperation = new BatchOperation(this);

            using (var command = saveChangesOperation.CreateRequest())
            {
                if (command == null)
                {
                    return;
                }

                if (NoTracking)
                {
                    throw new InvalidOperationException($"Cannot execute '{nameof(SaveChanges)}' when entity tracking is disabled in session.");
                }

                RequestExecutor.Execute(command, Context, sessionInfo: SessionInfo);
                UpdateSessionAfterSaveChanges(command.Result);
                saveChangesOperation.SetResult(command.Result);
            }
        }
Esempio n. 27
0
        public IEnumerable <NugetPlanRequest> Requests(Solution solution)
        {
            BatchOperation operation;

            if (FileFlag.IsNotEmpty())
            {
                var file = Path.Combine(RippleFileSystem.CurrentDirectory(), FileFlag);
                RippleLog.Info("Detected {0}. Reading batch instructions.".ToFormat(FileFlag));

                var contents = File.ReadAllText(file);
                operation = BatchOperation.Parse(solution, contents);

                After = () => File.Delete(file);
            }
            else
            {
                operation = readFromCommandLine(solution);
            }


            return(operation.Requests);
        }
Esempio n. 28
0
        public async Task <string> Store(string expectedETag, TransactionalStateMetaData metadata, List <PendingTransactionState <TState> > statesToPrepare, long?commitUpTo, long?abortAfter)
        {
            var keyETag = key.ETag.ToString();

            if ((!string.IsNullOrWhiteSpace(keyETag) || !string.IsNullOrWhiteSpace(expectedETag)) && keyETag != expectedETag)
            {
                throw new ArgumentException(nameof(expectedETag), "Etag does not match");
            }

            // assemble all storage operations into a single batch
            // these operations must commit in sequence, but not necessarily atomically
            // so we can split this up if needed
            var batchOperation = new BatchOperation(logger, key, table);

            // first, clean up aborted records
            if (abortAfter.HasValue && states.Count != 0)
            {
                while (states.Count > 0 && states[states.Count - 1].Key > abortAfter)
                {
                    var entity = states[states.Count - 1].Value;
                    await batchOperation.Add(new TableTransactionAction(TableTransactionActionType.Delete, entity.Entity, entity.ETag)).ConfigureAwait(false);

                    key.ETag = batchOperation.KeyETag;
                    states.RemoveAt(states.Count - 1);

                    if (logger.IsEnabled(LogLevel.Trace))
                    {
                        logger.LogTrace($"{partition}.{entity.RowKey} Delete {entity.TransactionId}");
                    }
                }
            }

            // second, persist non-obsolete prepare records
            var obsoleteBefore = commitUpTo.HasValue ? commitUpTo.Value : key.CommittedSequenceId;

            if (statesToPrepare != null)
            {
                foreach (var s in statesToPrepare)
                {
                    if (s.SequenceId >= obsoleteBefore)
                    {
                        if (FindState(s.SequenceId, out var pos))
                        {
                            // overwrite with new pending state
                            StateEntity existing = states[pos].Value;
                            existing.TransactionId        = s.TransactionId;
                            existing.TransactionTimestamp = s.TimeStamp;
                            existing.TransactionManager   = JsonConvert.SerializeObject(s.TransactionManager, this.jsonSettings);
                            existing.SetState(s.State, this.jsonSettings);
                            await batchOperation.Add(new TableTransactionAction(TableTransactionActionType.UpdateReplace, existing.Entity, existing.ETag)).ConfigureAwait(false);

                            key.ETag = batchOperation.KeyETag;

                            if (logger.IsEnabled(LogLevel.Trace))
                            {
                                logger.LogTrace($"{partition}.{existing.RowKey} Update {existing.TransactionId}");
                            }
                        }
                        else
                        {
                            var entity = StateEntity.Create(this.jsonSettings, this.partition, s);
                            await batchOperation.Add(new TableTransactionAction(TableTransactionActionType.Add, entity.Entity)).ConfigureAwait(false);

                            key.ETag = batchOperation.KeyETag;
                            states.Insert(pos, new KeyValuePair <long, StateEntity>(s.SequenceId, entity));

                            if (logger.IsEnabled(LogLevel.Trace))
                            {
                                logger.LogTrace($"{partition}.{entity.RowKey} Insert {entity.TransactionId}");
                            }
                        }
                    }
                }
            }

            // third, persist metadata and commit position
            key.Metadata = JsonConvert.SerializeObject(metadata, this.jsonSettings);
            if (commitUpTo.HasValue && commitUpTo.Value > key.CommittedSequenceId)
            {
                key.CommittedSequenceId = commitUpTo.Value;
            }
            if (string.IsNullOrEmpty(this.key.ETag.ToString()))
            {
                await batchOperation.Add(new TableTransactionAction(TableTransactionActionType.Add, key)).ConfigureAwait(false);

                key.ETag = batchOperation.KeyETag;

                if (logger.IsEnabled(LogLevel.Trace))
                {
                    logger.LogTrace($"{partition}.{KeyEntity.RK} Insert. v{this.key.CommittedSequenceId}, {metadata.CommitRecords.Count}c");
                }
            }
            else
            {
                await batchOperation.Add(new TableTransactionAction(TableTransactionActionType.UpdateReplace, key, key.ETag)).ConfigureAwait(false);

                key.ETag = batchOperation.KeyETag;

                if (logger.IsEnabled(LogLevel.Trace))
                {
                    logger.LogTrace($"{partition}.{KeyEntity.RK} Update. v{this.key.CommittedSequenceId}, {metadata.CommitRecords.Count}c");
                }
            }

            // fourth, remove obsolete records
            if (states.Count > 0 && states[0].Key < obsoleteBefore)
            {
                FindState(obsoleteBefore, out var pos);
                for (int i = 0; i < pos; i++)
                {
                    await batchOperation.Add(new TableTransactionAction(TableTransactionActionType.Delete, states[i].Value.Entity, states[i].Value.ETag)).ConfigureAwait(false);

                    key.ETag = batchOperation.KeyETag;

                    if (logger.IsEnabled(LogLevel.Trace))
                    {
                        logger.LogTrace($"{partition}.{states[i].Value.RowKey} Delete {states[i].Value.TransactionId}");
                    }
                }
                states.RemoveRange(0, pos);
            }

            await batchOperation.Flush().ConfigureAwait(false);

            if (logger.IsEnabled(LogLevel.Debug))
            {
                logger.LogDebug($"{partition} Stored v{this.key.CommittedSequenceId} eTag={key.ETag}");
            }

            return(key.ETag.ToString());
        }
Esempio n. 29
0
        public void Increment(Slice key, long delta, string treeName, ushort?version = null)
        {
            AssertValidTreeName(treeName);

            AddOperation(BatchOperation.Increment(key, delta, version, treeName));
        }
Esempio n. 30
0
        public void MultiDelete(Slice key, Slice value, string treeName, ushort?version = null)
        {
            AssertValidMultiOperation(value, treeName);

            AddOperation(BatchOperation.MultiDelete(key, value, version, treeName));
        }