Browse Source

put_fields

master
王雪飞 8 months ago
parent
commit
d93fe62697
3 changed files with 76 additions and 55 deletions
  1. +66
    -45
      db/db_impl.cc
  2. +1
    -1
      db/db_impl.h
  3. +9
    -9
      test/db_test3.cc

+ 66
- 45
db/db_impl.cc View File

@ -1202,7 +1202,7 @@ Status DBImpl::Get_Fields(const ReadOptions& options, const Slice& key,
slot_page_->get_slot(slot_num, &sc);
vlog_set_->get_value(sc.vlog_num, sc.value_offset, &vlog_value);
std::cout << "value from value_log: " << key.ToString() << vlog_value << std::endl;
// std::cout << "value from value_log: " << key.ToString() << std::endl;
*fields = DeserializeValue(vlog_value);
return Status::OK();
// Todo(end)
@ -1257,9 +1257,13 @@ Status DBImpl::Put_Fields(const WriteOptions& opt, const Slice& key,
const FieldArray& fields) {
// TODO(begin): allocate slot_num in slotpage and put value in vlog
// 将字段数组序列化
std::string serialized_value = SerializeValue(fields);
std::cout << "Put_Fields: " << key.ToString() << " " << serialized_value << std::endl;
size_t slot_num = slot_page_->alloc_slot();
std::string slot_num_str((char *)&slot_num, sizeof(size_t));
size_t slot_num_str_num;
std::memcpy(&slot_num_str_num, slot_num_str.c_str(), sizeof(size_t));
std::cout << "slot_num_str_num: " << slot_num_str_num << std::endl;
std::string serialized_value = SerializeValue(fields, slot_num_str);
std::cout << "Put_Fields: " << key.ToString() << " " << serialized_value << std::endl;
struct slot_content sc;
vlog_set_->put_value(&sc.vlog_num, &sc.value_offset, serialized_value);
slot_page_->set_slot(slot_num, &sc);
@ -1268,7 +1272,8 @@ Status DBImpl::Put_Fields(const WriteOptions& opt, const Slice& key,
memcpy(data, &slot_num, sizeof(size_t));
Slice slot_val(data, sizeof(data));
return DB::Put(opt, key, slot_val);
// return DB::Put(opt, key, slot_val);
return DB::Put(opt, key, serialized_value);
// TODO(end)
}
@ -1584,45 +1589,48 @@ void DBImpl::GetApproximateSizes(const Range* range, int n, uint64_t* sizes) {
FieldArray DBImpl::DeserializeValue(const std::string& value_str) {
// 存放解析后的字段数组
FieldArray fields;
// 将输入字符串转换为输入流 iss, 方便读取
// 将 value 字符串转换为输入流 iss
std::istringstream iss(value_str);
std::string content;
// 临时存放读取的数据
char buffer[100];
// 读取长度(定长,16比特)
iss.read(buffer, 16);
buffer[16] = '\0';
size_t total_length = std::stoi(buffer);
// std::cout << "读取到的总长度为: " << total_length << std::endl;
std::string value_content(value_str.begin() + 16, value_str.begin() + 16 + total_length);
// std::cout << value_content << std::endl;
char buffer_1[sizeof(uint16_t)];
// 读取 value 的长度
iss.read(buffer_1, sizeof(uint16_t));
size_t total_length;
std::memcpy(&total_length, buffer_1, sizeof(uint16_t));
std::cout << "total_length: " << total_length << std::endl;
char buffer_2[sizeof(size_t)];
// 读取 slot_num
iss.read(buffer_2, sizeof(size_t));
size_t slot_num_str;
std::memcpy(&slot_num_str, buffer_2, sizeof(size_t));
std::cout << "slot_num_str: " << slot_num_str << std::endl;
size_t sum_size = sizeof(size_t) + sizeof(uint16_t);
// 存放 value 的字符串
std::string value_content(value_str.begin() + sum_size, value_str.begin() + sum_size + total_length);
std::cout << value_content << std::endl;
std::istringstream iss_content(value_content);
iss_content.read(buffer, sizeof(size_t));
buffer[sizeof(size_t)] = '\0';
std::string slot_num = buffer;
// 读取属性个数
iss_content.read(buffer, 16);
// 在第17个比特位处添加终结符,确保字符串以终结符结尾
buffer[16] = '\0';
// 将 buffer 中的内容转化为整数并赋值给 field_count
int field_count = std::stoi(buffer);
// std::cout << "读取到的字段个数为: " << field_count << std::endl;
iss_content.read(buffer_1, sizeof(uint16_t));
size_t field_count;
std::memcpy(&field_count, buffer_1, sizeof(uint16_t));
std::cout << "field_count: " << field_count << std::endl;
for (int i = 0; i < field_count; ++i) {
Field field;
// 读取属性名长度(定长,16比特)
iss_content.read(buffer, 16);
buffer[16] = '\0';
int name_length = std::stoi(buffer);
// std::cout << "读取到的属性名长度为: " << name_length << std::endl;
// 读取属性名(变长)
// 读取属性名长度
iss_content.read(buffer_1, sizeof(uint16_t));
size_t name_length;
std::memcpy(&name_length, buffer_1, sizeof(uint16_t));
// std::cout << "name_length: " << name_length << std::endl;
// 读取属性名
field.name.resize(name_length);
iss_content.read(&field.name[0], name_length);
// std::cout << "读取到的属性名为: " << field.name << std::endl;
// 读取属性值长度(定长,16比特)
iss_content.read(buffer, 16);
buffer[16] = '\0';
int value_length = std::stoi(buffer);
iss_content.read(buffer_1, 16);
buffer_1[16] = '\0';
int value_length = std::stoi(buffer_1);
// std::cout << "读取到的属性值长度为: " << value_length << std::endl;
// 读取属性值(变长)
field.value.resize(value_length);
@ -1635,28 +1643,41 @@ FieldArray DBImpl::DeserializeValue(const std::string& value_str) {
// Todo(end)
// Todo(begin)
// 序列化函数,将字段数组序列化为字符串
std::string DBImpl::SerializeValue(const FieldArray& fields) {
// 创建并初始化一个字符串流 oss,用于逐步构建最终的序列化字符串
std::string DBImpl::SerializeValue(const FieldArray& fields, std::string slot_num_str) {
// 创建临时字符串流 oss_temp,用于存放 value 的内容
std::ostringstream oss_temp;
std::string slot_num = "slot_num";
oss_temp << std::setw(sizeof(size_t)) << std::setfill('0') << slot_num;
// 写入属性个数(定长,16比特),使用std::setw(16)设置宽度,使用std::setfull(0)设置填充字符,将字段数组的大小写入oss中
oss_temp << std::setw(16) << std::setfill('0') << fields.size();
// 写入属性个数
size_t fields_num = fields.size();
std::string field_num_str((char*)& fields_num, sizeof(uint16_t));
oss_temp << field_num_str;
for (const auto& field : fields) {
// 写入属性名长度(定长,16比特)
oss_temp << std::setw(16) << std::setfill('0') << field.name.size();
// 写入属性名(变长)
// 写入属性名长度
size_t name_length = field.name.size();
std::string name_length_str((char*)& name_length, sizeof(uint16_t));
oss_temp << name_length_str;
// 写入属性名
oss_temp << field.name;
// 写入属性值长度(定长,16比特)
oss_temp << std::setw(16) << std::setfill('0') << field.value.size();
// 写入属性值(变长)
// 写入属性值长度
size_t value_length = field.value.size();
std::string value_length_str((char*)& value_length, sizeof(uint16_t));
oss_temp << value_length_str;
// 写入属性值
oss_temp << field.value;
}
std::string temp_str = oss_temp.str();
size_t value_length = temp_str.size();
// std::cout << "value_length: " << value_length << std::endl;
std::string value_length_str((char*)& value_length, sizeof(uint16_t));
size_t value_length_str_var;
std::memcpy(&value_length_str_var, value_length_str.c_str(), sizeof(uint16_t));
// std::cout << "value_length_str_var: " << value_length_str_var << std::endl;
// 创建最终输出流 oss
std::ostringstream oss;
oss << std::setw(16) << std::setfill('0') << value_length;
// 写入 value 的长度
oss << value_length_str;
// 写入 slot_num
oss << slot_num_str;
// 写入 value
oss << temp_str;
return oss.str();
}

+ 1
- 1
db/db_impl.h View File

@ -91,7 +91,7 @@ class DBImpl : public DB {
// TODO(begin)
SlotPage *slot_page_;
VlogSet *vlog_set_;
static std::string SerializeValue(const FieldArray& fields);
static std::string SerializeValue(const FieldArray& fields, std::string slot_num_str);
static FieldArray DeserializeValue(const std::string& value_str);
// TODO(end)
// Information for a manual compaction

+ 9
- 9
test/db_test3.cc View File

@ -175,12 +175,12 @@ TEST(TestSchema, Basic) {
std::cerr << "open db failed" << std::endl;
abort();
}
std::string key = "key";
// std::string key = "key";
std::string key0 = "k_0";
std::string key1 = "k_1";
std::string key2 = "k_2";
std::string key3 = "k_3";
std::string value = "value";
// std::string value = "value";
FieldArray fields0 = {{"name", "wxf"}};
FieldArray fields1 = {
{"name", "Customer1"},
@ -198,15 +198,15 @@ TEST(TestSchema, Basic) {
{"address", "ecnu"},
{"phone", "11111"}
};
db->Put(writeOptions, key, value);
std::cout << "put_value: " << value << std::endl;
// db->Put(writeOptions, key, value);
// std::cout << "put_value: " << value << std::endl;
db->Put_Fields(leveldb::WriteOptions(), key0, fields0);
db->Put_Fields(leveldb::WriteOptions(), key1, fields1);
db->Put_Fields(leveldb::WriteOptions(), key2, fields2);
db->Put_Fields(leveldb::WriteOptions(), key3, fields3);
std::string value_ret;
db->Get(readOptions, key, &value_ret);
std::cout << "get_value: " << value_ret << std::endl;
// std::string value_ret;
// db->Get(readOptions, key, &value_ret);
// std::cout << "get_value: " << value_ret << std::endl;
// 读取并反序列化
FieldArray fields_ret_0;
FieldArray fields_ret_1;
@ -217,8 +217,8 @@ TEST(TestSchema, Basic) {
// 检查反序列化结果
ASSERT_EQ(fields_ret_0.size(), fields0.size());
for (size_t i = 0; i < fields_ret_0.size(); ++i) {
ASSERT_EQ(fields_ret_0[i].name, fields1[i].name);
ASSERT_EQ(fields_ret_0[i].value, fields1[i].value);
ASSERT_EQ(fields_ret_0[i].name, fields0[i].name);
ASSERT_EQ(fields_ret_0[i].value, fields0[i].value);
}
ASSERT_EQ(fields_ret_1.size(), fields1.size());

Loading…
Cancel
Save