private void HandleOperations(Transaction tx, IEnumerable <WriteBatch.BatchOperation> operations) { foreach (var g in operations.GroupBy(x => x.TreeName)) { var tree = tx.State.GetTree(tx, g.Key); // note that the ordering is done purely for performance reasons // we rely on the fact that there can be only a single operation per key in // each batch, and that we don't make any guarantees regarding ordering between // concurrent merged writes foreach (var operation in g.OrderBy(x => x.Key, SliceEqualityComparer.Instance)) { operation.Reset(); DebugActionType actionType; switch (operation.Type) { case WriteBatch.BatchOperationType.Add: tree.Add(tx, operation.Key, operation.Value as Stream, operation.Version); actionType = DebugActionType.Add; break; case WriteBatch.BatchOperationType.Delete: tree.Delete(tx, operation.Key, operation.Version); actionType = DebugActionType.Delete; break; case WriteBatch.BatchOperationType.MultiAdd: tree.MultiAdd(tx, operation.Key, operation.Value as Slice, operation.Version); actionType = DebugActionType.MultiAdd; break; case WriteBatch.BatchOperationType.MultiDelete: tree.MultiDelete(tx, operation.Key, operation.Value as Slice, operation.Version); actionType = DebugActionType.MultiDelete; break; default: throw new ArgumentOutOfRangeException(); } if (ShouldRecordToDebugJournal) { _debugJournal.RecordAction(actionType, operation.Key, g.Key, operation.Value); } } } }
public unsafe Tree CreateTree(Transaction tx, string name, bool keysPrefixing = false) { if (tx.Flags == (TransactionFlags.ReadWrite) == false) { throw new ArgumentException("Cannot create a new tree with a read only transaction"); } Tree tree = tx.ReadTree(name); if (tree != null) { return(tree); } Slice key = name; // we are in a write transaction, no need to handle locks var header = (TreeRootHeader *)tx.State.Root.DirectRead(key); if (header != null) { tree = Tree.Open(tx, header); tree.Name = name; tx.AddTree(name, tree); return(tree); } tree = Tree.Create(tx, keysPrefixing); tree.Name = name; var space = tx.State.Root.DirectAdd(key, sizeof(TreeRootHeader)); tree.State.CopyTo((TreeRootHeader *)space); tree.State.IsModified = true; tx.AddTree(name, tree); if (IsDebugRecording) { DebugJournal.RecordAction(DebugActionType.CreateTree, Slice.Empty, name, Stream.Null); } return(tree); }
private void HandleOperations(Transaction tx, List <OutstandingWrite> writes, CancellationToken token) { var trees = writes .SelectMany(x => x.Trees) .Distinct(); foreach (var treeName in trees) { token.ThrowIfCancellationRequested(); var tree = tx.State.GetTree(tx, treeName); foreach (var write in writes) { foreach (var operation in write.GetOperations(treeName)) { token.ThrowIfCancellationRequested(); operation.Reset(); try { if (ShouldRecordToDebugJournal) { DebugActionType actionType; switch (operation.Type) { case WriteBatch.BatchOperationType.Add: actionType = DebugActionType.Add; break; case WriteBatch.BatchOperationType.Delete: actionType = DebugActionType.Delete; break; case WriteBatch.BatchOperationType.MultiAdd: actionType = DebugActionType.MultiAdd; break; case WriteBatch.BatchOperationType.MultiDelete: actionType = DebugActionType.MultiDelete; break; case WriteBatch.BatchOperationType.Increment: actionType = DebugActionType.Increment; break; default: throw new ArgumentOutOfRangeException(); } _debugJournal.RecordAction(actionType, operation.Key, treeName, operation.GetValueForDebugJournal()); } switch (operation.Type) { case WriteBatch.BatchOperationType.Add: if (operation.ValueStream != null) { tree.Add(operation.Key, operation.ValueStream, operation.Version); } else { tree.Add(operation.Key, operation.ValueSlice, operation.Version); } break; case WriteBatch.BatchOperationType.Delete: tree.Delete(operation.Key, operation.Version); break; case WriteBatch.BatchOperationType.MultiAdd: tree.MultiAdd(operation.Key, operation.ValueSlice, operation.Version); break; case WriteBatch.BatchOperationType.MultiDelete: tree.MultiDelete(operation.Key, operation.ValueSlice, operation.Version); break; case WriteBatch.BatchOperationType.Increment: tree.Increment(operation.Key, operation.ValueLong, operation.Version); break; default: throw new ArgumentOutOfRangeException(); } } catch (Exception e) { if (operation.ExceptionTypesToIgnore.Contains(e.GetType()) == false) { throw; } } } } } }