如何在c++中实现分布式映射的API
How to implement an API for a distributed map in c++?
我正在用c++实现一个分布式映射,并寻找一个好的API设计。第一个简单的选择是使它与std::map完全一样。迭代器出现问题。
IMap<std::string,Person>::iterator it;
it = map.find("sample");
if(it == map.end() ){
//NULL
}
for(it = map.begin(); it != map.end(); it++){
//iterate
}
在分布式环境中(至少在我正在实现的环境中),没有映射的开始和结束。无论如何,它都不是有序的,所以返回迭代器看起来不像是一个选项。
第二种选择是通过复制返回值类,如下所示:
Person emptyPerson;
Person person = map.get("sample");
if(person == emptyPerson){
//NULL
}
问题是NULL检查看起来很奇怪。您可以先询问它是否可用,然后获取对象,但要求这些操作必须是原子操作。
第三个选项是返回指针:
Person* person = map.get("sample");
if(person == NULL){
//NULL
}
我不想这样做,因为它很容易出错。用户需要删除我在内部创建的指针。
我正在考虑返回一个包装用户对象的类,比如:
value_reference<std::map, Person> person = map.get("sample");
if(value_reference.hasValue() ){
Person p = value_reference;
}
那么你认为最好的方法是什么呢?
你知道有什么好的api类似于需求我的分布式地图吗?
基于您的术语"分布式地图",我做出以下假设:
- 数据的一个子集在本地可用,对于不是数据集的数据,需要执行一些远程获取
- 对返回对象的写入不应自动保留在数据存储中。应改为发出明确的更新请求
如果这是真的,那么迭代器不是您想要的,也不需要STL容器模型。C++迭代程序的概念要求您实现预增量(++i
)运算符,如果您的数据是无序的并且分布在多个节点上,那么"给我下一个条目"的请求就没有意义了。
如果出于互操作性的原因想要模拟STL容器和迭代器,您可能会创建一个糟糕的拼凑:让映射的end()
方法返回一个sentinel迭代器实例,让迭代器的operator++()
返回相同的sentinel。实际上,每个迭代器都会指向"映射中的最后一个元素"。我强烈建议不要采取这种方法,除非有必要,而且我认为不会。
听起来您想要的是一个简单的CRUD模型,其中必须明确请求更新。在这种情况下,您的API看起来像:
template <typename TKey, typename TValue>
class IMap<TKey, TValue>
{
public:
void create(TKey const & key, TValue const & value) = 0;
std::unique_ptr<TValue> retrieve(TKey const & key) = 0;
bool update(TKey const & key, TValue const & value) = 0;
bool remove(TKey const & key) = 0;
};
在检索的情况下,您只需按照建议返回一个空指针。std::unique_ptr<>
将确保调用者将删除分配的对象或显式地获得它的所有权
对于"返回指针到新分配的对象"的情况,另一种选择是让调用方传入引用,如果在映射中找到该值,则该方法将返回true。例如,这将允许调用者直接将对象检索到数组槽或其他本地结构中,而不需要中间堆分配。
bool retrieve(TKey const & key, TValue & value) = 0;
使用这种方法看起来像:
Person person;
if (map.retrieve("sample", person)) {
std::cout << "Found person: " << person << std::endl;
} else {
std::cout << "Did not find person." << std::endl;
}
您也可以同时提供这两种重载,默认情况下,返回指针的重载可以用另一种实现:
template <typename TKey, typename TValue>
std::unique_ptr<TValue> IMap<TKey, TValue>::retrieve(TKey const & key)
{
TValue v;
return std::unique_ptr<TValue>(retrieve(key, v) ? new TValue(v) : nullptr);
}
我认为选项3是最好的。你可以使用C++11中引入的一种标准智能指针类型来模拟它,这样你仍然可以创建一个指针,但用户不必释放它
std::unqiue_ptr<Person> person = map.get("sample");
if(person) {
person->makeMeASandwitch();
}
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 将函数类成员映射到类本身内部
- 如何在 C# 中映射双 C 结构指针?
- 如何在C++中使用结构生成映射
- 使用std::函数映射对象方法
- 如何加载(或映射)文件部分的最大大小,但适合在Windows上的RAM
- C++映射分割错误(核心转储)
- 内联映射初始化的动态atexit析构函数崩溃
- 使用"std::unordereded_map"映射到"std::list"对象
- 如何从多映射中删除特定的重复项
- 在未初始化映射的情况下,将值插入到映射的映射中
- QT通过C++添加映射QML项目
- 在c++中访问int到类对象的映射时出错
- 在C++中搜索嵌套多映射值
- 错误处理.将系统错误代码映射到泛型
- C++匿名结构作为std::映射值
- 如何从存储在std::映射中的std::集中删除元素
- 递归无序映射
- 如何在c++中实现分布式映射的API