/** Store a page in memory */ size_t PageStore::store_page(void* page) { xbt_assert(top_index_ <= this->capacity_, "top_index is not consistent"); // First, we check if a page with the same content is already in the page // store: // 1. compute the hash of the page; // 2. find pages with the same hash using `hash_index_`; // 3. find a page with the same content. hash_type hash = mc_hash_page(page); // Try to find a duplicate in set of pages with the same hash: page_set_type& page_set = this->hash_index_[hash]; BOOST_FOREACH (size_t pageno, page_set) { const void* snapshot_page = this->get_page(pageno); if (memcmp(page, snapshot_page, xbt_pagesize) == 0) { // If a page with the same content is already in the page store it is // reused and its reference count is incremented. page_counts_[pageno]++; return pageno; } } // Otherwise, a new page is allocated in the page store and the content // of the page is `memcpy()`-ed to this new page. size_t pageno = alloc_page(); xbt_assert(this->page_counts_[pageno]==0, "Allocated page is already used"); void* snapshot_page = (void*) this->get_page(pageno); memcpy(snapshot_page, page, xbt_pagesize); page_set.insert(pageno); page_counts_[pageno]++; return pageno; }
void PageStore::remove_page(size_t pageno) { this->free_pages_.push_back(pageno); const void* page = this->get_page(pageno); hash_type hash = mc_hash_page(page); #ifdef MC_PAGE_STORE_MD4 this->hash_index_.erase(hash); #else this->hash_index_[hash].erase(pageno); #endif }