Skip to content

Commit d1c2cf7

Browse files
authored
Consistent G3Frame versioning and serialization (#181)
This PR uses the same versioning and archive serialization methods for G3Frame instances as those for all other serializable objects in the library. The G3Frame class version is defined in the header, along with specialized load/save methods for IO with cereal binary archives. The load/save methods for streams are renamed to loads/saves to ensure that the cereal library binds the correct serialization methods. This PR does not change the serialized blob structure or increment the serialization version, so full compatibility with existing data is maintained.
1 parent 453f870 commit d1c2cf7

File tree

6 files changed

+47
-54
lines changed

6 files changed

+47
-54
lines changed

core/include/core/G3Frame.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,12 @@ class G3Frame {
9696
G3Frame &operator = (const G3Frame &);
9797

9898
// Serialize (or deserialize) from an IO stream.
99-
template <typename T> void save(T &os) const;
100-
template <typename T> void load(T &is);
99+
template <typename T> void saves(T &os) const;
100+
template <typename T> void loads(T &is);
101+
102+
// Serialize (or deserialize) from a cereal archive.
103+
template <class A> void save(A &ar, unsigned) const;
104+
template <class A> void load(A &ar, unsigned);
101105

102106
// Routines for handling the stored serialized copies of data.
103107
// These are all const because they only manipulate caches and
@@ -134,6 +138,8 @@ class G3Frame {
134138
};
135139

136140
G3_POINTERS(G3Frame);
141+
CEREAL_CLASS_VERSION(G3Frame, 1);
142+
CEREAL_SPECIALIZE_FOR_ALL_ARCHIVES(G3Frame, cereal::specialization::member_load_save);
137143

138144
template <typename T>
139145
std::shared_ptr<const T> G3Frame::Get(const std::string &name,

core/src/G3Frame.cxx

Lines changed: 34 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -234,14 +234,20 @@ std::ostream& operator<<(std::ostream& os, const G3Frame::FrameType &frame_type)
234234
}
235235

236236
template <typename T>
237-
void G3Frame::save(T &os) const
237+
void G3Frame::saves(T &os) const
238238
{
239239
using cereal::make_nvp;
240-
uint32_t crc = 0;
241-
uint32_t version(1), size(map_.size());
242240

243241
cereal::PortableBinaryOutputArchive ar(os);
244-
ar << make_nvp("version", version);
242+
ar << make_nvp("frame", *this);
243+
}
244+
245+
template <class A>
246+
void G3Frame::save(A &ar, unsigned v) const
247+
{
248+
using cereal::make_nvp;
249+
uint32_t crc(0), size(map_.size());
250+
245251
ar << make_nvp("size", size);
246252
ar << make_nvp("type", (uint32_t)type);
247253
for (auto i = map_.begin(); i != map_.end(); i++) {
@@ -259,16 +265,24 @@ void G3Frame::save(T &os) const
259265
}
260266

261267
template <typename T>
262-
void G3Frame::load(T &is)
268+
void G3Frame::loads(T &is)
263269
{
264270
using cereal::make_nvp;
265271

266272
cereal::PortableBinaryInputArchive ar(is);
267-
int version, size;
268-
uint32_t xtype;
269-
uint32_t crc(0), testcrc;
273+
ar >> make_nvp("frame", *this);
274+
}
275+
276+
template <class A>
277+
void G3Frame::load(A &ar, unsigned v)
278+
{
279+
using cereal::make_nvp;
280+
G3_CHECK_VERSION(v);
281+
282+
int size;
283+
uint32_t xtype, testcrc;
284+
uint32_t crc(0);
270285

271-
ar >> make_nvp("version", version);
272286
ar >> make_nvp("size", size);
273287
ar >> make_nvp("type", xtype);
274288
type = FrameType(xtype);
@@ -368,13 +382,17 @@ void G3Frame::blob_encode(struct blob_container &blob)
368382
item_os.flush();
369383
}
370384

371-
template void G3Frame::load(g3_istream &);
372-
template void G3Frame::load(std::istream &);
373-
template void G3Frame::load(std::istringstream &);
385+
template void G3Frame::loads(g3_istream &);
386+
template void G3Frame::loads(G3BufferInputStream &);
387+
template void G3Frame::loads(std::istream &);
388+
template void G3Frame::loads(std::istringstream &);
374389

375-
template void G3Frame::save(g3_ostream &) const;
376-
template void G3Frame::save(std::ostream &) const;
377-
template void G3Frame::save(std::ostringstream &) const;
390+
template void G3Frame::saves(g3_ostream &) const;
391+
template void G3Frame::saves(G3BufferOutputStream &) const;
392+
template void G3Frame::saves(std::ostream &) const;
393+
template void G3Frame::saves(std::ostringstream &) const;
394+
395+
G3_SPLIT_SERIALIZABLE_CODE(G3Frame);
378396

379397
G3FramePtr
380398
g3frame_char_constructor(std::string max_4_chars)
@@ -395,37 +413,6 @@ g3frame_char_constructor(std::string max_4_chars)
395413
return G3FramePtr(new G3Frame(G3Frame::FrameType(code)));
396414
}
397415

398-
// Use G3Frame::save()/G3Frame::load() to provide a pickle interface for frames
399-
struct g3frame_picklesuite : boost::python::pickle_suite
400-
{
401-
static boost::python::tuple getstate(boost::python::object obj)
402-
{
403-
namespace bp = boost::python;
404-
std::vector<char> buffer;
405-
G3BufferOutputStream os(buffer);
406-
(bp::extract<const G3Frame &>(obj))().save(os);
407-
os.flush();
408-
409-
return boost::python::make_tuple(obj.attr("__dict__"),
410-
bp::object(bp::handle<>(
411-
PyBytes_FromStringAndSize(&buffer[0], buffer.size()))));
412-
}
413-
414-
static void setstate(boost::python::object obj,
415-
boost::python::tuple state)
416-
{
417-
namespace bp = boost::python;
418-
Py_buffer view;
419-
PyObject_GetBuffer(bp::object(state[1]).ptr(), &view,
420-
PyBUF_SIMPLE);
421-
422-
bp::extract<bp::dict>(obj.attr("__dict__"))().update(state[0]);
423-
G3BufferInputStream is((char *)view.buf, view.len);
424-
(bp::extract<G3Frame &>(obj))().load(is);
425-
PyBuffer_Release(&view);
426-
}
427-
};
428-
429416
static boost::python::list g3frame_keys(const G3Frame &map)
430417
{
431418
boost::python::list keys;
@@ -599,7 +586,7 @@ PYBINDINGS("core") {
599586
"where those serialized copies already exist. Saves memory for "
600587
"frames about to be written at the expense of CPU time to "
601588
"re-decode them if they are accessed again later.")
602-
.def_pickle(g3frame_picklesuite())
589+
.def_pickle(g3frameobject_picklesuite<G3Frame>())
603590
;
604591
register_vector_of<G3FramePtr>("Frame");
605592
register_vector_of<G3FrameObjectPtr>("FrameObject");

core/src/G3MultiFileWriter.cxx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ G3MultiFileWriter::CheckNewFile(G3FramePtr frame)
120120
g3_ostream_to_path(stream_, filename, false, true);
121121

122122
for (auto i = metadata_cache_.begin(); i != metadata_cache_.end(); i++)
123-
(*i)->save(stream_);
123+
(*i)->saves(stream_);
124124

125125
return true;
126126
}
@@ -161,7 +161,7 @@ void G3MultiFileWriter::Process(G3FramePtr frame, std::deque<G3FramePtr> &out)
161161
// And out to disk, making sure not to write again if it just went into
162162
// the metadata cache and onto disk in CheckNewFile()
163163
if (!new_file || !meta_cached)
164-
frame->save(stream_);
164+
frame->saves(stream_);
165165

166166
done:
167167
out.push_back(frame);

core/src/G3NetworkSender.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ void G3NetworkSender::SerializeFrame(serialization_task& task)
174174
try{
175175
netbuf_type buf(new std::vector<char>);
176176
G3BufferOutputStream os(*buf);
177-
task.input->save(os);
177+
task.input->saves(os);
178178
os.flush();
179179
task.output.set_value(buf);
180180
}

core/src/G3Reader.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ void G3Reader::Process(G3FramePtr frame, std::deque<G3FramePtr> &out)
8484
}
8585
frame = G3FramePtr(new G3Frame);
8686
try {
87-
frame->load(stream_);
87+
frame->loads(stream_);
8888
} catch (...) {
8989
log_error("Exception raised while reading file %s",
9090
cur_file_.c_str());

core/src/G3Writer.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ void G3Writer::Process(G3FramePtr frame, std::deque<G3FramePtr> &out)
3131
else if (streams_.size() == 0 ||
3232
std::find(streams_.begin(), streams_.end(), frame->type) !=
3333
streams_.end())
34-
frame->save(stream_);
34+
frame->saves(stream_);
3535

3636
out.push_back(frame);
3737
}

0 commit comments

Comments
 (0)