コード例 #1
0
        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);
                    }
                }
            }
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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;
                            }
                        }
                    }
                }
            }
        }