-
哇!您并不是在追求该哈希函数的性能。
-
您正在复制每个键/值哈希上的所有块(例如,在查找、插入时)
-
你
较好的
永远不要希望使用共同例程,因为线程局部静态将使你的生活痛苦
请参阅下面的“我的奖金”部分
-
为什么要跳这种笨拙的舞蹈(简化代码):
auto iter = index.begin();
// first left element of bimap
BS first_left = iter->left;
Index::left_iterator left_iter = index.left.find(first_left);
有什么问题吗
auto left_iter = index.left.begin();
-
你认为迭代器序列化时的有效性是什么?(参见
Iterator invalidation rules
oa << left_iter;
我认为从存储中加载新的数据结构算作“重新分配”。迭代器或对另一个数据结构的引用在这里显然没有意义。
-
Erm。现在真的很困惑。
// first right element of bimap
auto pos = index.left.find(first_left);
Index::right_iterator right_iter = index.right.find(pos->second);
你称它为“右第一个元素”,但你做了一些别的事情:找到对应于
first_left
键(很可能是右侧的最后一个元素。还要注意,由于bimap的右侧是
multiset_of
,可能有多个匹配项,您可以随机使用第一个。
(旁注:
pos
是一个无用的复制
left_iter
的值)
-
见3。
oa << right_iter;
-
瓦里亚:
-
确保以二进制方式打开文件
std::ofstream ofs("binaryfile", std::ios::binary);
std::ifstream ifs("binaryfile", std::ios::binary);
-
为什么用值语义命名容器
index_reference
? 这太令人困惑了
-
SerializableType
未使用
-
BOOST_SERIALIZATION_NVP
对于二进制存档来说没有意义(其中的节点没有名称)
真正的问题
我想,真正的问题可能是“如何序列化
Bitset
s“。我很高兴地通知您,我在2015年编写了所需的bits:
How to serialize boost::dynamic_bitset?
拉动请求已被Boost接受
starting with version 1.64
.
因此,你可以坐下来,小口喝茶,包括:
#include <boost/dynamic_bitset/serialization.hpp>
全部完成
.
奖金部分
既然序列化实现了最小的副本序列化,为什么不使用它来增强哈希函数呢?序列化机制将为您提供所需的私有访问。
我滥用序列化管道
hash<>
之前的专业:
Hash an arbitrary precision value (boost::multiprecision::cpp_int)
把它们放在一起
Live On Coliru
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/bimap.hpp>
#include <boost/bimap/unordered_multiset_of.hpp>
#include <boost/bimap/unordered_set_of.hpp>
#include <boost/dynamic_bitset/serialization.hpp>
#include <fstream>
#include <iostream>
#include <string>
#include <boost/iostreams/device/back_inserter.hpp>
#include <boost/iostreams/stream_buffer.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/functional/hash.hpp>
namespace serial_hashing { // see https://stackoverflow.com/questions/30097385/hash-an-arbitrary-precision-value-boostmultiprecisioncpp-int
namespace io = boost::iostreams;
struct hash_sink {
hash_sink(size_t& seed_ref) : _ptr(&seed_ref) {}
typedef char char_type;
typedef io::sink_tag category;
std::streamsize write(const char* s, std::streamsize n) {
boost::hash_combine(*_ptr, boost::hash_range(s, s+n));
return n;
}
private:
size_t* _ptr;
};
template <typename T> struct hash_impl {
size_t operator()(T const& v) const {
using namespace boost;
size_t seed = 0;
{
iostreams::stream<hash_sink> os(seed);
archive::binary_oarchive oa(os, archive::no_header | archive::no_codecvt);
oa << v;
}
return seed;
}
};
}
namespace std {
template <typename Block, typename Alloc> struct hash<boost::dynamic_bitset<Block, Alloc> >
: serial_hashing::hash_impl<boost::dynamic_bitset<Block, Alloc> >
{};
} // namespace std
namespace bimaps = boost::bimaps;
using Bitset = boost::dynamic_bitset<>;
typedef boost::bimap<
bimaps::unordered_set_of<Bitset, std::hash<Bitset> >,
bimaps::unordered_multiset_of<Bitset, std::hash<Bitset> > > Index;
int main() {
using namespace std::string_literals;
{
std::cout << "# Writing binary file ... " << std::endl;
Index index;
index.insert({Bitset("10010"s), Bitset("1010110110101010101"s)});
std::ofstream ofs("binaryfile", std::ios::binary);
boost::archive::binary_oarchive oa(ofs);
oa << index;
}
{
std::cout << "# Loading binary file ... " << std::endl;
std::ifstream ifs("binaryfile", std::ios::binary); // name of loading file
boost::archive::binary_iarchive ia(ifs);
Index index;
ia >> index;
}
}
打印
# Writing binary file ...
# Loading binary file ...
没问题。
后脚本
真的,省省你自己的麻烦吧。因为你的用法清楚地表明你不想
无序
语义,只需按顺序排列即可:
Live On Coliru
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/bimap.hpp>
#include <boost/bimap/multiset_of.hpp>
#include <boost/dynamic_bitset/serialization.hpp>
#include <fstream>
#include <iostream>
namespace bimaps = boost::bimaps;
using Bitset = boost::dynamic_bitset<>;
typedef boost::bimap<bimaps::set_of<Bitset>, bimaps::multiset_of<Bitset>> Index;
int main() {
using namespace std::string_literals;
{
std::cout << "# Writing binary file ... " << std::endl;
Index index;
index.insert({Bitset("10010"s), Bitset("1010110110101010101"s)});
std::ofstream ofs("binaryfile", std::ios::binary);
boost::archive::binary_oarchive oa(ofs);
oa << index;
}
{
std::cout << "# Loading binary file ... " << std::endl;
std::ifstream ifs("binaryfile", std::ios::binary); // name of loading file
boost::archive::binary_iarchive ia(ifs);
Index index;
ia >> index;
}
}
减少到36行,剩下的代码不到一半。