diff --git a/src/pnl.c b/src/pnl.c index 88f14c7f..d573c987 100644 --- a/src/pnl.c +++ b/src/pnl.c @@ -23,6 +23,13 @@ void pnl_free(pnl_t pnl) { osal_free(pnl - 1); } +pnl_t pnl_clone(const pnl_t src) { + pnl_t pl = pnl_alloc(MDBX_PNL_ALLOCLEN(src)); + if (likely(pl)) + memcpy(pl, src, MDBX_PNL_SIZEOF(src)); + return pl; +} + void pnl_shrink(pnl_t __restrict *__restrict ppnl) { assert(pnl_bytes2size(pnl_size2bytes(MDBX_PNL_INITIAL)) >= MDBX_PNL_INITIAL && pnl_bytes2size(pnl_size2bytes(MDBX_PNL_INITIAL)) < MDBX_PNL_INITIAL * 3 / 2); @@ -234,3 +241,18 @@ __hot __noinline size_t pnl_search_nochk(const pnl_t pnl, pgno_t pgno) { assert(!MDBX_PNL_ORDERED(it[0], pgno)); return it - begin + 1; } + +size_t pnl_maxspan(const pnl_t pnl) { + size_t len = MDBX_PNL_GETSIZE(pnl); + if (len > 1) { + size_t span = 1, left = len - span; + const pgno_t *scan = MDBX_PNL_BEGIN(pnl); + do { + const bool contiguous = MDBX_PNL_CONTIGUOUS(*scan, scan[span], span); + span += contiguous; + scan += 1 - contiguous; + } while (--left); + len = span; + } + return len; +} diff --git a/src/pnl.h b/src/pnl.h index c0b7d542..a329b9b2 100644 --- a/src/pnl.h +++ b/src/pnl.h @@ -45,10 +45,12 @@ typedef const pgno_t *const_pnl_t; #define MDBX_PNL_EDGE(pl) ((pl) + 1) #define MDBX_PNL_LEAST(pl) MDBX_PNL_FIRST(pl) #define MDBX_PNL_MOST(pl) MDBX_PNL_LAST(pl) +#define MDBX_PNL_CONTIGUOUS(prev, next, span) ((next) - (prev)) == (span)) #else #define MDBX_PNL_EDGE(pl) ((pl) + MDBX_PNL_GETSIZE(pl)) #define MDBX_PNL_LEAST(pl) MDBX_PNL_LAST(pl) #define MDBX_PNL_MOST(pl) MDBX_PNL_FIRST(pl) +#define MDBX_PNL_CONTIGUOUS(prev, next, span) (((prev) - (next)) == (span)) #endif #define MDBX_PNL_SIZEOF(pl) ((MDBX_PNL_GETSIZE(pl) + 1) * sizeof(pgno_t)) @@ -83,6 +85,8 @@ MDBX_INTERNAL pnl_t pnl_alloc(size_t size); MDBX_INTERNAL void pnl_free(pnl_t pnl); +MDBX_MAYBE_UNUSED MDBX_INTERNAL pnl_t pnl_clone(const pnl_t src); + MDBX_INTERNAL int pnl_reserve(pnl_t __restrict *__restrict ppnl, const size_t wanna); MDBX_MAYBE_UNUSED static inline int __must_check_result pnl_need(pnl_t __restrict *__restrict ppnl, size_t num) { @@ -144,3 +148,5 @@ MDBX_MAYBE_UNUSED static inline size_t pnl_search(const pnl_t pnl, pgno_t pgno, } MDBX_INTERNAL size_t pnl_merge(pnl_t dst, const pnl_t src); + +MDBX_MAYBE_UNUSED MDBX_NOTHROW_PURE_FUNCTION MDBX_INTERNAL size_t pnl_maxspan(const pnl_t pnl);