On 14 Mar 2015 at 15:24, Amarnath V A wrote:
The move constructor can be written in two lines I believe. Think in terms of what other functions already present could be called to implement the move constructor for you. You should find the move constructor becomes quite trivial to implement, maybe two calls into other routines.
Taking hints from Niall's suggestions, I have re-implemented the move constructor using the member functions. Now, I extract the items first and then insert them into the new map.
concurrent_unordered_map(concurrent_unordered_map &&old_map) BOOST_NOEXCEPT : _hasher(std::move(old_map._hasher)), _key_equal(std::move(old_map._key_equal)), _allocator(std::move(old_map._allocator)), _max_load_factor(std::move(old_map._max_load_factor)), _min_bucket_capacity(std::move(old_map._min_bucket_capacity)), _oldbucketit(_oldbuckets.begin()) { _oldbuckets.fill(nullptr); auto items=old_map.extract(old_map.begin(), old_map.end()); buckets_type *buckets=new buckets_type(items.size()); buckets=_buckets.exchange(buckets, memory_order_acq_rel); insert(std::make_move_iterator(items.begin()), std::make_move_iterator(items.end())); }
Much better. Though in fact you can do better again. As I mentioned, I think maybe two lines. Remember in C++ 11 constructors can call other constructors.
I don't believe the copy constructor is as easy though. That you will have to implement yourself.
I am copying the snapshot of the original map when the call to the constructor was made.
concurrent_unordered_map(const concurrent_unordered_map &old_map) : _hasher(old_map._hasher), _key_equal(old_map._key_equal), _allocator(old_map._allocator), _max_load_factor(old_map._max_load_factor), _min_bucket_capacity(old_map._min_bucket_capacity), _oldbucketit(_oldbuckets.begin()) { _oldbuckets.fill(nullptr); buckets_type *tempbuckets=old_map._buckets.load(memory_order_consume); buckets_type *buckets=new buckets_type(tempbuckets->size()); buckets=_buckets.exchange(buckets, memory_order_acq_rel); for(const auto &ob : *tempbuckets) { if(ob.count.load(memory_order_relaxed)) { for(auto &i : ob.items) { if(i.p) { insert(*(i.p)); } } } } }
Now you're beginning to think more like an engineer. Good. The above is closer to working properly, but you've got a while to go yet.
Please let me know if I have got it completely wrong again. If that is the case, I don't think I should apply for GSoC this year. I have to take a step back and learn more about concurrent data structures to gain more knowledge.
"completely wrong" is too strong. Lack of experience that's all, same as any GSoC student. I'd aim for solid unit testing next. Really the competency test is testing whether students know how to test whether their solution is correct or not. I think the community ranking would favour a solid unit testing of an incorrect solution more than poor unit testing of a correct solution. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/