-
Notifications
You must be signed in to change notification settings - Fork 62
Add serialization #25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
99c9333
0b9a59f
70664ea
4ef6e8d
2b7cb8f
d1e113f
50dbb45
32a145f
1e93123
6cf3af5
d9bdfd7
7b9ef13
49b5d7f
12edc8d
fce55fe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,172 @@ | ||
| // Distributed under the Boost Software License, Version 1.0. | ||
| // (See the accompanying file LICENSE_1_0.txt | ||
| // or a copy at <http://www.boost.org/LICENSE_1_0.txt>.) | ||
|
|
||
| #include <boost/circular_buffer.hpp> | ||
| #include <sstream> | ||
| #include <iostream> | ||
| #include <cstdlib> | ||
| #include <random> | ||
| #include <chrono> | ||
| #include <fstream> | ||
| #include <boost/archive/text_oarchive.hpp> | ||
| #include <boost/archive/text_iarchive.hpp> | ||
| #include <boost/archive/binary_oarchive.hpp> | ||
| #include <boost/archive/binary_iarchive.hpp> | ||
|
|
||
| int main(int argc, char** argv) | ||
| { | ||
| int buffer_size = 100000; | ||
|
|
||
| if (argc == 2) { | ||
| buffer_size = std::atoi(argv[1]); | ||
| if (buffer_size <= 0) { | ||
| std::cout << "invalid buffer size" << std::endl; | ||
| return 1; | ||
| } | ||
| } | ||
|
|
||
| // Seed with a real random value, if available | ||
| std::random_device r; | ||
|
|
||
| // Choose a randomly whether to push or pop | ||
| std::default_random_engine e(r()); | ||
| std::uniform_int_distribution<int> uniform_dist(1, 10); | ||
|
|
||
| { | ||
| boost::circular_buffer<double> cb1(buffer_size); | ||
| for (auto i = 0; i < buffer_size; ++i) { | ||
| auto draw = uniform_dist(e); | ||
| if (draw < 8 || cb1.empty()) | ||
| cb1.push_back(i); | ||
| else | ||
| cb1.pop_front(); | ||
| } | ||
|
|
||
| { | ||
| // in-memory storage text | ||
| std::stringstream ss; | ||
|
|
||
| boost::archive::text_oarchive oa(ss); | ||
| std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); | ||
| boost::serialization::serialize(oa, cb1, 0); | ||
| std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); | ||
| std::cout << "in-memory serialization for buffer: " << buffer_size << " took: " << | ||
| std::chrono::duration_cast<std::chrono::microseconds> (end - begin).count() << " usec" << std::endl; | ||
|
|
||
| boost::circular_buffer<double> cb2(0); | ||
| boost::archive::text_iarchive ia(ss); | ||
| begin = std::chrono::steady_clock::now(); | ||
| boost::serialization::serialize(ia, cb2, 0); | ||
| end = std::chrono::steady_clock::now(); | ||
| std::cout << "in-memory deserialization for buffer: " << buffer_size << " took: " << | ||
| std::chrono::duration_cast<std::chrono::microseconds> (end - begin).count() << " usec" << std::endl; | ||
|
|
||
| if (cb1 != cb2) { | ||
| std::cout << "circular buffer did not recover correctly" << std::endl; | ||
| } | ||
| } | ||
|
|
||
| { | ||
| // in-memory storage binary | ||
| std::stringstream ss; | ||
|
|
||
| boost::archive::binary_oarchive oa(ss); | ||
| std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); | ||
| boost::serialization::serialize(oa, cb1, 0); | ||
| std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); | ||
| std::cout << "in-memory binary serialization for buffer: " << buffer_size << " took: " << | ||
| std::chrono::duration_cast<std::chrono::microseconds> (end - begin).count() << " usec" << std::endl; | ||
|
|
||
| boost::circular_buffer<double> cb2(0); | ||
| boost::archive::binary_iarchive ia(ss); | ||
| begin = std::chrono::steady_clock::now(); | ||
| boost::serialization::serialize(ia, cb2, 0); | ||
| end = std::chrono::steady_clock::now(); | ||
| std::cout << "in-memory binary deserialization for buffer: " << buffer_size << " took: " << | ||
| std::chrono::duration_cast<std::chrono::microseconds> (end - begin).count() << " usec" << std::endl; | ||
|
|
||
| if (cb1 != cb2) { | ||
| std::cout << "circular buffer did not recover correctly" << std::endl; | ||
| } | ||
| } | ||
|
|
||
| { | ||
| const std::string filename = "cb.tmp"; | ||
| // file storage text | ||
| { | ||
| std::ofstream ofs(filename); | ||
|
|
||
| boost::archive::text_oarchive oa(ofs); | ||
| std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); | ||
| boost::serialization::serialize(oa, cb1, 0); | ||
| std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); | ||
| std::cout << "file serialization for buffer: " << buffer_size << " took: " << | ||
| std::chrono::duration_cast<std::chrono::microseconds> (end - begin).count() << " usec" << std::endl; | ||
| } | ||
| { | ||
| std::ifstream ifs(filename); | ||
|
|
||
| boost::circular_buffer<double> cb2(0); | ||
| boost::archive::text_iarchive ia(ifs); | ||
| std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); | ||
| boost::serialization::serialize(ia, cb2, 0); | ||
| std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); | ||
| std::cout << "file deserialization for buffer: " << buffer_size << " took: " << | ||
| std::chrono::duration_cast<std::chrono::microseconds> (end - begin).count() << " usec" << std::endl; | ||
|
|
||
| if (cb1 != cb2) { | ||
| std::cout << "circular buffer did not recover correctly" << std::endl; | ||
| } | ||
| } | ||
| std::remove(filename.c_str()); | ||
| } | ||
| } | ||
|
|
||
| { | ||
| // space optimized | ||
| boost::circular_buffer_space_optimized<double> cb1(buffer_size); | ||
| for (auto i = 0; i < buffer_size; ++i) { | ||
| auto draw = uniform_dist(e); | ||
| if (draw < 8 || cb1.empty()) { | ||
| cb1.push_back(i); | ||
| } else { | ||
| cb1.pop_front(); | ||
| } | ||
| } | ||
|
|
||
| { | ||
| const std::string filename = "space_opt_cb.tmp"; | ||
| { | ||
| std::ofstream ofs(filename); | ||
|
|
||
| boost::archive::text_oarchive oa(ofs); | ||
| std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); | ||
| boost::serialization::serialize(oa, cb1, 0); | ||
| std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); | ||
| std::cout << "in-memory serialization for space optimized buffer: " << buffer_size << " took: " << | ||
| std::chrono::duration_cast<std::chrono::microseconds> (end - begin).count() << " usec" << std::endl; | ||
| } | ||
|
|
||
| { | ||
| std::ifstream ifs(filename); | ||
|
|
||
| boost::circular_buffer_space_optimized<double> cb2(0); | ||
| boost::archive::text_iarchive ia(ifs); | ||
| std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); | ||
| boost::serialization::serialize(ia, cb2, 0); | ||
| std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); | ||
| std::cout << "in-memory deserialization for space optimized buffer: " << buffer_size << " took: " << | ||
| std::chrono::duration_cast<std::chrono::microseconds> (end - begin).count() << " usec" << std::endl; | ||
|
|
||
| if (cb1 != cb2) { | ||
| std::cout << "space optimized circular buffer did not recover correctly" << std::endl; | ||
| } | ||
| } | ||
| std::remove(filename.c_str()); | ||
| } | ||
| } | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,6 +12,7 @@ project | |
| : requirements | ||
| <library>/boost/system//boost_system | ||
| <library>/boost/thread//boost_thread | ||
| <library>/boost//serialization | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't match the others - is it correct?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you mean the library location? i don't know why it is different, but this is the correct one for serialization |
||
| #<define>BOOST_ALL_NO_LIB=1 | ||
| <threading>multi | ||
|
|
||
|
|
@@ -39,4 +40,5 @@ run bounded_buffer_comparison.cpp ; | |
| run circular_buffer_iter_example.cpp ; | ||
| run circular_buffer_sum_example.cpp ; | ||
| run circular_buffer_bound_example.cpp ../../thread/build//boost_thread ../../timer/build//boost_timer ; | ||
| run circular_buffer_serialization.cpp ; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,167 @@ | ||
| // Implementation of circular_buffer serialization | ||
|
|
||
| // Use, modification, and distribution is subject to the Boost Software | ||
| // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | ||
| // http://www.boost.org/LICENSE_1_0.txt) | ||
|
|
||
| #include <boost/circular_buffer.hpp> | ||
| #include <boost/serialization/split_free.hpp> | ||
| #include <boost/smart_ptr/scoped_array.hpp> | ||
| #include <boost/archive/binary_oarchive.hpp> | ||
| #include <boost/archive/binary_iarchive.hpp> | ||
|
|
||
| namespace boost { namespace serialization { | ||
| template <class Archive, class T> | ||
| void save(Archive& ar, const circular_buffer<T>& b, const unsigned int /* version */) | ||
| { | ||
| ar << b.capacity(); | ||
| ar << b.size(); | ||
| const typename circular_buffer<T>::const_iterator it_end = b.end(); | ||
| typename circular_buffer<T>::const_iterator it = b.begin(); | ||
| for (; it != it_end; ++it) { | ||
| ar << *it; | ||
| } | ||
| } | ||
|
|
||
| template <class T> | ||
| void save(archive::binary_oarchive& ar, const circular_buffer<T>& b, const unsigned int /* version */) | ||
| { | ||
| ar << b.capacity(); | ||
| const typename circular_buffer<T>::const_array_range& one = b.array_one(); | ||
| const typename circular_buffer<T>::const_array_range& two = b.array_two(); | ||
| ar << one.second; | ||
| ar << two.second; | ||
| if (one.second) { | ||
| ar.save_binary(one.first, one.second*sizeof(T)); | ||
| } | ||
| if (two.second) { | ||
| ar.save_binary(two.first, two.second*sizeof(T)); | ||
| } | ||
| } | ||
|
|
||
| template <class Archive, class T> | ||
| void load(Archive& ar, circular_buffer<T>& b, const unsigned int /* version */) | ||
| { | ||
| b.clear(); | ||
| typename circular_buffer<T>::capacity_type capacity; | ||
| ar >> capacity; | ||
| b.set_capacity(capacity); | ||
| typename circular_buffer<T>::size_type size; | ||
| ar >> size; | ||
| while (size > 0) { | ||
| T e; | ||
| ar >> e; | ||
| b.push_back(e); | ||
| --size; | ||
| } | ||
| } | ||
|
|
||
| template <class T> | ||
| void load(archive::binary_iarchive& ar, circular_buffer<T>& b, const unsigned int /* version */) | ||
| { | ||
| b.clear(); | ||
| typename circular_buffer<T>::capacity_type capacity; | ||
| ar >> capacity; | ||
| b.set_capacity(capacity); | ||
| typename circular_buffer<T>::size_type size1; | ||
| typename circular_buffer<T>::size_type size2; | ||
| ar >> size1; | ||
| ar >> size2; | ||
| const scoped_array<typename circular_buffer<T>::value_type> buff(new T[size1+size2]); | ||
| if (size1) { | ||
| ar.load_binary(buff.get(), size1*sizeof(T)); | ||
| } | ||
| if (size2) { | ||
| ar.load_binary(&buff[size1], size2*sizeof(T)); | ||
| } | ||
| b.insert(b.begin(), buff.get(), buff.get()+size1+size2); | ||
| } | ||
|
|
||
| template<class Archive, class T> | ||
| inline void serialize(Archive & ar, circular_buffer<T>& b, const unsigned int version) | ||
| { | ||
| split_free(ar, b, version); | ||
| } | ||
|
|
||
| template <class Archive, class T> | ||
| void save(Archive& ar, const circular_buffer_space_optimized<T>& b, const unsigned int /* version */) | ||
| { | ||
| ar << b.capacity().capacity(); | ||
| ar << b.capacity().min_capacity(); | ||
| ar << b.size(); | ||
| const typename circular_buffer_space_optimized<T>::const_iterator it_end = b.end(); | ||
| typename circular_buffer_space_optimized<T>::const_iterator it = b.begin(); | ||
| for (; it != it_end; ++it) { | ||
| ar << *it; | ||
| } | ||
| } | ||
|
|
||
| template <class T> | ||
| void save(archive::binary_oarchive& ar, const circular_buffer_space_optimized<T>& b, const unsigned int /* version */) | ||
| { | ||
| ar << b.capacity().capacity(); | ||
| ar << b.capacity().min_capacity(); | ||
| const typename circular_buffer_space_optimized<T>::const_array_range one = b.array_one(); | ||
| const typename circular_buffer_space_optimized<T>::const_array_range two = b.array_two(); | ||
| ar << one.second; | ||
| ar << two.second; | ||
| if (one.second) { | ||
| ar.save_binary(one.first, one.second*sizeof(T)); | ||
| } | ||
| if (two.second) { | ||
| ar.save_binary(two.first, two.second*sizeof(T)); | ||
| } | ||
| } | ||
|
|
||
| template <class Archive, class T> | ||
| void load(Archive& ar, circular_buffer_space_optimized<T>& b, const unsigned int /* version */) | ||
| { | ||
| b.clear(); | ||
| typename circular_buffer_space_optimized<T>::size_type capacity; | ||
| typename circular_buffer_space_optimized<T>::size_type min_capacity; | ||
| ar >> capacity; | ||
| ar >> min_capacity; | ||
| const typename circular_buffer_space_optimized<T>::capacity_type capacity_control(capacity, min_capacity); | ||
| b.set_capacity(capacity_control); | ||
| typename circular_buffer<T>::size_type size; | ||
| ar >> size; | ||
| while (size > 0) { | ||
| T e; | ||
| ar >> e; | ||
| b.push_back(e); | ||
| --size; | ||
| } | ||
| } | ||
|
|
||
| template <class T> | ||
| void load(archive::binary_iarchive& ar, circular_buffer_space_optimized<T>& b, const unsigned int /* version */) | ||
| { | ||
| b.clear(); | ||
| typename circular_buffer_space_optimized<T>::size_type capacity; | ||
| typename circular_buffer_space_optimized<T>::size_type min_capacity; | ||
| ar >> capacity; | ||
| ar >> min_capacity; | ||
| const typename circular_buffer_space_optimized<T>::capacity_type capacity_control(capacity, min_capacity); | ||
| b.set_capacity(capacity_control); | ||
| typename circular_buffer<T>::size_type size1; | ||
| typename circular_buffer<T>::size_type size2; | ||
| ar >> size1; | ||
| ar >> size2; | ||
| const scoped_array<typename circular_buffer<T>::value_type> buff(new T[size1+size2]); | ||
| if (size1) { | ||
| ar.load_binary(buff.get(), size1*sizeof(T)); | ||
| } | ||
| if (size2) { | ||
| ar.load_binary(&buff[size1], size2*sizeof(T)); | ||
| } | ||
| b.insert(b.begin(), buff.get(), buff.get()+size1+size2); | ||
| } | ||
|
|
||
| template<class Archive, class T> | ||
| inline void serialize(Archive & ar, circular_buffer_space_optimized<T>& b, const unsigned int version) | ||
| { | ||
| split_free(ar, b, version); | ||
| } | ||
|
|
||
| } } // end namespace boost::serialization | ||
|
|
Uh oh!
There was an error while loading. Please reload this page.