63#define FREE_PAGE_SPAN_LEADER_MAGIC 0xea4020f0
64#define FREE_PAGE_LEAF_MAGIC 0x98eae728
65#define FREE_PAGE_INTERNAL_MAGIC 0x19aa32c9
100#define FPM_ITEMS_PER_INTERNAL_PAGE \
101 ((FPM_PAGE_SIZE - sizeof(FreePageBtreeHeader)) / \
102 sizeof(FreePageBtreeInternalKey))
103#define FPM_ITEMS_PER_LEAF_PAGE \
104 ((FPM_PAGE_SIZE - sizeof(FreePageBtreeHeader)) / \
105 sizeof(FreePageBtreeLeafKey))
167#ifdef FPM_EXTRA_ASSERTS
196#ifdef FPM_EXTRA_ASSERTS
213 Size contiguous_pages;
238#ifdef FPM_EXTRA_ASSERTS
241 Assert(fpm->free_pages >= npages);
242 fpm->free_pages -= npages;
250#ifdef FPM_EXTRA_ASSERTS
381 Size contiguous_pages;
393 if (contiguous_pages > npages)
413#ifdef FPM_EXTRA_ASSERTS
414 fpm->free_pages += npages;
513 first_page =
btp->u.leaf_key[0].first_page;
519 first_page =
btp->u.internal_key[0].first_page;
551#ifdef USE_ASSERT_CHECKING
591 if (
root->hdr.nused == 1)
615 else if (
root->hdr.nused == 2 &&
622 root->u.leaf_key[0].npages;
635 root->u.leaf_key[1].npages + 1;
670 Size contiguous_pages;
675 if (contiguous_pages == 0)
717 if (
btp->hdr.nused >= max / 3)
724 if (
np !=
NULL &&
btp->hdr.nused +
np->hdr.nused <= max)
730 btp->hdr.nused +=
np->hdr.nused;
734 memcpy(&
btp->u.internal_key[
btp->hdr.nused], &
np->u.internal_key[0],
736 btp->hdr.nused +=
np->hdr.nused;
749 if (
np !=
NULL &&
btp->hdr.nused +
np->hdr.nused <= max)
755 np->hdr.nused +=
btp->hdr.nused;
759 memcpy(&
np->u.internal_key[
np->hdr.nused], &
btp->u.internal_key[0],
761 np->hdr.nused +=
btp->hdr.nused;
868 return btp->u.leaf_key[0].first_page;
872 return btp->u.internal_key[0].first_page;
908 btp->u.internal_key[
index].first_page = first_page;
925 btp->u.leaf_key[
index].first_page = first_page;
926 btp->u.leaf_key[
index].npages = npages;
961 if (
btp->hdr.nused == 1)
1077 result->
found =
false;
1089 btp->u.internal_key[
index].first_page == first_page;
1131 first_page ==
btp->u.leaf_key[
index].first_page;
1150 Size mid = (low + high) / 2;
1151 Size val =
btp->u.internal_key[mid].first_page;
1153 if (first_page ==
val)
1155 else if (first_page <
val)
1180 Size mid = (low + high) / 2;
1183 if (first_page ==
val)
1185 else if (first_page <
val)
1213 &
btp->u.leaf_key[
btp->hdr.nused],
1219 &
btp->u.internal_key[
btp->hdr.nused],
1237 for (
i = 0;
i <
btp->hdr.nused; ++
i)
1271 btp->u.internal_key[
index].first_page,
1365 if (
victim->npages == npages)
1440 if (
victim->npages == npages)
1450 key->first_page += npages;
1451 key->npages -= npages;
1452 if (result.
index == 0)
1457 victim->npages - npages);
1534 elog(
FATAL,
"free page manager btree is corrupt");
1539 root->hdr.nused = 1;
1554 if (
root->u.leaf_key[0].npages == 0)
1556 root->u.leaf_key[0].first_page = first_page;
1557 root->u.leaf_key[0].npages = npages;
1569 if (result.
index > 0)
1582 nextkey = &
np->u.leaf_key[0];
1595 if (nextkey !=
NULL &&
1628 if (nextkey !=
NULL && first_page + npages >= nextkey->
first_page)
1689 elog(
FATAL,
"free page manager btree is corrupt");
1718 Size key = first_page;
1758 key <
newsibling->u.internal_key[0].first_page ?
1778 newroot->u.internal_key[0].first_page =
1783 newroot->u.internal_key[1].first_page =
1795 key =
newsibling->u.internal_key[0].first_page;
1829 if (result.
index == 0)
1880 span->npages = npages;
#define Assert(condition)
static Size FreePageBtreeSearchInternal(FreePageBtree *btp, Size first_page)
#define FREE_PAGE_INTERNAL_MAGIC
static FreePageBtree * FreePageBtreeFindRightSibling(char *base, FreePageBtree *btp)
static Size FreePageBtreeFirstKey(FreePageBtree *btp)
static Size FreePageBtreeSearchLeaf(FreePageBtree *btp, Size first_page)
static void FreePagePopSpanLeader(FreePageManager *fpm, Size pageno)
static bool FreePageManagerGetInternal(FreePageManager *fpm, Size npages, Size *first_page)
char * FreePageManagerDump(FreePageManager *fpm)
static void FreePageBtreeRemove(FreePageManager *fpm, FreePageBtree *btp, Size index)
static void FreePagePushSpanLeader(FreePageManager *fpm, Size first_page, Size npages)
static void FreePageBtreeInsertInternal(char *base, FreePageBtree *btp, Size index, Size first_page, FreePageBtree *child)
static void FreePageBtreeAdjustAncestorKeys(FreePageManager *fpm, FreePageBtree *btp)
bool FreePageManagerGet(FreePageManager *fpm, Size npages, Size *first_page)
static Size FreePageManagerLargestContiguous(FreePageManager *fpm)
void FreePageManagerPut(FreePageManager *fpm, Size first_page, Size npages)
#define FPM_ITEMS_PER_LEAF_PAGE
static void FreePageManagerUpdateLargest(FreePageManager *fpm)
static FreePageBtree * FreePageBtreeFindLeftSibling(char *base, FreePageBtree *btp)
static FreePageBtree * FreePageBtreeGetRecycled(FreePageManager *fpm)
static FreePageBtree * FreePageBtreeSplitPage(FreePageManager *fpm, FreePageBtree *btp)
static void FreePageBtreeRemovePage(FreePageManager *fpm, FreePageBtree *btp)
static void FreePageBtreeUpdateParentPointers(char *base, FreePageBtree *btp)
#define FREE_PAGE_SPAN_LEADER_MAGIC
static Size FreePageManagerPutInternal(FreePageManager *fpm, Size first_page, Size npages, bool soft)
void FreePageManagerInitialize(FreePageManager *fpm, char *base)
static void FreePageManagerDumpBtree(FreePageManager *fpm, FreePageBtree *btp, FreePageBtree *parent, int level, StringInfo buf)
static Size FreePageBtreeCleanup(FreePageManager *fpm)
static void FreePageBtreeInsertLeaf(FreePageBtree *btp, Size index, Size first_page, Size npages)
static void FreePageBtreeSearch(FreePageManager *fpm, Size first_page, FreePageBtreeSearchResult *result)
#define FPM_ITEMS_PER_INTERNAL_PAGE
static void FreePageBtreeConsolidate(FreePageManager *fpm, FreePageBtree *btp)
#define FREE_PAGE_LEAF_MAGIC
static void FreePageManagerDumpSpans(FreePageManager *fpm, FreePageSpanLeader *span, Size expected_pages, StringInfo buf)
static void FreePageBtreeRecycle(FreePageManager *fpm, Size pageno)
#define fpm_page_to_pointer(base, page)
#define FPM_NUM_FREELISTS
#define fpm_pointer_to_page(base, ptr)
#define fpm_segment_base(fpm)
#define fpm_pointer_is_page_aligned(base, ptr)
static char buf[DEFAULT_XLOG_SEG_SIZE]
#define relptr_is_null(rp)
#define relptr_access(base, rp)
#define relptr_store(base, rp, val)
#define relptr_offset(rp)
#define relptr_copy(rp1, rp2)
void check_stack_depth(void)
void appendStringInfo(StringInfo str, const char *fmt,...)
void appendStringInfoString(StringInfo str, const char *s)
void appendStringInfoChar(StringInfo str, char ch)
void initStringInfo(StringInfo str)
RelptrFreePageBtree child
union FreePageBtree::@35 u
FreePageBtreeInternalKey internal_key[FPM_ITEMS_PER_INTERNAL_PAGE]
FreePageBtreeLeafKey leaf_key[FPM_ITEMS_PER_LEAF_PAGE]
unsigned btree_recycle_count
RelptrFreePageManager self
Size singleton_first_page
RelptrFreePageBtree btree_root
RelptrFreePageSpanLeader freelist[FPM_NUM_FREELISTS]
bool contiguous_pages_dirty
RelptrFreePageSpanLeader btree_recycle
RelptrFreePageSpanLeader prev
RelptrFreePageSpanLeader next