#4 pzy

Merged
朴祉燕 merged 2 commits from pzy into main 1 month ago
  1. +10
    -52
      db/memtable.cc
  2. +101
    -0
      db/version_set.cc
  3. +3
    -2
      table/block.cc
  4. +71
    -1
      table/table.cc
  5. +2
    -1
      test/ttl_test.cc

+ 10
- 52
db/memtable.cc View File

@ -100,63 +100,21 @@ void MemTable::Add(SequenceNumber s, ValueType type, const Slice& key,
table_.Insert(buf); table_.Insert(buf);
} }
// bool MemTable::Get(const LookupKey& key, std::string* value, Status* s) { //燕改
// Slice memkey = key.memtable_key();
// Table::Iterator iter(&table_);
// iter.Seek(memkey.data());
// if (iter.Valid()) {// 获取跳表项的内容
// // entry format is:
// // klength varint32
// // userkey char[klength]
// // tag uint64
// // vlength varint32
// // value char[vlength]
// // Check that it belongs to same user key. We do not check the
// // sequence number since the Seek() call above should have skipped
// // all entries with overly large sequence numbers.
// const char* entry = iter.key();
// uint32_t key_length;
// const char* key_ptr = GetVarint32Ptr(entry, entry + 5, &key_length);
// if (comparator_.comparator.user_comparator()->Compare(// 比较键值
// Slice(key_ptr, key_length - 8), key.user_key()) == 0) {
// // Correct user key
// const uint64_t tag = DecodeFixed64(key_ptr + key_length - 8);
// switch (static_cast<ValueType>(tag & 0xff)) {
// case kTypeValue: {
// // Slice v = GetLengthPrefixedSlice(key_ptr + key_length);
// // value->assign(v.data(), v.size());
// // return true;
// // 获取过期时间戳,燕改
// Slice v = GetLengthPrefixedSlice(key_ptr + key_length);
// uint64_t expire_time = DecodeFixed64(v.data() + v.size() - sizeof(uint64_t));
// // 检查是否已过期
// uint64_t current_time = Env::Default()->NowMicros() / 1000000; // 当前时间(秒)
// if (expire_time > 0 && expire_time < current_time) {
// *s = Status::NotFound("Key has expired"); // 已过期
// return false;
// }
// // 未过期,返回值
// value->assign(v.data() + 8, v.size() - 8); // 去除前8字节的时间戳
// return true;
// }
// case kTypeDeletion:
// *s = Status::NotFound(Slice());
// return true;
// }
// }
// }
// return false;
// }
bool MemTable::Get(const LookupKey& key, std::string* value, Status* s) {
bool MemTable::Get(const LookupKey& key, std::string* value, Status* s) { //燕改
Slice memkey = key.memtable_key(); Slice memkey = key.memtable_key();
Table::Iterator iter(&table_); Table::Iterator iter(&table_);
iter.Seek(memkey.data()); iter.Seek(memkey.data());
if (iter.Valid()) { // 获取跳表项的内容 if (iter.Valid()) { // 获取跳表项的内容
// entry format is:
// klength varint32
// userkey char[klength]
// tag uint64
// vlength varint32
// value char[vlength]
// Check that it belongs to same user key. We do not check the
// sequence number since the Seek() call above should have skipped
// all entries with overly large sequence numbers.
const char* entry = iter.key(); const char* entry = iter.key();
uint32_t key_length; uint32_t key_length;
const char* key_ptr = GetVarint32Ptr(entry, entry + 5, &key_length); const char* key_ptr = GetVarint32Ptr(entry, entry + 5, &key_length);

+ 101
- 0
db/version_set.cc View File

@ -321,6 +321,107 @@ void Version::ForEachOverlapping(Slice user_key, Slice internal_key, void* arg,
} }
} }
// Status Version::Get(const ReadOptions& options, const LookupKey& k,
// std::string* value, GetStats* stats) {
// stats->seek_file = nullptr;
// stats->seek_file_level = -1;
// struct State {
// Saver saver;
// GetStats* stats;
// const ReadOptions* options;
// Slice ikey;
// FileMetaData* last_file_read;
// int last_file_read_level;
// VersionSet* vset;
// Status s;
// bool found;
// static bool Match(void* arg, int level, FileMetaData* f) {
// State* state = reinterpret_cast<State*>(arg);
// if (state->stats->seek_file == nullptr &&
// state->last_file_read != nullptr) { //如果 seek_file 为空且 last_file_read 不为空
// // We have had more than one seek for this read. Charge the 1st file.
// // 记录第一次的查找文件信息
// state->stats->seek_file = state->last_file_read; //则记录 seek_file 以标记第一次读取的文件和层级。
// state->stats->seek_file_level = state->last_file_read_level;
// }
// state->last_file_read = f; //更新 last_file_read 和 last_file_read_level
// state->last_file_read_level = level;
// //调用 table_cache_->Get:从缓存中获取指定文件,并在查找键时使用 SaveValue 回调,
// state->s = state->vset->table_cache_->Get(*state->options, f->number,
// f->file_size, state->ikey,
// &state->saver, SaveValue);
// // 使用TableCache::Get并传递自定义的SaveValue函数以进行TTL检查,燕改
// auto ttl_save_value = [](void* arg, const Slice& key, const Slice& value) {
// Saver* saver = reinterpret_cast<Saver*>(arg);
// if (value.size() < 19) {
// saver->state = kNotFound;
// return;
// }
// // 解析时间戳并检查过期情况
// uint64_t expire_time = DecodeFixed64(value.data() + value.size() - 19);
// if (expire_time > Env::Default()->NowMicros()) {
// SaveValue(arg, key, value); // 未过期,保存数据
// } else {
// saver->state = kNotFound; // 数据已过期
// }
// };
// // 调用Get并传递自定义的ttl_save_value,燕改
// state->s = state->vset->table_cache_->Get(*state->options, f->number,
// f->file_size, state->ikey,
// &state->saver, ttl_save_value);
// if (!state->s.ok()) {
// return false;
// }
// switch (state->saver.state) {
// case kNotFound:
// state->found = false; // 设置为未找到,燕改
// return true; // Keep searching in other files
// case kFound:
// state->found = true;
// return false;
// case kDeleted:
// return false;
// case kCorrupt:
// state->s =
// Status::Corruption("corrupted key for ", state->saver.user_key);
// state->found = true;
// return false;
// }
// // Not reached. Added to avoid false compilation warnings of
// // "control reaches end of non-void function".
// return false;
// }
// };
// State state;
// state.found = false;
// state.stats = stats;
// state.last_file_read = nullptr;
// state.last_file_read_level = -1;
// state.options = &options;
// state.ikey = k.internal_key();
// state.vset = vset_;
// state.saver.state = kNotFound;
// state.saver.ucmp = vset_->icmp_.user_comparator();
// state.saver.user_key = k.user_key();
// state.saver.value = value;
// ForEachOverlapping(state.saver.user_key, state.ikey, &state, &State::Match);
// return state.found ? state.s : Status::NotFound(Slice());
// }
Status Version::Get(const ReadOptions& options, const LookupKey& k, Status Version::Get(const ReadOptions& options, const LookupKey& k,
std::string* value, GetStats* stats) { std::string* value, GetStats* stats) {
stats->seek_file = nullptr; stats->seek_file = nullptr;

+ 3
- 2
table/block.cc View File

@ -180,7 +180,7 @@ class Block::Iter : public Iterator {
right = restart_index_; right = restart_index_;
} else { } else {
// We're seeking to the key we're already at. // We're seeking to the key we're already at.
return;
return;// 已找到,不需要进一步查找
} }
} }
@ -193,9 +193,10 @@ class Block::Iter : public Iterator {
&non_shared, &value_length); &non_shared, &value_length);
if (key_ptr == nullptr || (shared != 0)) { if (key_ptr == nullptr || (shared != 0)) {
CorruptionError(); CorruptionError();
return;
return; // 返回错误状态
} }
Slice mid_key(key_ptr, non_shared); Slice mid_key(key_ptr, non_shared);
if (Compare(mid_key, target) < 0) { if (Compare(mid_key, target) < 0) {
// Key at "mid" is smaller than "target". Therefore all // Key at "mid" is smaller than "target". Therefore all
// blocks before "mid" are uninteresting. // blocks before "mid" are uninteresting.

+ 71
- 1
table/table.cc View File

@ -4,6 +4,11 @@
#include "leveldb/table.h" #include "leveldb/table.h"
#include <sstream> // For std::istringstream
#include <iomanip> // For std::get_time
#include <ctime> // For std::tm and std::mktime
#include "leveldb/cache.h" #include "leveldb/cache.h"
#include "leveldb/comparator.h" #include "leveldb/comparator.h"
#include "leveldb/env.h" #include "leveldb/env.h"
@ -211,6 +216,35 @@ Iterator* Table::NewIterator(const ReadOptions& options) const {
&Table::BlockReader, const_cast<Table*>(this), options); &Table::BlockReader, const_cast<Table*>(this), options);
} }
// Status Table::InternalGet(const ReadOptions& options, const Slice& k, void* arg,
// void (*handle_result)(void*, const Slice&,
// const Slice&)) {
// Status s;
// Iterator* iiter = rep_->index_block->NewIterator(rep_->options.comparator);
// iiter->Seek(k);
// if (iiter->Valid()) {
// Slice handle_value = iiter->value();
// FilterBlockReader* filter = rep_->filter;
// BlockHandle handle;
// if (filter != nullptr && handle.DecodeFrom(&handle_value).ok() &&
// !filter->KeyMayMatch(handle.offset(), k)) {
// // Not found
// } else {
// Iterator* block_iter = BlockReader(this, options, iiter->value());
// block_iter->Seek(k);
// if (block_iter->Valid()) {
// (*handle_result)(arg, block_iter->key(), block_iter->value());
// }
// s = block_iter->status();
// delete block_iter;
// }
// }
// if (s.ok()) {
// s = iiter->status();
// }
// delete iiter;
// return s;
// }
Status Table::InternalGet(const ReadOptions& options, const Slice& k, void* arg, Status Table::InternalGet(const ReadOptions& options, const Slice& k, void* arg,
void (*handle_result)(void*, const Slice&, void (*handle_result)(void*, const Slice&,
const Slice&)) { const Slice&)) {
@ -228,19 +262,55 @@ Status Table::InternalGet(const ReadOptions& options, const Slice& k, void* arg,
Iterator* block_iter = BlockReader(this, options, iiter->value()); Iterator* block_iter = BlockReader(this, options, iiter->value());
block_iter->Seek(k); block_iter->Seek(k);
if (block_iter->Valid()) { if (block_iter->Valid()) {
(*handle_result)(arg, block_iter->key(), block_iter->value());
// 这里获取存储的组合字符串
s = Status::OK(); // 确保状态为 OK
Slice combined_value = block_iter->value();
// 获取实际的值和过期时间
std::string combined_str = combined_value.ToString();
// 假设过期时间是字符串的最后19个字符
std::string expiration_time_str = combined_str.substr(combined_str.size() - 19, 19); // 获取过期时间字符串
std::string actual_value = combined_str.substr(0, combined_str.size() - 19); // 获取实际值
// 解析过期时间为时间戳
std::tm tm = {};
std::istringstream ss(expiration_time_str);
ss >> std::get_time(&tm, "%Y-%m-%d %H:%M:%S");
std::time_t expiration_time = std::mktime(&tm);
// 获取当前时间并与过期时间进行比较
auto now = std::chrono::system_clock::now();
auto now_time_t = std::chrono::system_clock::to_time_t(now);
// 检查是否过期
if (expiration_time > now_time_t) {
// 调用结果处理函数,返回实际值
(*handle_result)(arg, block_iter->key(), Slice(actual_value));//, Slice(expiration_time_str));
s = block_iter->status();
if (! s.ok()) printf("291\n");
} else {
// 数据已过期,处理过期情况
s = Status::NotFound("Key has expired");
} }
}
else {
s = block_iter->status(); s = block_iter->status();
if (! s.ok()) printf("299\n");
}
delete block_iter; delete block_iter;
} }
} }
if (s.ok()) { if (s.ok()) {
s = iiter->status(); s = iiter->status();
if (! s.ok()) printf("306\n");
} }
delete iiter; delete iiter;
if (! s.ok()) printf("!!!!!!!!!!!"); // 如果不在sstable里
return s; return s;
} }
uint64_t Table::ApproximateOffsetOf(const Slice& key) const { uint64_t Table::ApproximateOffsetOf(const Slice& key) const {
Iterator* index_iter = Iterator* index_iter =
rep_->index_block->NewIterator(rep_->options.comparator); rep_->index_block->NewIterator(rep_->options.comparator);

+ 2
- 1
test/ttl_test.cc View File

@ -54,7 +54,7 @@ TEST(TestTTL, ReadTTL) {
abort(); abort();
} }
uint64_t ttl = 200;
uint64_t ttl = 50;
InsertData(db, ttl); InsertData(db, ttl);
@ -81,6 +81,7 @@ TEST(TestTTL, ReadTTL) {
status = db->Get(readOptions, key, &value); status = db->Get(readOptions, key, &value);
ASSERT_FALSE(status.ok()); ASSERT_FALSE(status.ok());
} }
delete db;
} }
TEST(TestTTL, CompactionTTL) { TEST(TestTTL, CompactionTTL) {

Loading…
Cancel
Save