WL#7290: Refactor the mtr code

Status: Complete   —   Priority: Medium

Convert all the #defines into enums, improve the dynarr performance. Use proper 
interfaces and improve extensibility.
No user visible changes. Should not impact performance, at least not adversely.
Get rid of the dyn array code. It was sub-optimal. Replace it with a class that 
provides the same functionality and in a more manageable way. Prepare the ground 
work for WL#6769.

** Class that manages dynamic buffers. It uses a UT_LIST of
dyn_buf_t::block_t instances. We don't use of STL containers in
order to avoid the overhead of heap calls. Using a custom memory
allocator doesn't solve the problem either because we have to get
the memory from somewhere. We can't use the block_t::m_data as the
backend for the custom allocator because we would like the data in
the blocks to be contiguous. */
template <size_t SIZE = DYN_ARRAY_DATA_SIZE>
struct dyn_buf_t;

This replaces dyn_block_t, it reduces the size too.

To minimise changes to existing code use #defines to map the old function calls to   
the new mtr_t class and its methods e.g.,

/**
Starts a mini-transaction. */
#define mtr_start(m)            (m)->start()

Allow tagging of mini-transactions as read-only and whether they can be written to 
the redo log asynchronously.

Hide the implementation details of min-transactions from the callers.

/** Mini-transaction handle and buffer */
struct mtr_t {

        /**
        Starts a mini-transaction.
        @param sync             true if it is a synchronouse mini-transaction
        @param read_only        true if read only mini-transaction */
        void start(bool sync = true, bool read_only = false);

        /**
        @return true if it is an asynchronouse mini-transaction. */
        bool is_async() const;

        /**
        For the mini-transaction to do a synchornous commit. */
        void set_sync();

        /**
        Commits a mini-transaction. */
        void commit();

        /**
        Returns current size of the buffer.
        @return savepoint */
        ulint get_savepoint()
                __attribute__((warn_unused_result));

        /**
        Releases the (index tree) s-latch stored in an mtr memo after a
        savepoint.
        @param savepoint        value returned by @see set_savepoint.
        @param lock             latch to release */
        inline void release_s_latch_at_savepoint(
                ulint           savepoint,
                rw_lock_t*      lock);

        /**
        Releases the block in an mtr memo after a savepoint. */
        inline void release_block_at_savepoint(
                ulint           savepoint,
                buf_block_t*    block);

        /**
        SX-latches the not yet latched block after a savepoint. */
        inline void sx_latch_at_savepoint(ulint savepoint, buf_block_t* block);

        /**
        X-latches the not yet latched block after a savepoint. */
        inline void x_latch_at_savepoint(ulint savepoint, buf_block_t*  block);

        /**
        Gets the logging mode of a mini-transaction.
        @return logging mode: MTR_LOG_NONE, ... */
        inline mtr_log_t get_log_mode() const
                __attribute__((warn_unused_result));

        /**
        Changes the logging mode of a mini-transaction.
        @param mode      logging mode: MTR_LOG_NONE, ...
        @return old mode */
        inline mtr_log_t set_log_mode(mtr_log_t mode);

        /**
        Reads 1 - 4 bytes from a file page buffered in the buffer pool.
        @param ptr      pointer from where to read
        @param type)    MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES
        @return value read */
        inline ulint read_ulint(const byte* ptr, mlog_id_t type) const
                __attribute__((warn_unused_result));

        /**
        Reads 8 bytes from a file page buffered in the buffer pool.
        @return value read */
        inline ib_id_t read_ull(const byte* ptr, ulint type) const
                __attribute__((warn_unused_result));

        /**
        Locks a lock in s-mode.
        @param lock     rw-lock
        @param file     file name from where called
        @param line     line number in file */
        inline void s_lock(rw_lock_t* lock, const char* file, ulint line);

        /**
        Locks a lock in x-mode.
        @param lock     rw-lock
        @param file     file name from where called
        @param line     line number in file */
        inline void x_lock(rw_lock_t* lock, const char* file, ulint line);

        /**
        Locks a lock in sx-mode. */
        inline void sx_lock(rw_lock_t* lock, const char* file, ulint line);

        /**
        Releases an object in the memo stack.
        @param object   object
        @param type     object type: MTR_MEMO_S_LOCK, ...
        @return bool if lock released */
        bool memo_release(const void* object, ulint type);

        /**
        Set the state to modified. */
        void set_modified();

        /**
        Set the state to not-modified. This will not log the changes */
        void discard_modifications();

        /**
        @return the commit LSN */
        lsn_t commit_lsn() const;

        /**
        Note that we are inside the change buffer code */
        void enter_ibuf();

        /**
        Note that we have exited from the change buffer code */
        void exit_ibuf();

        /**
        @return true if we are inside the change buffer code */
        bool is_inside_ibuf() const;

        /**
        Note that some  pages were freed */
        void add_freed_pages();

       /**
        @return true if a record was added to the mini-transaction */
        bool is_dirty() const;

        /**
        Note that a record has been added to the log */
        void added_rec();

        /**
        Returns the log object of a mini-transaction buffer.
        @return const log */
        const mtr_buf_t* get_log() const;

        /**
        Returns the log object of a mini-transaction buffer.
        @return log */
        mtr_buf_t* get_log();

        /**
        Pushes an object to an mtr memo stack.
        @param object   object
        @param type     object type: MTR_MEMO_S_LOCK, ... */
        inline void memo_push(void* object, mtr_memo_type_t type);

        /**
        Checks if a mini-transaction is dirtying a clean page.
        @param block    block being x-fixed
        @return true if the mtr is dirtying a clean page. */
        static bool is_block_dirtied(const buf_block_t* block)
                __attribute__((warn_unused_result));
};