|
|
@ -75,8 +75,8 @@ Version::~Version() { |
|
|
|
// An internal iterator. For a given version/level pair, yields
|
|
|
|
// An internal iterator. For a given version/level pair, yields
|
|
|
|
// information about the files in the level. For a given entry, key()
|
|
|
|
// information about the files in the level. For a given entry, key()
|
|
|
|
// is the largest key that occurs in the file, and value() is an
|
|
|
|
// is the largest key that occurs in the file, and value() is an
|
|
|
|
// 8-byte value containing the file number of the file, encoding using
|
|
|
|
// 16-byte value containing the file number and file size, both
|
|
|
|
// EncodeFixed64.
|
|
|
|
// encoded using EncodeFixed64.
|
|
|
|
class Version::LevelFileNumIterator : public Iterator { |
|
|
|
class Version::LevelFileNumIterator : public Iterator { |
|
|
|
public: |
|
|
|
public: |
|
|
|
LevelFileNumIterator(const Version* version, |
|
|
|
LevelFileNumIterator(const Version* version, |
|
|
@ -129,6 +129,7 @@ class Version::LevelFileNumIterator : public Iterator { |
|
|
|
Slice value() const { |
|
|
|
Slice value() const { |
|
|
|
assert(Valid()); |
|
|
|
assert(Valid()); |
|
|
|
EncodeFixed64(value_buf_, (*flist_)[index_]->number); |
|
|
|
EncodeFixed64(value_buf_, (*flist_)[index_]->number); |
|
|
|
|
|
|
|
EncodeFixed64(value_buf_+8, (*flist_)[index_]->file_size); |
|
|
|
return Slice(value_buf_, sizeof(value_buf_)); |
|
|
|
return Slice(value_buf_, sizeof(value_buf_)); |
|
|
|
} |
|
|
|
} |
|
|
|
virtual Status status() const { return Status::OK(); } |
|
|
|
virtual Status status() const { return Status::OK(); } |
|
|
@ -137,18 +138,21 @@ class Version::LevelFileNumIterator : public Iterator { |
|
|
|
const std::vector<FileMetaData*>* const flist_; |
|
|
|
const std::vector<FileMetaData*>* const flist_; |
|
|
|
int index_; |
|
|
|
int index_; |
|
|
|
|
|
|
|
|
|
|
|
mutable char value_buf_[8]; // Used for encoding the file number for value()
|
|
|
|
// Backing store for value(). Holds the file number and size.
|
|
|
|
|
|
|
|
mutable char value_buf_[16]; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
static Iterator* GetFileIterator(void* arg, |
|
|
|
static Iterator* GetFileIterator(void* arg, |
|
|
|
const ReadOptions& options, |
|
|
|
const ReadOptions& options, |
|
|
|
const Slice& file_value) { |
|
|
|
const Slice& file_value) { |
|
|
|
TableCache* cache = reinterpret_cast<TableCache*>(arg); |
|
|
|
TableCache* cache = reinterpret_cast<TableCache*>(arg); |
|
|
|
if (file_value.size() != 8) { |
|
|
|
if (file_value.size() != 16) { |
|
|
|
return NewErrorIterator( |
|
|
|
return NewErrorIterator( |
|
|
|
Status::Corruption("FileReader invoked with unexpected value")); |
|
|
|
Status::Corruption("FileReader invoked with unexpected value")); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
return cache->NewIterator(options, DecodeFixed64(file_value.data())); |
|
|
|
return cache->NewIterator(options, |
|
|
|
|
|
|
|
DecodeFixed64(file_value.data()), |
|
|
|
|
|
|
|
DecodeFixed64(file_value.data() + 8)); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -164,7 +168,8 @@ void Version::AddIterators(const ReadOptions& options, |
|
|
|
// Merge all level zero files together since they may overlap
|
|
|
|
// Merge all level zero files together since they may overlap
|
|
|
|
for (int i = 0; i < files_[0].size(); i++) { |
|
|
|
for (int i = 0; i < files_[0].size(); i++) { |
|
|
|
iters->push_back( |
|
|
|
iters->push_back( |
|
|
|
vset_->table_cache_->NewIterator(options, files_[0][i]->number)); |
|
|
|
vset_->table_cache_->NewIterator( |
|
|
|
|
|
|
|
options, files_[0][i]->number, files_[0][i]->file_size)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// For levels > 0, we can use a concatenating iterator that sequentially
|
|
|
|
// For levels > 0, we can use a concatenating iterator that sequentially
|
|
|
@ -650,7 +655,7 @@ uint64_t VersionSet::ApproximateOffsetOf(Version* v, const InternalKey& ikey) { |
|
|
|
// approximate offset of "ikey" within the table.
|
|
|
|
// approximate offset of "ikey" within the table.
|
|
|
|
Table* tableptr; |
|
|
|
Table* tableptr; |
|
|
|
Iterator* iter = table_cache_->NewIterator( |
|
|
|
Iterator* iter = table_cache_->NewIterator( |
|
|
|
ReadOptions(), files[i]->number, &tableptr); |
|
|
|
ReadOptions(), files[i]->number, files[i]->file_size, &tableptr); |
|
|
|
if (tableptr != NULL) { |
|
|
|
if (tableptr != NULL) { |
|
|
|
result += tableptr->ApproximateOffsetOf(ikey.Encode()); |
|
|
|
result += tableptr->ApproximateOffsetOf(ikey.Encode()); |
|
|
|
} |
|
|
|
} |
|
|
@ -855,7 +860,8 @@ Iterator* VersionSet::MakeInputIterator(Compaction* c) { |
|
|
|
if (c->level() + which == 0) { |
|
|
|
if (c->level() + which == 0) { |
|
|
|
const std::vector<FileMetaData*>& files = c->inputs_[which]; |
|
|
|
const std::vector<FileMetaData*>& files = c->inputs_[which]; |
|
|
|
for (int i = 0; i < files.size(); i++) { |
|
|
|
for (int i = 0; i < files.size(); i++) { |
|
|
|
list[num++] = table_cache_->NewIterator(options, files[i]->number); |
|
|
|
list[num++] = table_cache_->NewIterator( |
|
|
|
|
|
|
|
options, files[i]->number, files[i]->file_size); |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
// Create concatenating iterator for the files from this level
|
|
|
|
// Create concatenating iterator for the files from this level
|
|
|
|