/** The MVCC read view manager */ classMVCC { public: /** Allocate and create a view. @param view view owned by this class created for the caller. Must be freed by calling close() @param trx transaction creating the view */ voidview_open(ReadView *&view, trx_t *trx);
/** Close a view created by the above function. @param view view allocated by trx_open. @param own_mutex true if caller owns trx_sys_t::mutex */ voidview_close(ReadView *&view, bool own_mutex);
/** Release a view that is inactive but not closed. Caller must own the trx_sys_t::mutex. @param view View to release */ voidview_release(ReadView *&view);
/** Clones the oldest view and stores it in view. No need to call view_close(). The caller owns the view that is passed in. It will also move the closed views from the m_views list to the m_free list. This function is called by Purge to create it view. @param view Preallocated view, owned by the caller */ voidclone_oldest_view(ReadView *view);
/** @return the number of active views */ ulint size()const;
/** @return true if the view is active and valid */ staticboolis_view_active(ReadView *view){ ut_a(view != reinterpret_cast<ReadView *>(0x1));
/** Set the view creator transaction id. Note: This shouldbe set only for views created by RW transactions. */ staticvoidset_view_creator_trx_id(ReadView *view, trx_id_t id);
private: /** Validates a read view list. */ boolvalidate()const;
/** Find a free view from the active list, if none found then allocate a new view. This function will also attempt to move delete marked views from the active list to the freed list. @return a view to use */ inline ReadView *get_view();
/** Get the oldest view in the system. It will also move the delete marked read views from the views list to the freed list. @return oldest view if found or NULL */ inline ReadView *get_oldest_view()const; ReadView *get_view_created_by_trx_id(trx_id_t trx_id)const;
private: /** Free views ready for reuse. */ view_list_t m_free;
/** Active and closed views, the closed views will have the creator trx id set to TRX_ID_MAX */ view_list_t m_views; };
private: /** The read should not see any transaction with trx id >= this value. In other words, this is the "high water mark". */ trx_id_t m_low_limit_id;
/** The read should see all trx ids which are strictly smaller (<) than this value. In other words, this is the low water mark". */ trx_id_t m_up_limit_id;
/** trx id of creating transaction, set to TRX_ID_MAX for free views. */ trx_id_t m_creator_trx_id;
/** Set of RW transactions that was active when this snapshot was taken */ ids_t m_ids;
/** The view does not need to see the undo logs for transactions whose transaction number is strictly smaller (<) than this value: they can be removed in purge if not needed by other views */ trx_id_t m_low_limit_no;
/** AC-NL-RO transaction view that has been "closed". */ bool m_closed;
typedefUT_LIST_NODE_T(ReadView)node_t;
/** List of read views in trx_sys */ byte pad1[64 - sizeof(node_t)]; node_t m_view_list; };
if (m_creator_trx_id > 0) { ut_ad(size > 0); --size; }
if (size == 0) { m_ids.clear(); return; }
m_ids.reserve(size); m_ids.resize(size);
ids_t::value_type *p = m_ids.data();
/* Copy all the trx_ids except the creator trx id */
if (m_creator_trx_id > 0) { // 拷贝 自己之外的元素 /* Note: We go through all this trouble because it is unclear whether std::vector::resize() will cause an overhead or not. We should test this extensively and if the vector to vector copy is fast enough then get rid of this code and replace it with more readable and obvious code. The code below does exactly one copy, and filters out the creator's trx id. */
trx_ids_t::const_iterator it = std::lower_bound(trx_ids.begin(), trx_ids.end(), m_creator_trx_id);