|
|
@ -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(); |
|
|
|
} |
|
|
|