Skip to content

Commit f358021

Browse files
authored
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
1 parent 2d062fc commit f358021

File tree

2 files changed

+74
-11
lines changed

2 files changed

+74
-11
lines changed

parallel_hashmap/phmap_dump.h

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
#include <iostream>
2323
#include <fstream>
24-
#include <sstream>
24+
#include <functional>
2525
#include "phmap.h"
2626
namespace phmap
2727
{
@@ -168,22 +168,32 @@ bool parallel_hash_set<N, RefSet, Mtx_, Policy, Hash, Eq, Alloc>::phmap_load(Inp
168168
class BinaryOutputArchive {
169169
public:
170170
BinaryOutputArchive(const char *file_path) {
171-
ofs_.open(file_path, std::ofstream::out | std::ofstream::trunc | std::ofstream::binary);
171+
os_ = new std::ofstream(file_path, std::ofstream::out |
172+
std::ofstream::trunc |
173+
std::ofstream::binary);
174+
destruct_ = [this]() { delete os_; };
172175
}
173176

174-
~BinaryOutputArchive() = default;
177+
BinaryOutputArchive(std::ostream &os) : os_(&os) {}
178+
179+
~BinaryOutputArchive() {
180+
if (destruct_) {
181+
destruct_();
182+
}
183+
}
184+
175185
BinaryOutputArchive(const BinaryOutputArchive&) = delete;
176186
BinaryOutputArchive& operator=(const BinaryOutputArchive&) = delete;
177187

178188
bool saveBinary(const void *p, size_t sz) {
179-
ofs_.write(reinterpret_cast<const char*>(p), (std::streamsize)sz);
189+
os_->write(reinterpret_cast<const char*>(p), (std::streamsize)sz);
180190
return true;
181191
}
182192

183193
template<typename V>
184194
typename std::enable_if<type_traits_internal::IsTriviallyCopyable<V>::value, bool>::type
185195
saveBinary(const V& v) {
186-
ofs_.write(reinterpret_cast<const char *>(&v), sizeof(V));
196+
os_->write(reinterpret_cast<const char *>(&v), sizeof(V));
187197
return true;
188198
}
189199

@@ -194,29 +204,39 @@ class BinaryOutputArchive {
194204
}
195205

196206
private:
197-
std::ofstream ofs_;
207+
std::ostream* os_;
208+
std::function<void()> destruct_;
198209
};
199210

200211

201212
class BinaryInputArchive {
202213
public:
203214
BinaryInputArchive(const char * file_path) {
204-
ifs_.open(file_path, std::ofstream::in | std::ofstream::binary);
215+
is_ = new std::ifstream(file_path,
216+
std::ifstream::in | std::ifstream::binary);
217+
destruct_ = [this]() { delete is_; };
205218
}
219+
220+
BinaryInputArchive(std::istream& is) : is_(&is) {}
206221

207-
~BinaryInputArchive() = default;
222+
~BinaryInputArchive() {
223+
if (destruct_) {
224+
destruct_();
225+
}
226+
}
227+
208228
BinaryInputArchive(const BinaryInputArchive&) = delete;
209229
BinaryInputArchive& operator=(const BinaryInputArchive&) = delete;
210230

211231
bool loadBinary(void* p, size_t sz) {
212-
ifs_.read(reinterpret_cast<char*>(p), (std::streamsize)sz);
232+
is_->read(reinterpret_cast<char*>(p), (std::streamsize)sz);
213233
return true;
214234
}
215235

216236
template<typename V>
217237
typename std::enable_if<type_traits_internal::IsTriviallyCopyable<V>::value, bool>::type
218238
loadBinary(V* v) {
219-
ifs_.read(reinterpret_cast<char *>(v), sizeof(V));
239+
is_->read(reinterpret_cast<char *>(v), sizeof(V));
220240
return true;
221241
}
222242

@@ -227,7 +247,8 @@ class BinaryInputArchive {
227247
}
228248

229249
private:
230-
std::ifstream ifs_;
250+
std::istream* is_;
251+
std::function<void()> destruct_;
231252
};
232253

233254
} // namespace phmap

tests/dump_load_test.cc

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
#include <cstdint>
2+
#include <fstream>
3+
#include <parallel_hashmap/phmap.h>
4+
#include <sstream>
15
#include <vector>
26

37
#include "gtest/gtest.h"
@@ -22,6 +26,16 @@ TEST(DumpLoad, FlatHashSet_uint32) {
2226
EXPECT_TRUE(st2.phmap_load(ar_in));
2327
}
2428
EXPECT_TRUE(st1 == st2);
29+
30+
{
31+
std::stringstream ss;
32+
phmap::BinaryOutputArchive ar_out(ss);
33+
EXPECT_TRUE(st1.phmap_dump(ar_out));
34+
phmap::flat_hash_set<uint32_t> st3;
35+
phmap::BinaryInputArchive ar_in(ss);
36+
EXPECT_TRUE(st3.phmap_load(ar_in));
37+
EXPECT_TRUE(st1 == st3);
38+
}
2539
}
2640

2741
TEST(DumpLoad, FlatHashMap_uint64_uint32) {
@@ -39,6 +53,16 @@ TEST(DumpLoad, FlatHashMap_uint64_uint32) {
3953
EXPECT_TRUE(mp2.phmap_load(ar_in));
4054
}
4155

56+
{
57+
std::stringstream ss;
58+
phmap::BinaryOutputArchive ar_out(ss);
59+
EXPECT_TRUE(mp1.phmap_dump(ar_out));
60+
phmap::flat_hash_map<uint64_t, uint32_t> mp3;
61+
phmap::BinaryInputArchive ar_in(ss);
62+
EXPECT_TRUE(mp3.phmap_load(ar_in));
63+
EXPECT_TRUE(mp1 == mp3);
64+
}
65+
4266
EXPECT_TRUE(mp1 == mp2);
4367
}
4468

@@ -57,6 +81,24 @@ TEST(DumpLoad, ParallelFlatHashMap_uint64_uint32) {
5781
EXPECT_TRUE(mp2.phmap_load(ar_in));
5882
}
5983
EXPECT_TRUE(mp1 == mp2);
84+
85+
// test stringstream and dump/load in the middle of the stream
86+
{
87+
char hello[] = "Hello";
88+
std::stringstream ss;
89+
ss.write(hello, 5);
90+
phmap::BinaryOutputArchive ar_out(ss);
91+
EXPECT_TRUE(mp1.phmap_dump(ar_out));
92+
phmap::parallel_flat_hash_map<uint64_t, uint32_t> mp3;
93+
phmap::BinaryInputArchive ar_in(ss);
94+
char s[5];
95+
ss.read(s, 5);
96+
for (int i = 0; i < 5; ++i) {
97+
EXPECT_EQ(hello[i], s[i]);
98+
}
99+
EXPECT_TRUE(mp3.phmap_load(ar_in));
100+
EXPECT_TRUE(mp1 == mp3);
101+
}
60102
}
61103

62104
}

0 commit comments

Comments
 (0)