diff --git a/lmdb.h b/lmdb.h index 19a8d148..2829f285 100644 --- a/lmdb.h +++ b/lmdb.h @@ -1554,6 +1554,18 @@ int mdb_reader_list(MDB_env *env, MDB_msg_func *func, void *ctx); * @return 0 on success, non-zero on failure. */ int mdb_reader_check(MDB_env *env, int *dead); + + /** @brief Returns a lag of the reading. + * + * Returns an information for estimate how much given read-only + * transaction is lagging relative the to actual head. + * + * @param[in] txn A transaction handle returned by #mdb_txn_begin() + * @param[out] percent Percentage of page allocation in the database. + * @return Number of transactions committed after the given was started for read, or -1 on failure. + */ +int mdb_txn_straggler(MDB_txn *txnm, int *percent); + /** @} */ #ifdef __cplusplus diff --git a/mdb.c b/mdb.c index 076a682e..2bda1a5b 100644 --- a/mdb.c +++ b/mdb.c @@ -2838,6 +2838,26 @@ mdb_dbis_update(MDB_txn *txn, int keep) env->me_numdbs = n; } +int +mdb_txn_straggler(MDB_txn *txn, int *percent) +{ + MDB_env *env; + MDB_meta *meta; + txnid_t lag; + + if (! txn || ! txn->mt_u.reader) + return -1; + + env = txn->mt_env; + meta = env->me_metas[ mdb_env_pick_meta(env) ]; + if (percent) { + long cent = env->me_maxpg / 100; + *percent = (meta->mm_last_pg + cent / 2 + 1) / (cent ? cent : 1); + } + lag = meta->mm_txnid - txn->mt_u.reader->mr_txnid; + return (0 > (int) lag) ? ~0u >> 1: lag; +} + /** Common code for #mdb_txn_reset() and #mdb_txn_abort(). * May be called twice for readonly txns: First reset it, then abort. * @param[in] txn the transaction handle to reset