mirror of
https://github.com/greg7mdp/parallel-hashmap.git
synced 2026-08-29 08:34:39 +08:00
Enhance the flexibility of the BinaryOutputArchive and BinaryInputArchive (#267)
* Refactor BinaryOutputArchive and BinaryInputArchive to use std::ostream and std::istream, allowing for more flexible output/input stream handling * update code based one the review comment * format code
This commit is contained in:
Vendored
+32
-11
@@ -21,7 +21,7 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <functional>
|
||||
#include "phmap.h"
|
||||
namespace phmap
|
||||
{
|
||||
@@ -168,22 +168,32 @@ bool parallel_hash_set<N, RefSet, Mtx_, Policy, Hash, Eq, Alloc>::phmap_load(Inp
|
||||
class BinaryOutputArchive {
|
||||
public:
|
||||
BinaryOutputArchive(const char *file_path) {
|
||||
ofs_.open(file_path, std::ofstream::out | std::ofstream::trunc | std::ofstream::binary);
|
||||
os_ = new std::ofstream(file_path, std::ofstream::out |
|
||||
std::ofstream::trunc |
|
||||
std::ofstream::binary);
|
||||
destruct_ = [this]() { delete os_; };
|
||||
}
|
||||
|
||||
BinaryOutputArchive(std::ostream &os) : os_(&os) {}
|
||||
|
||||
~BinaryOutputArchive() {
|
||||
if (destruct_) {
|
||||
destruct_();
|
||||
}
|
||||
}
|
||||
|
||||
~BinaryOutputArchive() = default;
|
||||
BinaryOutputArchive(const BinaryOutputArchive&) = delete;
|
||||
BinaryOutputArchive& operator=(const BinaryOutputArchive&) = delete;
|
||||
|
||||
bool saveBinary(const void *p, size_t sz) {
|
||||
ofs_.write(reinterpret_cast<const char*>(p), (std::streamsize)sz);
|
||||
os_->write(reinterpret_cast<const char*>(p), (std::streamsize)sz);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename V>
|
||||
typename std::enable_if<type_traits_internal::IsTriviallyCopyable<V>::value, bool>::type
|
||||
saveBinary(const V& v) {
|
||||
ofs_.write(reinterpret_cast<const char *>(&v), sizeof(V));
|
||||
os_->write(reinterpret_cast<const char *>(&v), sizeof(V));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -194,29 +204,39 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
std::ofstream ofs_;
|
||||
std::ostream* os_;
|
||||
std::function<void()> destruct_;
|
||||
};
|
||||
|
||||
|
||||
class BinaryInputArchive {
|
||||
public:
|
||||
BinaryInputArchive(const char * file_path) {
|
||||
ifs_.open(file_path, std::ofstream::in | std::ofstream::binary);
|
||||
is_ = new std::ifstream(file_path,
|
||||
std::ifstream::in | std::ifstream::binary);
|
||||
destruct_ = [this]() { delete is_; };
|
||||
}
|
||||
|
||||
BinaryInputArchive(std::istream& is) : is_(&is) {}
|
||||
|
||||
~BinaryInputArchive() {
|
||||
if (destruct_) {
|
||||
destruct_();
|
||||
}
|
||||
}
|
||||
|
||||
~BinaryInputArchive() = default;
|
||||
BinaryInputArchive(const BinaryInputArchive&) = delete;
|
||||
BinaryInputArchive& operator=(const BinaryInputArchive&) = delete;
|
||||
|
||||
bool loadBinary(void* p, size_t sz) {
|
||||
ifs_.read(reinterpret_cast<char*>(p), (std::streamsize)sz);
|
||||
is_->read(reinterpret_cast<char*>(p), (std::streamsize)sz);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename V>
|
||||
typename std::enable_if<type_traits_internal::IsTriviallyCopyable<V>::value, bool>::type
|
||||
loadBinary(V* v) {
|
||||
ifs_.read(reinterpret_cast<char *>(v), sizeof(V));
|
||||
is_->read(reinterpret_cast<char *>(v), sizeof(V));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -227,7 +247,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
std::ifstream ifs_;
|
||||
std::istream* is_;
|
||||
std::function<void()> destruct_;
|
||||
};
|
||||
|
||||
} // namespace phmap
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
#include <cstdint>
|
||||
#include <fstream>
|
||||
#include <parallel_hashmap/phmap.h>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
@@ -22,6 +26,16 @@ TEST(DumpLoad, FlatHashSet_uint32) {
|
||||
EXPECT_TRUE(st2.phmap_load(ar_in));
|
||||
}
|
||||
EXPECT_TRUE(st1 == st2);
|
||||
|
||||
{
|
||||
std::stringstream ss;
|
||||
phmap::BinaryOutputArchive ar_out(ss);
|
||||
EXPECT_TRUE(st1.phmap_dump(ar_out));
|
||||
phmap::flat_hash_set<uint32_t> st3;
|
||||
phmap::BinaryInputArchive ar_in(ss);
|
||||
EXPECT_TRUE(st3.phmap_load(ar_in));
|
||||
EXPECT_TRUE(st1 == st3);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(DumpLoad, FlatHashMap_uint64_uint32) {
|
||||
@@ -39,6 +53,16 @@ TEST(DumpLoad, FlatHashMap_uint64_uint32) {
|
||||
EXPECT_TRUE(mp2.phmap_load(ar_in));
|
||||
}
|
||||
|
||||
{
|
||||
std::stringstream ss;
|
||||
phmap::BinaryOutputArchive ar_out(ss);
|
||||
EXPECT_TRUE(mp1.phmap_dump(ar_out));
|
||||
phmap::flat_hash_map<uint64_t, uint32_t> mp3;
|
||||
phmap::BinaryInputArchive ar_in(ss);
|
||||
EXPECT_TRUE(mp3.phmap_load(ar_in));
|
||||
EXPECT_TRUE(mp1 == mp3);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(mp1 == mp2);
|
||||
}
|
||||
|
||||
@@ -57,6 +81,24 @@ TEST(DumpLoad, ParallelFlatHashMap_uint64_uint32) {
|
||||
EXPECT_TRUE(mp2.phmap_load(ar_in));
|
||||
}
|
||||
EXPECT_TRUE(mp1 == mp2);
|
||||
|
||||
// test stringstream and dump/load in the middle of the stream
|
||||
{
|
||||
char hello[] = "Hello";
|
||||
std::stringstream ss;
|
||||
ss.write(hello, 5);
|
||||
phmap::BinaryOutputArchive ar_out(ss);
|
||||
EXPECT_TRUE(mp1.phmap_dump(ar_out));
|
||||
phmap::parallel_flat_hash_map<uint64_t, uint32_t> mp3;
|
||||
phmap::BinaryInputArchive ar_in(ss);
|
||||
char s[5];
|
||||
ss.read(s, 5);
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
EXPECT_EQ(hello[i], s[i]);
|
||||
}
|
||||
EXPECT_TRUE(mp3.phmap_load(ar_in));
|
||||
EXPECT_TRUE(mp1 == mp3);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user