/* * __compact_rewrite -- * Return if a page needs to be re-written. */ static int __compact_rewrite(WT_SESSION_IMPL *session, WT_REF *ref, int *skipp) { WT_BM *bm; WT_DECL_RET; WT_PAGE *page; WT_PAGE_MODIFY *mod; size_t addr_size; const uint8_t *addr; *skipp = 1; /* Default skip. */ bm = S2BT(session)->bm; page = ref->page; mod = page->modify; /* * Ignore the root: it may not have a replacement address, and besides, * if anything else gets written, so will it. */ if (__wt_ref_is_root(ref)) return (0); /* Ignore currently dirty pages, they will be written regardless. */ if (__wt_page_is_modified(page)) return (0); /* * If the page is clean, test the original addresses. * If the page is a 1-to-1 replacement, test the replacement addresses. * Ignore empty pages, they get merged into the parent. */ if (mod == NULL || F_ISSET(mod, WT_PM_REC_MASK) == 0) { WT_RET(__wt_ref_info(session, ref, &addr, &addr_size, NULL)); if (addr == NULL) return (0); WT_RET( bm->compact_page_skip(bm, session, addr, addr_size, skipp)); } else if (F_ISSET(mod, WT_PM_REC_MASK) == WT_PM_REC_REPLACE) { /* * The page's modification information can change underfoot if * the page is being reconciled, lock the page down. */ WT_PAGE_LOCK(session, page); ret = bm->compact_page_skip(bm, session, mod->mod_replace.addr, mod->mod_replace.size, skipp); WT_PAGE_UNLOCK(session, page); WT_RET(ret); } return (0); }
/*将多余的文件空间compact到合适的位置,如果ref在compact范围内,返回skip = 1,表示文件空间不能进行compact*/ static int __compact_rewrite(WT_SESSION_IMPL* session, WT_REF* ref, int* skipp) { WT_BM *bm; WT_DECL_RET; WT_PAGE *page; WT_PAGE_MODIFY *mod; size_t addr_size; const uint8_t *addr; *skipp = 1; bm = S2BT(session)->bm; page = ref->page; mod = page->modify; /*root page是不能被compact*/ if (__wt_ref_is_root(ref)) return 0; /*ref指向的是个脏页,不进行compact*/ if (__wt_page_is_modified(page)) return (0); /*假如page一已经被清空的,直接判断是否可以它的block空间compact*/ if (mod == NULL || F_ISSET(mod, WT_PM_REC_MASK) == 0) { WT_RET(__wt_ref_info(session, ref, &addr, &addr_size, NULL)); if (addr == NULL) return (0); WT_RET(bm->compact_page_skip(bm, session, addr, addr_size, skipp)); } else if (F_ISSET(mod, WT_PM_REC_MASK) == WT_PM_REC_REPLACE){ /*如果page空间是替换,那么进行替换block的compact操作判断*/ WT_PAGE_LOCK(session, page); ret = bm->compact_page_skip(bm, session, mod->mod_replace.addr, mod->mod_replace.size, skipp); WT_PAGE_UNLOCK(session, page); WT_RET(ret); } return 0; }