void AntiCacheEvictionManager::printLRUChain(PersistentTable* table, int max, bool forward) { VOLT_INFO("num tuples in chain: %d", table->getNumTuplesInEvictionChain()); VOLT_INFO("oldest tuple id: %u", table->getOldestTupleID()); VOLT_INFO("newest tuple id: %u", table->getNewestTupleID()); char chain[max * 4]; int tuple_id; TableTuple tuple = table->tempTuple(); if(forward) tuple_id = table->getOldestTupleID(); else tuple_id = table->getNewestTupleID(); chain[0] = '\0'; int iterations = 0; while(iterations < table->getNumTuplesInEvictionChain() && iterations < max) { strcat(chain, itoa(tuple_id)); strcat(chain, " "); tuple.move(table->dataPtrForTuple(tuple_id)); if(forward) tuple_id = tuple.getNextTupleInChain(); else tuple_id = tuple.getPreviousTupleInChain(); iterations++; } VOLT_INFO("LRU CHAIN: %s", chain); }
bool AntiCacheEvictionManager::removeTupleSingleLinkedList(PersistentTable* table, uint32_t removal_id) { bool tuple_found = false; int tuples_in_chain; // ids for iterating through the list uint32_t current_tuple_id; uint32_t previous_tuple_id; uint32_t next_tuple_id; uint32_t newest_tuple_id; // assert we have tuples in the eviction chain before we try to remove anything tuples_in_chain = table->getNumTuplesInEvictionChain(); if (tuples_in_chain <= 0) return false; previous_tuple_id = 0; current_tuple_id = table->getOldestTupleID(); newest_tuple_id = table->getNewestTupleID(); // set the tuple to the first tuple in the chain (i.e. oldest) TableTuple tuple = table->tempTuple(); tuple.move(table->dataPtrForTuple(current_tuple_id)); // we're removing the head of the chain, i.e. the oldest tuple if (table->getOldestTupleID() == removal_id) { //VOLT_INFO("Removing the first tuple in the eviction chain."); if (table->getNumTuplesInEvictionChain() == 1) { // this is the only tuple in the chain table->setOldestTupleID(0); table->setNewestTupleID(0); } else { next_tuple_id = tuple.getNextTupleInChain(); table->setOldestTupleID(next_tuple_id); } tuple_found = true; } int iterations = 0; while(!tuple_found && iterations < table->getNumTuplesInEvictionChain()) { // we've found the tuple we want to remove if (current_tuple_id == removal_id) { next_tuple_id = tuple.getNextTupleInChain(); // create a tuple from the previous tuple id in the chain tuple.move(table->dataPtrForTuple(previous_tuple_id)); // set the previous tuple to point to the next tuple tuple.setNextTupleInChain(next_tuple_id); tuple_found = true; break; } // advance pointers previous_tuple_id = current_tuple_id; current_tuple_id = tuple.getNextTupleInChain(); tuple.move(table->dataPtrForTuple(current_tuple_id)); iterations++; } if (current_tuple_id == newest_tuple_id && !tuple_found) { // we are at the back of the chain if (current_tuple_id == removal_id) { // we're removing the back of the chain // set the previous tuple pointer to 0 since it is now the back of the chain tuple.move(table->dataPtrForTuple(previous_tuple_id)); tuple.setNextTupleInChain(0); table->setNewestTupleID(previous_tuple_id); tuple_found = true; } } if (tuple_found) { --tuples_in_chain; table->setNumTuplesInEvictionChain(tuples_in_chain); return true; } return false; }
// for the double linked list we start from the tail of the chain and iterate backwards bool AntiCacheEvictionManager::removeTupleDoubleLinkedList(PersistentTable* table, uint32_t removal_id) { bool tuple_found = false; int tuples_in_chain; // ids for iterating through the list uint32_t current_tuple_id; uint32_t previous_tuple_id; uint32_t next_tuple_id; uint32_t oldest_tuple_id; // assert we have tuples in the eviction chain before we try to remove anything tuples_in_chain = table->getNumTuplesInEvictionChain(); if (tuples_in_chain <= 0) return false; previous_tuple_id = 0; oldest_tuple_id = table->getOldestTupleID(); current_tuple_id = table->getNewestTupleID(); // start iteration at back of chain // set the tuple to the back of the chain (i.e. the newest) TableTuple tuple = table->tempTuple(); tuple.move(table->dataPtrForTuple(current_tuple_id)); // we're removing the tail of the chain, i.e. the newest tuple if (table->getNewestTupleID() == removal_id) { if (table->getNumTuplesInEvictionChain() == 1) { // this is the only tuple in the chain table->setOldestTupleID(0); table->setNewestTupleID(0); } else if(table->getNumTuplesInEvictionChain() == 2) { table->setNewestTupleID(oldest_tuple_id); table->setOldestTupleID(oldest_tuple_id); } else { tuple.move(table->dataPtrForTuple(table->getNewestTupleID())); // we need the previous tuple in the chain, since we're iterating from back to front previous_tuple_id = tuple.getPreviousTupleInChain(); table->setNewestTupleID(previous_tuple_id); } tuple_found = true; } // we're removing the head of the chain, i.e. the oldest tuple if(table->getOldestTupleID() == removal_id && !tuple_found) { if (table->getNumTuplesInEvictionChain() == 1) { // this is the only tuple in the chain table->setOldestTupleID(0); table->setNewestTupleID(0); } else if(table->getNumTuplesInEvictionChain() == 2) { table->setNewestTupleID(table->getNewestTupleID()); table->setOldestTupleID(table->getNewestTupleID()); } else { tuple.move(table->dataPtrForTuple(table->getOldestTupleID())); next_tuple_id = tuple.getNextTupleInChain(); table->setOldestTupleID(next_tuple_id); } tuple_found = true; } int iterations = 0; while(!tuple_found && iterations < table->getNumTuplesInEvictionChain()) { if(current_tuple_id == oldest_tuple_id) break; // we've found the tuple we want to remove if (current_tuple_id == removal_id) { next_tuple_id = tuple.getPreviousTupleInChain(); // point previous tuple in chain to next tuple tuple.move(table->dataPtrForTuple(previous_tuple_id)); tuple.setPreviousTupleInChain(next_tuple_id); // point next tuple in chain to previous tuple tuple.move(table->dataPtrForTuple(next_tuple_id)); tuple.setNextTupleInChain(previous_tuple_id); tuple_found = true; break; } // advance pointers previous_tuple_id = current_tuple_id; current_tuple_id = tuple.getPreviousTupleInChain(); // iterate back to front tuple.move(table->dataPtrForTuple(current_tuple_id)); iterations++; } if (tuple_found) { tuples_in_chain = table->getNumTuplesInEvictionChain(); --tuples_in_chain; table->setNumTuplesInEvictionChain(tuples_in_chain); return true; } return false; }