Subject: Re: [boost] GSOC 2015 : Project on Concurrent Hash Tables
From: Amarnath V A (me_at_[hidden])
Date: 2015-03-14 05:54:56


On Wed, Mar 11, 2015 at 7:18 AM, Niall Douglas
<s_sourceforge_at_[hidden]> 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()));
      }

>
> 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));
              }
            }
          }
        }
      }

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.

Thanks,
Amarnath