根据你的描述,我认为你有这个:
typedef std::map<long long, std::set<int>> MyMap;
其中map
非常大,而单个集合非常小。这里有几个开销来源:
- 中的各个条目
map
,每个条目都是单独的分配;
- s中的各个条目
set
,同上;
- 描述每个的结构
set
,独立于它们的内容。
使用标准库组件,不可能消除所有这些开销;关联容器的语义很好地要求每个条目的单独分配,并且使用红黑树需要为每个条目添加几个指针(理论上,只需要两个指针,但是如果没有迭代器的有效实现是困难的父指针。)
map
但是,您可以通过将 s与set
s 组合使用这样的数据结构来减少开销而不会丢失功能:
typedef std::set<std::pair<long long, int>> MyMap;
您仍然可以回答所有相同的查询,尽管其中一些不太方便。请记住,std::pair
默认比较器按字典顺序排序,因此具有相同first
值的所有元素都是连续的。因此,例如,您可以使用以下方法查询给定索引是否有任何int
关联的 s:
it = theMap.lower_bound(std::make_pair(index, INT_MIN));
if (it != theMap.end() && it->first == index) {
// there is at least one int associated with index
}
相同的调用lower_bound
将为您提供 int s associate with the key, while a call to
upper_bound(std::make_pair(key, INT_MAX))` 的开始迭代器,将为您提供相应的结束迭代器,因此您可以轻松地迭代与给定键关联的所有值。
这可能仍然不足以在 128GB 中存储 7 亿个带有相关整数集的索引,除非平均集大小非常小。下一步必须是某种形式的 b 树,它不在标准库中。B-树通过将多个条目组合到一个集群中来避免单个条目的开销;这应该足以满足您的需求。