Boost serialization
It doesn't seem possible to skip around inside a boost serialization archive. The best I've got so far is to use multiple archives on one stream:
static const int numPatches = 5000;
std::vector<int> indices(numPatches, 0);
std::iota(indices.begin(), indices.end(), 0);
std::vector<Patch> outPatches(numPatches, Patch());
std::for_each(outPatches.begin(), outPatches.end(),
[] (Patch& p)
{
p.ZOrigin = rand();
p.XOrigin = rand();
p.Resolution = rand();
});
std::vector<int64_t> offsets(numPatches, 0);
std::ofstream ofs("testing.sss", std::ios::binary);
for (auto i : indices)
{
offsets[i] = ofs.tellp();
boost::archive::binary_oarchive oa(ofs,
boost::archive::no_header | boost::archive::no_tracking);
oa << outPatches[i];
}
ofs.close();
std::random_shuffle(indices.begin(), indices.end());
std::vector<Patch> inPatches(numPatches, Patch());
std::ifstream ifs("testing.sss", std::ios::binary);
for (auto i : indices)
{
ifs.seekg(offsets[i]);
boost::archive::binary_iarchive ia(ifs,
boost::archive::no_header | boost::archive::no_tracking);
ia >> inPatches[i];
ifs.clear();
}
std::cout << std::all_of(indices.begin(), indices.end(),
[&] (int i) { return inPatches[i] == outPatches[i]; }) << std::endl;
Unfortunately, this is very slow, so I don't think I can use it. Next up is testing protobuf.
google::protobuf
I've got something working with protobuf. It required a bit of fiddling around (apparently I have to use the LimitingInputStream type, and store the size of each object), but it's a lot faster than the boost::serialization version:
static const int numPatches = 500;
std::vector<int> indices(numPatches, 0);
std::iota(indices.begin(), indices.end(), 0);
std::vector<Patch> outPatches(numPatches, Patch());
std::for_each(outPatches.begin(), outPatches.end(),
[] (Patch& p)
{
p.ZOrigin = rand();
p.XOrigin = rand();
p.Resolution = 64;
});
std::vector<int64_t> streamOffset(numPatches, 0);
std::vector<int64_t> streamSize(numPatches, 0);
std::ofstream ofs("testing.sss", std::ios::binary);
PatchBuffer buffer;
for (auto i : indices)
{
buffer.Clear();
WriteToPatchBuffer(buffer, outPatches[i]);
streamOffset[i] = ofs.tellp();
streamSize[i] = buffer.ByteSize();
buffer.SerializeToOstream(&ofs);
}
ofs.close();
std::random_shuffle(indices.begin(), indices.end());
std::vector<Patch> inPatches(numPatches, Patch());
std::ifstream ifs("testing.sss", std::ios::binary);
for (auto i : indices)
{
ifs.seekg(streamOffset[i]);
buffer.Clear();
google::protobuf::io::IstreamInputStream iis(&ifs);
google::protobuf::io::LimitingInputStream lis(&iis, streamSize[i]);
buffer.ParseFromZeroCopyStream(&lis);
ReadFromPatchBuffer(inPatches[i], buffer);
ifs.clear();
}
std::cout << std::all_of(indices.begin(), indices.end(),
[&] (int i) { return inPatches[i] == outPatches[i]; }) << std::endl;