|
|
@ -0,0 +1,165 @@ |
|
|
|
#include "fields.h"
|
|
|
|
#include "util/coding.h"
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
#include <utility>
|
|
|
|
|
|
|
|
|
|
|
|
namespace leveldb { |
|
|
|
|
|
|
|
/* 构造函数 */ |
|
|
|
Fields::Fields(FieldArray fields) |
|
|
|
: fields_(std::move(fields)) { |
|
|
|
SortFields(); |
|
|
|
} |
|
|
|
|
|
|
|
Fields::Fields(const Field& field) |
|
|
|
: fields_({field}) {} |
|
|
|
|
|
|
|
Fields::Fields(const std::vector<std::string>& field_names) { |
|
|
|
for (const auto& name : field_names) { |
|
|
|
fields_.emplace_back(name, ""); |
|
|
|
} |
|
|
|
SortFields(); |
|
|
|
} |
|
|
|
|
|
|
|
/* 根据 field_name 从小到大进行排序,减少通过 field_name 遍历 Fields 的耗时 */ |
|
|
|
void Fields::SortFields() { |
|
|
|
std::sort(fields_.begin(), fields_.end(), [](const Field& a, const Field& b) { |
|
|
|
return a.first < b.first; |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
/* 更新/插入单个字段值 */ |
|
|
|
void Fields::UpdateField(const std::string& field_name, const std::string& field_value) { |
|
|
|
for (auto iter = fields_.begin(); iter != fields_.end(); iter++) { |
|
|
|
if ((*iter).first > field_name) { |
|
|
|
fields_.insert(iter, {field_name, field_value}); |
|
|
|
return; |
|
|
|
} |
|
|
|
if ((*iter).first == field_name) { |
|
|
|
(*iter).second = field_value; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
fields_.emplace_back(field_name, field_value); |
|
|
|
} |
|
|
|
|
|
|
|
void Fields::UpdateField(const Field& field) { |
|
|
|
UpdateField(field.first, field.second); |
|
|
|
} |
|
|
|
|
|
|
|
/* 更新/插入多个字段值 */ |
|
|
|
void Fields::UpdateFields(const std::vector<std::string>& field_names, const std::vector<std::string>& field_values) { |
|
|
|
if (field_names.size() != field_values.size()) { |
|
|
|
std::cerr << "UpdateFields Failed: field_name and field_values must have the same size." << std::endl; |
|
|
|
return; |
|
|
|
} |
|
|
|
for (size_t i = 0; i < field_names.size(); ++i) { |
|
|
|
UpdateField(field_names[i], field_values[i]); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void Fields::UpdateFields(const FieldArray& fields) { |
|
|
|
for (const auto& field : fields) { |
|
|
|
UpdateField(field); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* 删除单个字段 */ |
|
|
|
void Fields::DeleteField(const std::string& field_name) { |
|
|
|
for (auto iter = fields_.begin(); iter != fields_.end(); iter++) { |
|
|
|
if ((*iter).first > field_name) return; |
|
|
|
if ((*iter).first == field_name) { |
|
|
|
fields_.erase(iter); |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* 删除多个字段 */ |
|
|
|
void Fields::DeleteFields(const std::vector<std::string>& field_names) { |
|
|
|
for (auto &name : field_names) { |
|
|
|
if (fields_.empty()) return; |
|
|
|
DeleteField(name); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* 序列化 Field 或 FieldArray 为 value 字符串 */ |
|
|
|
std::string Fields::SerializeValue(const FieldArray& fields) { |
|
|
|
std::string value_str; |
|
|
|
for (const auto& field : fields) { |
|
|
|
std::string field_str = SerializeValue(field); |
|
|
|
value_str += field_str; |
|
|
|
} |
|
|
|
return value_str; |
|
|
|
} |
|
|
|
|
|
|
|
std::string Fields::SerializeValue(const Field& field) { |
|
|
|
std::string value_str; |
|
|
|
PutLengthPrefixedSlice(&value_str, Slice(field.first)); |
|
|
|
PutLengthPrefixedSlice(&value_str, Slice(field.second)); |
|
|
|
return value_str; |
|
|
|
} |
|
|
|
|
|
|
|
std::string Fields::SerializeValue() const { |
|
|
|
return SerializeValue(fields_); |
|
|
|
} |
|
|
|
|
|
|
|
/* 反序列化 value 字符串为 Fields */ |
|
|
|
Fields Fields::ParseValue(const std::string& value_str) { |
|
|
|
Fields fields; |
|
|
|
Slice value_slice(value_str); |
|
|
|
while (!value_slice.empty()) { |
|
|
|
Slice field_name; |
|
|
|
Slice field_value; |
|
|
|
if (!GetLengthPrefixedSlice(&value_slice, &field_name)) break; |
|
|
|
if (!GetLengthPrefixedSlice(&value_slice, &field_value)) break; |
|
|
|
fields.UpdateField(field_name.ToString(), field_value.ToString()); |
|
|
|
} |
|
|
|
return fields; |
|
|
|
} |
|
|
|
|
|
|
|
/* 获取字段 */ |
|
|
|
Field Fields::GetField(const std::string& field_name) const { |
|
|
|
for (auto iter = fields_.begin(); iter != fields_.end(); iter++) { |
|
|
|
if ((*iter).first == field_name) return *iter; |
|
|
|
if ((*iter).first > field_name || iter == fields_.end() - 1) { |
|
|
|
std::cerr << "GetField Failed: field name [" + field_name + "] doesn't exist, return {}." << std::endl; |
|
|
|
return {}; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* 检查字段是否存在 */ |
|
|
|
bool Fields::HasField(const std::string& field_name) const { |
|
|
|
for (auto iter = fields_.begin(); iter != fields_.end(); iter++) { |
|
|
|
if ((*iter).first == field_name) return true; |
|
|
|
if ((*iter).first > field_name || iter == fields_.end() - 1) return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* 重载运算符 [] 用于访问字段值 */ |
|
|
|
std::string Fields::operator[](const std::string& field_name) const { |
|
|
|
for (auto iter = fields_.begin(); iter != fields_.end(); iter++) { |
|
|
|
if ((*iter).first == field_name) return (*iter).second; |
|
|
|
if ((*iter).first > field_name || iter == fields_.end() - 1) { |
|
|
|
static const std::string empty_str; |
|
|
|
std::cerr << "GetField Failed: field name [" + field_name + "] doesn't exist." << std::endl; |
|
|
|
return empty_str; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
std::string& Fields::operator[](const std::string& field_name) { |
|
|
|
for (auto iter = fields_.begin(); iter != fields_.end(); iter++) { |
|
|
|
if ((*iter).first == field_name) return (*iter).second; |
|
|
|
if ((*iter).first > field_name) { |
|
|
|
return fields_.insert(iter, {field_name, ""})->second; |
|
|
|
} |
|
|
|
} |
|
|
|
fields_.emplace_back(field_name, ""); |
|
|
|
return fields_.back().second; |
|
|
|
} |
|
|
|
|
|
|
|
} // namespace leveldb
|