summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Cahill <mjc@wiredtiger.com>2012-04-03 15:36:55 -0700
committerMichael Cahill <mjc@wiredtiger.com>2012-04-03 15:36:55 -0700
commit75bca7e8f18f1715e1e1d8b66b51533496ee5f4e (patch)
treed0082883bdbdd20af33d18178dd584aeada80922
parent2da36349a2fb9884221806ff85abf934d032130c (diff)
parent7ef387690614ee39cc7fd735ccd0b88321f3f60d (diff)
downloadmongo-75bca7e8f18f1715e1e1d8b66b51533496ee5f4e.tar.gz
Merge pull request #188 from wiredtiger/feature/eviction-fixes
Merge eviction-fixes into develop.
-rw-r--r--src/btree/bt_discard.c2
-rw-r--r--src/btree/bt_evict.c195
-rw-r--r--src/btree/bt_walk.c10
-rw-r--r--src/btree/rec_evict.c62
-rw-r--r--src/include/btmem.h9
-rw-r--r--src/include/extern.h1
6 files changed, 152 insertions, 127 deletions
diff --git a/src/btree/bt_discard.c b/src/btree/bt_discard.c
index f77a89f3613..8ffb02ea271 100644
--- a/src/btree/bt_discard.c
+++ b/src/btree/bt_discard.c
@@ -32,6 +32,8 @@ __wt_page_out(WT_SESSION_IMPL *session, WT_PAGE *page, uint32_t flags)
page->parent = NULL;
page->ref = NULL;
+ WT_ASSERT(session, !F_ISSET(page, WT_PAGE_EVICT_LRU));
+
/* If not a split merged into its parent, the page must be clean. */
WT_ASSERT(session,
!__wt_page_is_modified(page) ||
diff --git a/src/btree/bt_evict.c b/src/btree/bt_evict.c
index c7a72bb5b45..86036d68553 100644
--- a/src/btree/bt_evict.c
+++ b/src/btree/bt_evict.c
@@ -7,12 +7,11 @@
#include "wt_internal.h"
-static void __evict_dup_remove(WT_SESSION_IMPL *);
static int __evict_file(WT_SESSION_IMPL *, WT_EVICT_REQ *);
static int __evict_lru(WT_SESSION_IMPL *);
static int __evict_lru_cmp(const void *, const void *);
+static void __evict_lru_sort(WT_SESSION_IMPL *);
static void __evict_pages(WT_SESSION_IMPL *);
-static int __evict_page_cmp(const void *, const void *);
static int __evict_request_walk(WT_SESSION_IMPL *);
static int __evict_walk(WT_SESSION_IMPL *);
static int __evict_walk_file(WT_SESSION_IMPL *, u_int *);
@@ -40,13 +39,67 @@ static int __evict_worker(WT_SESSION_IMPL *);
* Clear an entry in the eviction list.
*/
static inline void
-__evict_clr(WT_EVICT_LIST *e)
+__evict_clr(WT_SESSION_IMPL *session, WT_EVICT_LIST *e)
{
+ if (e->page != NULL) {
+ WT_ASSERT(session, F_ISSET(e->page, WT_PAGE_EVICT_LRU));
+ F_CLR(e->page, WT_PAGE_EVICT_LRU);
+ }
e->page = NULL;
e->btree = WT_DEBUG_POINT;
}
/*
+ * __evict_clr_all --
+ * Clear all entries in the eviction list.
+ */
+static inline void
+__evict_clr_all(WT_SESSION_IMPL *session)
+{
+ WT_CACHE *cache;
+ WT_EVICT_LIST *evict;
+ int i, elem;
+
+ cache = S2C(session)->cache;
+
+ elem = cache->evict_entries;
+ for (evict = cache->evict, i = 0; i < elem; i++, evict++)
+ __evict_clr(session, evict);
+}
+
+/*
+ * __wt_evict_clr_page --
+ * Make sure a page is not in the eviction request list. This called
+ * from inside __rec_review to make sure there is no attempt to evict
+ * child pages multiple times.
+ */
+void
+__wt_evict_clr_page(WT_SESSION_IMPL *session, WT_PAGE *page)
+{
+ WT_CACHE *cache;
+ WT_EVICT_LIST *evict;
+ int i, elem;
+
+ /* Fast path: if the page isn't on the queue, don't bother searching. */
+ if (!F_ISSET(page, WT_PAGE_EVICT_LRU))
+ return;
+
+ cache = S2C(session)->cache;
+ __wt_spin_lock(session, &cache->lru_lock);
+
+ elem = cache->evict_entries;
+ for (evict = cache->evict, i = 0; i < elem; i++, evict++)
+ if (evict->page == page) {
+ __evict_clr(session, evict);
+ break;
+ }
+
+ WT_ASSERT(session, !F_ISSET(page, WT_PAGE_EVICT_LRU));
+
+ __wt_spin_unlock(session, &cache->lru_lock);
+}
+
+/*
* __evict_req_set --
* Set an entry in the eviction request list.
*/
@@ -353,7 +406,7 @@ __evict_request_walk(WT_SESSION_IMPL *session)
* The eviction candidate list might reference pages we are
* about to discard; clear it.
*/
- memset(cache->evict, 0, cache->evict_allocated);
+ __evict_clr_all(session);
if (F_ISSET(er, WT_EVICT_REQ_PAGE)) {
ref = er->page->ref;
@@ -418,16 +471,20 @@ static int
__evict_file(WT_SESSION_IMPL *session, WT_EVICT_REQ *er)
{
WT_PAGE *next_page, *page;
+ WT_REF *ref;
WT_VERBOSE(session, evictserver,
"file request: %s",
(F_ISSET(er, WT_EVICT_REQ_CLOSE) ? "close" : "sync"));
/* Clear the current eviction point. */
- if ((page = session->btree->evict_page) != NULL &&
- !WT_PAGE_IS_ROOT(page))
- (void)WT_ATOMIC_CAS(page->ref->state,
- WT_REF_EVICT_WALK, WT_REF_MEM);
+ page = session->btree->evict_page;
+ while (page != NULL && !WT_PAGE_IS_ROOT(page)) {
+ ref = page->ref;
+ page = page->parent;
+ WT_ASSERT(session, ref->state == WT_REF_EVICT_WALK);
+ ref->state = WT_REF_MEM;
+ }
session->btree->evict_page = NULL;
/* If this is a close, wait for LRU eviction activity to drain. */
@@ -490,9 +547,9 @@ __evict_lru(WT_SESSION_IMPL *session)
/* Get some more pages to consider for eviction. */
WT_RET(__evict_walk(session));
- /* Sort and remove duplicates from the list, restart. */
+ /* Sort the list into LRU order and restart. */
__wt_spin_lock(session, &cache->lru_lock);
- __evict_dup_remove(session);
+ __evict_lru_sort(session);
cache->evict_current = cache->evict;
__wt_spin_unlock(session, &cache->lru_lock);
@@ -534,8 +591,8 @@ __evict_walk(WT_SESSION_IMPL *session)
*/
elem = WT_EVICT_WALK_BASE + (conn->btqcnt * WT_EVICT_WALK_PER_TABLE);
if (elem > cache->evict_entries) {
- __wt_spin_lock(session, &cache->lru_lock);
/* Save the offset of the eviction point. */
+ __wt_spin_lock(session, &cache->lru_lock);
i = (u_int)(cache->evict_current - cache->evict);
WT_ERR(__wt_realloc(session, &cache->evict_allocated,
elem * sizeof(WT_EVICT_LIST), &cache->evict));
@@ -555,10 +612,13 @@ __evict_walk(WT_SESSION_IMPL *session)
WT_CLEAR_BTREE_IN_SESSION(session);
if (ret != 0)
- goto err;
+ break;
}
-err: __wt_spin_unlock(session, &conn->spinlock);
+ if (0) {
+err: __wt_spin_unlock(session, &cache->lru_lock);
+ }
+ __wt_spin_unlock(session, &conn->spinlock);
return (ret);
}
@@ -571,11 +631,14 @@ __evict_walk_file(WT_SESSION_IMPL *session, u_int *slotp)
{
WT_BTREE *btree;
WT_CACHE *cache;
+ WT_EVICT_LIST *end, *evict, *start;
WT_PAGE *page;
- int i, restarts, ret;
+ int restarts, ret;
btree = session->btree;
cache = S2C(session)->cache;
+ start = cache->evict + *slotp;
+ end = start + WT_EVICT_WALK_PER_TABLE;
/*
* Get the next WT_EVICT_WALK_PER_TABLE entries.
@@ -583,8 +646,8 @@ __evict_walk_file(WT_SESSION_IMPL *session, u_int *slotp)
* We can't evict the page just returned to us, it marks our place in
* the tree. So, always stay one page ahead of the page being returned.
*/
- for (i = restarts = ret = 0;
- i < WT_EVICT_WALK_PER_TABLE && restarts <= 1 && ret == 0;
+ for (evict = start, restarts = ret = 0;
+ evict < end && restarts <= 1 && ret == 0;
ret = __wt_tree_np(session, &btree->evict_page, 1, 1)) {
if ((page = btree->evict_page) == NULL) {
++restarts;
@@ -593,40 +656,44 @@ __evict_walk_file(WT_SESSION_IMPL *session, u_int *slotp)
/*
* Root pages can't be evicted, nor can skip pages that must be
- * merged into their parents. Don't skip pages marked
- * WT_PAGE_REC_EMPTY or SPLIT: updates after their last
- * reconciliation may have changed their state and only the
- * eviction code can check whether they should really be
- * skipped.
+ * merged into their parents. Use the EVICT_LRU flag to avoid
+ * putting pages onto the list multiple times.
+ *
+ * Don't skip pages marked WT_PAGE_REC_EMPTY or SPLIT: updates
+ * after their last reconciliation may have changed their state
+ * and only the eviction code can check whether they should
+ * really be skipped.
*/
if (WT_PAGE_IS_ROOT(page) ||
- F_ISSET(page, WT_PAGE_REC_SPLIT_MERGE))
+ F_ISSET(page, WT_PAGE_EVICT_LRU | WT_PAGE_REC_SPLIT_MERGE))
continue;
WT_VERBOSE(session, evictserver,
"select: %p, size %" PRIu32, page, page->memory_footprint);
- ++i;
- cache->evict[*slotp].page = page;
- cache->evict[*slotp].btree = btree;
- ++*slotp;
+ WT_ASSERT(session, page->ref->state == WT_REF_EVICT_WALK);
+
+ /* Mark the page on the list */
+ F_SET(page, WT_PAGE_EVICT_LRU);
+
+ __evict_clr(session, evict);
+ evict->page = page;
+ evict->btree = btree;
+ ++evict;
}
+ *slotp += (u_int)(evict - start);
return (ret);
}
/*
- * __evict_dup_remove --
- * Discard duplicates from the list of pages we collected.
+ * __evict_lru_sort --
+ * Sort the list of pages queued for eviction into LRU order.
*/
static void
-__evict_dup_remove(WT_SESSION_IMPL *session)
+__evict_lru_sort(WT_SESSION_IMPL *session)
{
WT_CACHE *cache;
- WT_EVICT_LIST *evict;
- u_int elem, i, j;
-
- cache = S2C(session)->cache;
/*
* We have an array of page eviction references that may contain NULLs,
@@ -642,26 +709,9 @@ __evict_dup_remove(WT_SESSION_IMPL *session)
* page and its parent, the duplicate of the page's WT_REF might have
* been free'd before a subsequent review of the eviction array.)
*/
- evict = cache->evict;
- elem = cache->evict_entries;
- qsort(evict, elem, sizeof(WT_EVICT_LIST), __evict_page_cmp);
- for (i = 0; i < elem; i = j) {
- /*
- * Once we hit a NULL, we're done, the NULLs all sorted to the
- * end of the array.
- */
- if (evict[i].page == NULL)
- break;
-
- /* Delete any subsequent duplicates. */
- for (j = i + 1;
- j < elem && evict[j].page == evict[i].page;
- ++j)
- __evict_clr(&evict[j]);
- }
-
- /* Sort the array by LRU, then evict the most promising candidates. */
- qsort(evict, i, sizeof(WT_EVICT_LIST), __evict_lru_cmp);
+ cache = S2C(session)->cache;
+ qsort(cache->evict,
+ cache->evict_entries, sizeof(WT_EVICT_LIST), __evict_lru_cmp);
}
/*
@@ -725,14 +775,14 @@ __evict_get_page(
*/
WT_ATOMIC_ADD(evict->btree->lru_count, 1);
- *pagep = evict->page;
*btreep = evict->btree;
+ *pagep = evict->page;
/*
- * Paranoia: remove the entry so we never try and reconcile
- * the same page on reconciliation error.
+ * Remove the entry so we never try and reconcile the same page
+ * on reconciliation error.
*/
- __evict_clr(evict);
+ __evict_clr(session, evict);
break;
}
@@ -789,35 +839,8 @@ __wt_evict_lru_page(WT_SESSION_IMPL *session, int is_app)
static void
__evict_pages(WT_SESSION_IMPL *session)
{
- u_int i;
-
- for (i = 0; i < WT_EVICT_GROUP / 2; i++)
- if (__wt_evict_lru_page(session, 0) != 0)
- break;
-}
-
-/*
- * __evict_page_cmp --
- * Qsort function: sort WT_EVICT_LIST array based on the page's address.
- */
-static int
-__evict_page_cmp(const void *a, const void *b)
-{
- WT_PAGE *a_page, *b_page;
-
- /*
- * There may be NULL references in the array; sort them as greater than
- * anything else so they migrate to the end of the array.
- */
- a_page = ((WT_EVICT_LIST *)a)->page;
- b_page = ((WT_EVICT_LIST *)b)->page;
- if (a_page == NULL)
- return (b_page == NULL ? 0 : 1);
- if (b_page == NULL)
- return (-1);
-
- /* Sort the page address in ascending order. */
- return (a_page > b_page ? 1 : (a_page < b_page ? -1 : 0));
+ while (__wt_evict_lru_page(session, 0) == 0)
+ ;
}
/*
diff --git a/src/btree/bt_walk.c b/src/btree/bt_walk.c
index 38aa8eb3eb8..990547ab947 100644
--- a/src/btree/bt_walk.c
+++ b/src/btree/bt_walk.c
@@ -62,11 +62,6 @@ __wt_tree_np(WT_SESSION_IMPL *session, WT_PAGE **pagep, int eviction, int next)
* that can't be discarded.
*/
if (eviction) {
- if (!WT_PAGE_IS_ROOT(t)) {
- while (!WT_ATOMIC_CAS(t->ref->state,
- WT_REF_MEM, WT_REF_EVICT_WALK))
- __wt_yield();
- }
WT_ASSERT(session, page->ref->state == WT_REF_EVICT_WALK);
page->ref->state = WT_REF_MEM;
} else {
@@ -107,11 +102,6 @@ descend: for (;;) {
if (!WT_ATOMIC_CAS(ref->state,
WT_REF_MEM, WT_REF_EVICT_WALK))
break;
- if (!WT_PAGE_IS_ROOT(page)) {
- WT_ASSERT(session, page->ref->state ==
- WT_REF_EVICT_WALK);
- page->ref->state = WT_REF_MEM;
- }
} else {
/*
* Swap hazard references at each level (but
diff --git a/src/btree/rec_evict.c b/src/btree/rec_evict.c
index fa86b0a943f..b724739df48 100644
--- a/src/btree/rec_evict.c
+++ b/src/btree/rec_evict.c
@@ -8,15 +8,15 @@
#include "wt_internal.h"
static int __hazard_exclusive(WT_SESSION_IMPL *, WT_REF *, int);
-static int __rec_discard(WT_SESSION_IMPL *, WT_PAGE *);
-static int __rec_discard_page(WT_SESSION_IMPL *, WT_PAGE *);
+static int __rec_discard(WT_SESSION_IMPL *, WT_PAGE *, int);
+static int __rec_discard_page(WT_SESSION_IMPL *, WT_PAGE *, int);
static void __rec_excl_clear(WT_SESSION_IMPL *);
-static int __rec_page_clean_update(WT_SESSION_IMPL *, WT_PAGE *);
-static int __rec_page_dirty_update(WT_SESSION_IMPL *, WT_PAGE *);
+static int __rec_page_clean_update(WT_SESSION_IMPL *, WT_PAGE *, int);
+static int __rec_page_dirty_update(WT_SESSION_IMPL *, WT_PAGE *, int);
static int __rec_review(WT_SESSION_IMPL *, WT_REF *, WT_PAGE *, uint32_t, int);
static int __rec_root_addr_update(WT_SESSION_IMPL *, uint8_t *, uint32_t);
-static int __rec_root_clean_update(WT_SESSION_IMPL *, WT_PAGE *);
-static int __rec_root_dirty_update(WT_SESSION_IMPL *, WT_PAGE *);
+static int __rec_root_clean_update(WT_SESSION_IMPL *, WT_PAGE *, int);
+static int __rec_root_dirty_update(WT_SESSION_IMPL *, WT_PAGE *, int);
/*
* __wt_rec_evict --
@@ -26,7 +26,7 @@ int
__wt_rec_evict(WT_SESSION_IMPL *session, WT_PAGE *page, uint32_t flags)
{
WT_CONNECTION_IMPL *conn;
- int ret;
+ int ret, single;
conn = S2C(session);
ret = 0;
@@ -35,6 +35,7 @@ __wt_rec_evict(WT_SESSION_IMPL *session, WT_PAGE *page, uint32_t flags)
"page %p (%s)", page, __wt_page_type_string(page->type));
WT_ASSERT(session, session->excl_next == 0);
+ single = LF_ISSET(WT_REC_SINGLE) ? 1 : 0;
/*
* Get exclusive access to the page and review the page and its subtree
@@ -51,7 +52,7 @@ __wt_rec_evict(WT_SESSION_IMPL *session, WT_PAGE *page, uint32_t flags)
WT_ERR(__rec_review(session, page->ref, page, flags, 1));
/* Count evictions of internal pages during normal operation. */
- if (!LF_ISSET(WT_REC_SINGLE) &&
+ if (!single &&
(page->type == WT_PAGE_COL_INT || page->type == WT_PAGE_ROW_INT))
WT_STAT_INCR(conn->stats, cache_evict_internal);
@@ -60,16 +61,16 @@ __wt_rec_evict(WT_SESSION_IMPL *session, WT_PAGE *page, uint32_t flags)
WT_STAT_INCR(conn->stats, cache_evict_unmodified);
if (WT_PAGE_IS_ROOT(page))
- WT_ERR(__rec_root_clean_update(session, page));
+ WT_ERR(__rec_root_clean_update(session, page, single));
else
- WT_ERR(__rec_page_clean_update(session, page));
+ WT_ERR(__rec_page_clean_update(session, page, single));
} else {
WT_STAT_INCR(conn->stats, cache_evict_modified);
if (WT_PAGE_IS_ROOT(page))
- WT_ERR(__rec_root_dirty_update(session, page));
+ WT_ERR(__rec_root_dirty_update(session, page, single));
else
- WT_ERR(__rec_page_dirty_update(session, page));
+ WT_ERR(__rec_page_dirty_update(session, page, single));
}
if (0) {
@@ -88,13 +89,13 @@ err: /*
* Update a page's reference for an evicted, clean page.
*/
static int
-__rec_page_clean_update(WT_SESSION_IMPL *session, WT_PAGE *page)
+__rec_page_clean_update(WT_SESSION_IMPL *session, WT_PAGE *page, int single)
{
/* Update the relevant WT_REF structure. */
WT_PUBLISH(page->ref->state, WT_REF_DISK);
page->ref->page = NULL;
- return (__rec_discard_page(session, page));
+ return (__rec_discard_page(session, page, single));
}
/*
@@ -102,7 +103,7 @@ __rec_page_clean_update(WT_SESSION_IMPL *session, WT_PAGE *page)
* Update a page's reference for an evicted, clean page.
*/
static int
-__rec_root_clean_update(WT_SESSION_IMPL *session, WT_PAGE *page)
+__rec_root_clean_update(WT_SESSION_IMPL *session, WT_PAGE *page, int single)
{
WT_BTREE *btree;
@@ -110,7 +111,7 @@ __rec_root_clean_update(WT_SESSION_IMPL *session, WT_PAGE *page)
btree->root_page = NULL;
- return (__rec_discard_page(session, page));
+ return (__rec_discard_page(session, page, single));
}
/*
@@ -118,7 +119,7 @@ __rec_root_clean_update(WT_SESSION_IMPL *session, WT_PAGE *page)
* Update a page's reference for an evicted, dirty page.
*/
static int
-__rec_page_dirty_update(WT_SESSION_IMPL *session, WT_PAGE *page)
+__rec_page_dirty_update(WT_SESSION_IMPL *session, WT_PAGE *page, int single)
{
WT_PAGE_MODIFY *mod;
WT_REF *parent_ref;
@@ -170,7 +171,7 @@ __rec_page_dirty_update(WT_SESSION_IMPL *session, WT_PAGE *page)
* Discard pages which were merged into this page during reconciliation,
* then discard the page itself.
*/
- WT_RET(__rec_discard(session, page));
+ WT_RET(__rec_discard(session, page, single));
return (0);
}
@@ -206,7 +207,7 @@ __rec_root_addr_update(WT_SESSION_IMPL *session, uint8_t *addr, uint32_t size)
* Update the reference for an evicted, dirty root page.
*/
static int
-__rec_root_dirty_update(WT_SESSION_IMPL *session, WT_PAGE *page)
+__rec_root_dirty_update(WT_SESSION_IMPL *session, WT_PAGE *page, int single)
{
WT_BTREE *btree;
WT_PAGE *next;
@@ -248,7 +249,7 @@ __rec_root_dirty_update(WT_SESSION_IMPL *session, WT_PAGE *page)
* Discard pages which were merged into this page during reconciliation,
* then discard the page itself.
*/
- WT_RET(__rec_discard(session, page));
+ WT_RET(__rec_discard(session, page, single));
if (next == NULL)
return (0);
@@ -274,7 +275,7 @@ __rec_root_dirty_update(WT_SESSION_IMPL *session, WT_PAGE *page)
WT_RET(__wt_rec_write(session, next, NULL));
- return (__rec_root_dirty_update(session, next));
+ return (__rec_root_dirty_update(session, next, single));
}
/*
@@ -282,7 +283,7 @@ __rec_root_dirty_update(WT_SESSION_IMPL *session, WT_PAGE *page)
* Discard any pages merged into an evicted page, then the page itself.
*/
static int
-__rec_discard(WT_SESSION_IMPL *session, WT_PAGE *page)
+__rec_discard(WT_SESSION_IMPL *session, WT_PAGE *page, int single)
{
WT_REF *ref;
uint32_t i;
@@ -291,12 +292,16 @@ __rec_discard(WT_SESSION_IMPL *session, WT_PAGE *page)
case WT_PAGE_COL_INT:
case WT_PAGE_ROW_INT:
/* For each entry in the page... */
- WT_REF_FOREACH(page, ref, i)
- if (ref->state != WT_REF_DISK)
- WT_RET(__rec_discard(session, ref->page));
+ WT_REF_FOREACH(page, ref, i) {
+ if (ref->state == WT_REF_DISK)
+ continue;
+ WT_ASSERT(session,
+ single || ref->state == WT_REF_LOCKED);
+ WT_RET(__rec_discard(session, ref->page, single));
+ }
/* FALLTHROUGH */
default:
- WT_RET(__rec_discard_page(session, page));
+ WT_RET(__rec_discard_page(session, page, single));
break;
}
return (0);
@@ -307,7 +312,7 @@ __rec_discard(WT_SESSION_IMPL *session, WT_PAGE *page)
* Process the page's list of tracked objects, and discard it.
*/
static int
-__rec_discard_page(WT_SESSION_IMPL *session, WT_PAGE *page)
+__rec_discard_page(WT_SESSION_IMPL *session, WT_PAGE *page, int single)
{
WT_PAGE_MODIFY *mod;
@@ -337,6 +342,9 @@ __rec_discard_page(WT_SESSION_IMPL *session, WT_PAGE *page)
/* We should never evict the file's current eviction point. */
WT_ASSERT(session, session->btree->evict_page != page);
+ if (!single)
+ __wt_evict_clr_page(session, page);
+
/* Discard the page itself. */
__wt_page_out(session, page, 0);
diff --git a/src/include/btmem.h b/src/include/btmem.h
index e8ec2c7e9f7..b27cbeb3095 100644
--- a/src/include/btmem.h
+++ b/src/include/btmem.h
@@ -292,10 +292,11 @@ struct __wt_page {
* the threads could race.
*/
#define WT_PAGE_BUILD_KEYS 0x001 /* Keys have been built in memory */
-#define WT_PAGE_REC_EMPTY 0x002 /* Reconciliation: page empty */
-#define WT_PAGE_REC_REPLACE 0x004 /* Reconciliation: page replaced */
-#define WT_PAGE_REC_SPLIT 0x008 /* Reconciliation: page split */
-#define WT_PAGE_REC_SPLIT_MERGE 0x010 /* Reconciliation: page split merge */
+#define WT_PAGE_EVICT_LRU 0x002 /* Page is on the LRU queue */
+#define WT_PAGE_REC_EMPTY 0x004 /* Reconciliation: page empty */
+#define WT_PAGE_REC_REPLACE 0x008 /* Reconciliation: page replaced */
+#define WT_PAGE_REC_SPLIT 0x010 /* Reconciliation: page split */
+#define WT_PAGE_REC_SPLIT_MERGE 0x020 /* Reconciliation: page split merge */
uint8_t flags; /* Page flags */
};
diff --git a/src/include/extern.h b/src/include/extern.h
index e5d53b95ee3..652618bcd87 100644
--- a/src/include/extern.h
+++ b/src/include/extern.h
@@ -192,6 +192,7 @@ extern int __wt_debug_page(WT_SESSION_IMPL *session,
extern void __wt_page_out(WT_SESSION_IMPL *session,
WT_PAGE *page,
uint32_t flags);
+extern void __wt_evict_clr_page(WT_SESSION_IMPL *session, WT_PAGE *page);
extern void __wt_evict_server_wake(WT_SESSION_IMPL *session);
extern void __wt_evict_file_serial_func(WT_SESSION_IMPL *session);
extern int __wt_evict_page_request(WT_SESSION_IMPL *session, WT_PAGE *page);