Skip to content
This repository was archived by the owner on Aug 10, 2025. It is now read-only.

Commit d87cefe

Browse files
committed
Two bug fix for anticache:
1. Unevicted blocks might be evicted again in the uneviction from another table. Now we can only check whether the evicted block ID is still valid. 2. Original EvictedAccessException cannot be used with tuple-merge strategy. There was a hack in that. But still there's a problem with stats.
1 parent 87465c6 commit d87cefe

File tree

11 files changed

+99
-25
lines changed

11 files changed

+99
-25
lines changed

src/ee/anticache/AntiCacheDB.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ class AntiCacheDB {
117117
*/
118118
virtual AntiCacheBlock* readBlock(uint16_t blockId, bool isMigrate) = 0;
119119

120+
virtual bool validateBlock(uint16_t blockId) = 0;
121+
120122

121123
/**
122124
* Flush the buffered blocks to disk.

src/ee/anticache/AntiCacheEvictionManager.cpp

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,7 +1175,7 @@ bool AntiCacheEvictionManager::readEvictedBlock(PersistentTable *table, int32_t
11751175

11761176
int already_unevicted = table->isAlreadyUnEvicted(block_id);
11771177
if (already_unevicted && table->mergeStrategy()) { // this block has already been read
1178-
VOLT_WARN("Block 0x%x has already been read.", block_id);
1178+
VOLT_WARN("Block %d has already been read.", block_id);
11791179
return true;
11801180
}
11811181

@@ -1189,14 +1189,26 @@ bool AntiCacheEvictionManager::readEvictedBlock(PersistentTable *table, int32_t
11891189

11901190
AntiCacheDB* antiCacheDB = m_db_lookup[ACID];
11911191

1192+
if (!antiCacheDB->validateBlock(_block_id)) {
1193+
VOLT_WARN("Block %d has already been read from another table.", block_id);
1194+
return true;
1195+
}
1196+
11921197
if (already_unevicted) { // this block has already been read, but it is tuple-merge strategy
1198+
/* This is a HACK!! CHANGE LATER!!
1199+
for (int k = 0; k < (int)table->unevictedBlocksSize(); ++k) {
1200+
if (table->getMergeTupleOffset(k) == tuple_offset) {
1201+
return true;
1202+
}
1203+
}*/
1204+
11931205
table->insertUnevictedBlock(table->getUnevictedBlocks(already_unevicted - 1));
11941206
table->insertTupleOffset(tuple_offset);
11951207

11961208
antiCacheDB->removeSingleTupleStats(_block_id);
11971209

11981210
VOLT_DEBUG("BLOCK %u TUPLE %d - unevicted blocks size is %d",
1199-
block_id, tuple_offset, already_unevicted);
1211+
block_id, tuple_offset, (int)table->unevictedBlocksSize());
12001212

12011213
return true;
12021214
}
@@ -1221,6 +1233,8 @@ bool AntiCacheEvictionManager::readEvictedBlock(PersistentTable *table, int32_t
12211233
//AntiCacheDB* antiCacheDB = table->getAntiCacheDB();
12221234

12231235
try {
1236+
VOLT_DEBUG("BLOCK %u %d - unevicted blocks size is %d - alreadyUevicted %d",
1237+
_block_id, block_id, static_cast<int>(table->unevictedBlocksSize()), already_unevicted);
12241238
AntiCacheBlock* value = antiCacheDB->readBlock(_block_id, 0);
12251239

12261240
// allocate the memory for this block
@@ -1250,12 +1264,11 @@ bool AntiCacheEvictionManager::readEvictedBlock(PersistentTable *table, int32_t
12501264
}
12511265

12521266
table->insertUnevictedBlock(unevicted_tuples);
1253-
VOLT_DEBUG("BLOCK %u - unevicted blocks size is %d",
1254-
_block_id, static_cast<int>(table->unevictedBlocksSize()));
12551267
table->insertTupleOffset(tuple_offset);
12561268

12571269

12581270
table->insertUnevictedBlockID(std::pair<int32_t,int32_t>(block_id, table->unevictedBlocksSize()));
1271+
VOLT_DEBUG("after insert: alreadyUnevicted %d - IDs size %ld", table->isAlreadyUnEvicted(block_id), table->getUnevictedBlockIDs().size());
12591272

12601273
VOLT_DEBUG("BLOCK %u TUPLE %d - unevicted blocks size is %d",
12611274
block_id, tuple_offset, static_cast<int>(table->unevictedBlocksSize()));
@@ -1575,23 +1588,25 @@ bool AntiCacheEvictionManager::mergeUnevictedTuples(PersistentTable *table) {
15751588
#ifdef VOLT_INFO_ENABLED
15761589
VOLT_INFO("Merging %d blocks for table %s.", num_blocks, table->name().c_str());
15771590
#endif
1591+
VOLT_INFO("Merging %d blocks for table %s.", num_blocks, table->name().c_str());
15781592

15791593
for (int i = 0; i < num_blocks; i++) {
15801594
// XXX: have to put block size, which we don't know, so just put something large, like 10MB
15811595
ReferenceSerializeInput in(table->getUnevictedBlocks(i), 10485760);
15821596

1597+
merge_tuple_offset = table->getMergeTupleOffset(i); // what to do about this?
1598+
VOLT_DEBUG("Merge Tuple offset is %d", merge_tuple_offset);
1599+
15831600
// Read in all the meta-data
15841601
int num_tables = in.readInt();
15851602
std::vector<std::string> tableNames;
15861603
std::vector<int> numTuples;
15871604
for(int j = 0; j < num_tables; j++){
15881605
tableNames.push_back(in.readTextString());
15891606
numTuples.push_back(in.readInt());
1607+
VOLT_TRACE("%s", tableNames[j].c_str());
15901608
}
15911609

1592-
merge_tuple_offset = table->getMergeTupleOffset(i); // what to do about this?
1593-
//VOLT_INFO("Tuple offset is %d", merge_tuple_offset);
1594-
15951610
int count = 0;
15961611
for (std::vector<std::string>::iterator it = tableNames.begin() ; it != tableNames.end(); ++it){
15971612
PersistentTable *tableInBlock = dynamic_cast<PersistentTable*>(m_engine->getTable(*it));
@@ -1686,6 +1701,8 @@ bool AntiCacheEvictionManager::mergeUnevictedTuples(PersistentTable *table) {
16861701
}
16871702
table->clearUnevictedBlocks();
16881703
table->clearMergeTupleOffsets();
1704+
VOLT_DEBUG("unevicted blockIDs size %d", static_cast<int>(table->getUnevictedBlockIDs().size()));
1705+
VOLT_DEBUG("unevicted blocks size %d", static_cast<int>(table->unevictedBlocksSize()));
16891706

16901707
//VOLT_ERROR("Active Tuple Count: %d -- %d", (int)active_tuple_count, (int)table->activeTupleCount());
16911708
#ifndef ANTICACHE_TIMESTAMPS
@@ -1721,6 +1738,17 @@ void AntiCacheEvictionManager::recordEvictedAccess(catalog::Table* catalogTable,
17211738
if (m_blockable_accesses && !(block_id & 0x00080000)) {
17221739
m_blockable_accesses = false;
17231740
}
1741+
1742+
/*
1743+
if (m_evicted_filter.find(block_id) != m_evicted_filter.end())
1744+
if (m_evicted_filter[block_id].find(tuple_id) != m_evicted_filter[block_id].end()) {
1745+
VOLT_ERROR("try skipping %d %d", block_id, tuple_id);
1746+
return;
1747+
}
1748+
1749+
(m_evicted_filter[block_id]).insert(tuple_id);*/
1750+
//VOLT_ERROR("try reading %d %d", block_id, tuple_id);
1751+
17241752
m_evicted_tables.push_back(catalogTable);
17251753
m_evicted_block_ids.push_back(block_id);
17261754
m_evicted_offsets.push_back(tuple_id);
@@ -1745,14 +1773,14 @@ void AntiCacheEvictionManager::throwEvictedAccessException() {
17451773
// copy the block ids into an array
17461774
int num_blocks = 0;
17471775
for(vector<int32_t>::iterator itr = m_evicted_block_ids.begin(); itr != m_evicted_block_ids.end(); ++itr) {
1748-
VOLT_DEBUG("Marking block %d as being needed for uneviction", *itr);
1776+
VOLT_TRACE("Marking block %d as being needed for uneviction", *itr);
17491777
block_ids[num_blocks++] = *itr;
17501778
}
17511779

17521780
// copy the tuple offsets into an array
17531781
int num_tuples = 0;
17541782
for(vector<int32_t>::iterator itr = m_evicted_offsets.begin(); itr != m_evicted_offsets.end(); ++itr) {
1755-
VOLT_DEBUG("Marking tuple %d from %s as being needed for uneviction", *itr, m_evicted_tables[num_tuples]->name().c_str());
1783+
VOLT_TRACE("Marking tuple %d from %s as being needed for uneviction", *itr, m_evicted_tables[num_tuples]->name().c_str());
17561784
tuple_ids[num_tuples++] = *itr;
17571785
}
17581786

@@ -1761,7 +1789,7 @@ void AntiCacheEvictionManager::throwEvictedAccessException() {
17611789

17621790
// Do we really want to throw this here?
17631791
// FIXME We need to support multiple tables in the exception data
1764-
VOLT_INFO("Throwing EvictedTupleAccessException for table %s (%d) "
1792+
VOLT_DEBUG("Throwing EvictedTupleAccessException for table %s (%d) "
17651793
"[num_blocks=%d / num_tuples=%d]",
17661794
catalogTable->name().c_str(), catalogTable->relativeIndex(),
17671795
num_blocks, num_tuples);

src/ee/anticache/AntiCacheEvictionManager.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838

3939
#include <vector>
4040
#include <map>
41+
#include <pthread.h>
4142

4243
#define MAX_DBS 8
4344

@@ -84,6 +85,7 @@ class AntiCacheEvictionManager {
8485
m_evicted_tables.clear();
8586
m_evicted_block_ids.clear();
8687
m_evicted_offsets.clear();
88+
m_evicted_filter.clear();
8789
m_blockable_accesses = true;
8890
}
8991
inline bool hasEvictedAccesses() const {
@@ -119,6 +121,7 @@ class AntiCacheEvictionManager {
119121
std::vector<catalog::Table*> m_evicted_tables;
120122
std::vector<int32_t> m_evicted_block_ids;
121123
std::vector<int32_t> m_evicted_offsets;
124+
std::map <int32_t, set <int32_t> > m_evicted_filter;
122125
// whether the block to be merged is blockable, that is, all blocks that are needed
123126
// are in blockable tiers
124127
bool m_blockable_accesses;
@@ -132,7 +135,7 @@ class AntiCacheEvictionManager {
132135
// m_numdbs > 1;
133136
bool m_migrate;
134137
//std::map<int16_t, AntiCacheDB*> m_db_lookup_table;
135-
138+
136139
}; // AntiCacheEvictionManager class
137140

138141

src/ee/anticache/BerkeleyAntiCacheDB.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,10 @@ void BerkeleyAntiCacheDB::writeBlock(const std::string tableName,
183183
delete [] databuf_;
184184
}
185185

186+
bool BerkeleyAntiCacheDB::validateBlock(uint16_t blockId) {
187+
return true;
188+
}
189+
186190
AntiCacheBlock* BerkeleyAntiCacheDB::readBlock(uint16_t blockId, bool isMigrate) {
187191
Dbt key;
188192
key.set_data(&blockId);

src/ee/anticache/BerkeleyAntiCacheDB.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ class BerkeleyAntiCacheDB : public AntiCacheDB {
9999
const char* data,
100100
const long size,
101101
const int evictedTupleCount);
102+
103+
bool validateBlock(uint16_t blockID);
104+
102105
private:
103106
DbEnv* m_dbEnv;
104107
Db* m_db;

src/ee/anticache/EvictedTupleAccessException.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,13 @@ EvictedTupleAccessException::EvictedTupleAccessException(int tableId, int numBlo
5353
void EvictedTupleAccessException::p_serialize(ReferenceSerializeOutput *output) {
5454

5555
VOLT_TRACE("In EvictedTupleAccessException p_serialize().");
56+
// This is hack. But the string buffer in Java layer has limit.
57+
//if (m_numBlockIds > 10000)
58+
// m_numBlockIds = 10000;
5659

5760
output->writeInt(m_tableId);
58-
output->writeShort(static_cast<short>(m_numBlockIds)); // # of block ids
61+
output->writeInt(m_numBlockIds); // # of block ids
62+
//output->writeShort(static_cast<short>(m_numBlockIds)); // # of block ids
5963
for (int ii = 0; ii < m_numBlockIds; ii++) {
6064
output->writeInt(m_blockIds[ii]);
6165
}

src/ee/anticache/NVMAntiCacheDB.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,8 @@ void NVMAntiCacheDB::writeBlock(const std::string tableName,
216216
memcpy(block, buffer, bufsize);
217217
delete[] buffer;
218218

219-
VOLT_DEBUG("Writing NVM Block: ID = %u, index = %u, tupleCount = %d, size = %ld", blockId, index, tupleCount, bufsize);
219+
VOLT_DEBUG("Writing NVM Block: ID = %u, index = %u, tupleCount = %d, size = %ld, tableName = %s",
220+
blockId, index, tupleCount, bufsize, tableName.c_str());
220221

221222
tupleInBlock[blockId] = tupleCount;
222223
evictedTupleInBlock[blockId] = evictedTupleCount;
@@ -235,6 +236,13 @@ void NVMAntiCacheDB::writeBlock(const std::string tableName,
235236
pushBlockLRU(blockId);
236237
}
237238

239+
bool NVMAntiCacheDB::validateBlock(uint16_t blockId) {
240+
if (m_blockMap.find(blockId) == m_blockMap.end())
241+
return 0;
242+
else
243+
return 1;
244+
}
245+
238246
AntiCacheBlock* NVMAntiCacheDB::readBlock(uint16_t blockId, bool isMigrate) {
239247

240248
std::map<uint16_t, std::pair<uint16_t, int32_t> >::iterator itr;

src/ee/anticache/NVMAntiCacheDB.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ class NVMAntiCacheDB : public AntiCacheDB {
7575
const long size,
7676
const int evictedTupleCount);
7777

78+
bool validateBlock(uint16_t blockId);
79+
7880
private:
7981
/**
8082
* NVM constants

src/ee/execution/VoltDBEngine.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@
108108
#include "logging/Logrecord.h"
109109
#include "logging/AriesLogProxy.h"
110110
#include <string>
111+
#include <map>
112+
#include <set>
111113

112114
#define BUFFER_SIZE 1024*1024*300 // 100 MB buffer for reading in log file
113115

@@ -2032,13 +2034,15 @@ void VoltDBEngine::antiCacheAddDB(std::string dbDir, AntiCacheDBType dbType, boo
20322034
int VoltDBEngine::antiCacheReadBlocks(int32_t tableId, int numBlocks, int32_t blockIds[], int32_t tupleOffsets[]) {
20332035
int retval = ENGINE_ERRORCODE_SUCCESS;
20342036

2037+
20352038
// Grab the PersistentTable referenced by the given tableId
20362039
// This is simply the relativeIndex of the table in the catalog
20372040
// We can assume that the ordering hasn't changed.
20382041
PersistentTable *table = dynamic_cast<PersistentTable*>(this->getTable(tableId));
20392042
if (table == NULL) {
20402043
throwFatalException("Invalid table id %d", tableId);
20412044
}
2045+
VOLT_DEBUG("Read from table: %d %s", tableId, (table->name()).c_str());
20422046

20432047
#ifdef VOLT_INFO_ENABLED
20442048
std::ostringstream buffer;
@@ -2048,12 +2052,23 @@ int VoltDBEngine::antiCacheReadBlocks(int32_t tableId, int numBlocks, int32_t bl
20482052
}
20492053
VOLT_INFO("Preparing to read %d evicted blocks: [%s]", numBlocks, buffer.str().c_str());
20502054
#endif
2055+
VOLT_DEBUG("Preparing to read %d evicted blocks: [%s]", numBlocks, (table->name()).c_str());
20512056

20522057
// We can now ask it directly to read in the evicted blocks that they want
20532058
bool finalResult = true;
20542059
AntiCacheEvictionManager* eviction_manager = m_executorContext->getAntiCacheEvictionManager();
2060+
std::map <int32_t, set <int32_t> > filter;
20552061
try {
20562062
for (int i = 0; i < numBlocks; i++) {
2063+
VOLT_TRACE("inengine: %d", i);
2064+
if (filter.find(blockIds[i]) != filter.end())
2065+
if (filter[blockIds[i]].find(tupleOffsets[i]) != filter[blockIds[i]].end()) {
2066+
VOLT_WARN("skipping %d %d", blockIds[i], tupleOffsets[i]);
2067+
continue;
2068+
}
2069+
2070+
(filter[blockIds[i]]).insert(tupleOffsets[i]);
2071+
VOLT_DEBUG("reading %d %d", blockIds[i], tupleOffsets[i]);
20572072
finalResult = eviction_manager->readEvictedBlock(table, blockIds[i], tupleOffsets[i]) && finalResult;
20582073
} // FOR
20592074

@@ -2069,6 +2084,7 @@ int VoltDBEngine::antiCacheReadBlocks(int32_t tableId, int numBlocks, int32_t bl
20692084
retval = ENGINE_ERRORCODE_ERROR;
20702085
}
20712086

2087+
VOLT_DEBUG("Read from finished table: %d %s", tableId, (table->name()).c_str());
20722088
return (retval);
20732089
}
20742090

src/frontend/edu/brown/hstore/AntiCacheManager.java

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ protected void processingCallback(QueueEntry next) {
334334
LOG.debug(String.format("Asking EE to read in evicted blocks from table %s on partition %d: %s",
335335
next.catalog_tbl.getName(), next.partition, Arrays.toString(next.block_ids)));
336336

337+
//LOG.warn(Arrays.toString(next.block_ids) + "\n" + Arrays.toString(next.tuple_offsets));
337338
ee.antiCacheReadBlocks(next.catalog_tbl, next.block_ids, next.tuple_offsets);
338339

339340
if (debug.val)
@@ -411,15 +412,18 @@ public boolean queue(AbstractTransaction txn, int partition, Table catalog_tbl,
411412
txn.getBasePartition(), partition));
412413

413414
// HACK
414-
Set<Integer> allBlockIds = new HashSet<Integer>();
415-
for (int block : block_ids) {
416-
allBlockIds.add(block);
417-
}
418-
block_ids = new int[allBlockIds.size()];
419-
int i = 0;
420-
for (int block : allBlockIds) {
421-
block_ids[i++] = block;
422-
}
415+
if (hstore_conf.site.anticache_block_merge) {
416+
//LOG.warn("here!!");
417+
Set<Integer> allBlockIds = new HashSet<Integer>();
418+
for (int block : block_ids) {
419+
allBlockIds.add(block);
420+
}
421+
block_ids = new int[allBlockIds.size()];
422+
int i = 0;
423+
for (int block : allBlockIds) {
424+
block_ids[i++] = block;
425+
}
426+
}
423427

424428
if (txn instanceof LocalTransaction) {
425429
LocalTransaction ts = (LocalTransaction)txn;

0 commit comments

Comments
 (0)