Esempio n. 1
0
        /// <summary>Adds a command to the write list of this transaction</summary>
        /// <remarks>Must be called with m_lock taken</remarks>
        private void AddWriteCommand_NeedsLocking(WriteCommand command)
        {
            var commands = new WriteCommand[1];

            commands[0] = command;

            if (!m_writes.GetOrAdd(command.Key, commands, out commands))
            {             // there is already a command for that key
                if (command.Type == Operation.Set)
                {         // Set always overwrites everything
                    if (commands.Length == 1)
                    {     // reuse the command array
                        commands[0] = command;
                        return;
                    }
                    // overwrite
                    m_writes.SetItem(command.Key, new[] { command });
                    return;
                }

                var last = commands[commands.Length - 1];
                if (last.Type == Operation.Set)
                {                 // "SET(X) x ATOMIC(op, P)" are merged into "SET(X')" with X' = atomic(op, X, P)
                    Contract.Assert(commands.Length == 1);

                    command = WriteCommand.MergeSetAndAtomicOperation(last, command.Type, command.Value);
                    // update in place
                    commands[commands.Length - 1] = command;
                    return;
                }

                if (last.Type == command.Type)
                {                 // atomics of the same kind can be merged
                    command = WriteCommand.MergeTwoAtomicOperations(last, command.Value);
                    // update in place
                    commands[commands.Length - 1] = command;
                    return;
                }

                // just queue the command at the end
                Array.Resize <WriteCommand>(ref commands, commands.Length + 1);
                commands[commands.Length - 1] = command;

                m_writes.SetItem(command.Key, commands);
            }
        }