/*
    Copyright 2005-2010 Intel Corporation.  All Rights Reserved.

    This file is part of Threading Building Blocks.

    Threading Building Blocks is free software; you can redistribute it
    and/or modify it under the terms of the GNU General Public License
    version 2 as published by the Free Software Foundation.

    Threading Building Blocks is distributed in the hope that it will be
    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Threading Building Blocks; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

    As a special exception, you may use this file as part of a free software
    library without restriction.  Specifically, if other files instantiate
    templates or use macros or inline functions from this file, or you compile
    this file and link it with other files to produce an executable, this
    file does not by itself cause the resulting executable to be covered by
    the GNU General Public License.  This exception does not however
    invalidate any other reasons why the executable file might be covered by
    the GNU General Public License.
*/

#ifndef __TBB_concurrent_hash_map_H
#define __TBB_concurrent_hash_map_H

#include "tbb_stddef.h"

#if !TBB_USE_EXCEPTIONS && _MSC_VER
    // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers
    #pragma warning (push)
    #pragma warning (disable: 4530)
#endif

#include <iterator>
#include <utility>      // Need std::pair
#include <cstring>      // Need std::memset

#if !TBB_USE_EXCEPTIONS && _MSC_VER
    #pragma warning (pop)
#endif

#include "cache_aligned_allocator.h"
#include "tbb_allocator.h"
#include "spin_rw_mutex.h"
#include "atomic.h"
#include "aligned_space.h"
#include "tbb_exception.h"
#include "_concurrent_unordered_internal.h" // Need tbb_hasher
#if TBB_USE_PERFORMANCE_WARNINGS
#include <typeinfo>
#endif

namespace tbb {

//! @cond INTERNAL
namespace internal {
    //! ITT instrumented routine that loads pointer from location pointed to by src.
    void* __TBB_EXPORTED_FUNC itt_load_pointer_with_acquire_v3( const void* src );
    //! ITT instrumented routine that stores src into location pointed to by dst.
    void __TBB_EXPORTED_FUNC itt_store_pointer_with_release_v3( void* dst, void* src );
    //! Routine that loads pointer from location pointed to by src without causing ITT to report a race.
    void* __TBB_EXPORTED_FUNC itt_load_pointer_v3( const void* src );
}
//! @endcond

//! hash_compare that is default argument for concurrent_hash_map
template<typename Key>
struct tbb_hash_compare {
    static size_t hash( const Key& a ) { return tbb_hasher(a); }
    static bool equal( const Key& a, const Key& b ) { return a == b; }
};

namespace interface4 {

    template<typename Key, typename T, typename HashCompare = tbb_hash_compare<Key>, typename A = tbb_allocator<std::pair<Key, T> > >
    class concurrent_hash_map;

    //! @cond INTERNAL
    namespace internal {


    //! Type of a hash code.
    typedef size_t hashcode_t;
    //! Node base type
    struct hash_map_node_base : tbb::internal::no_copy {
        //! Mutex type
        typedef spin_rw_mutex mutex_t;
        //! Scoped lock type for mutex
        typedef mutex_t::scoped_lock scoped_t;
        //! Next node in chain
        hash_map_node_base *next;
        mutex_t mutex;
    };
    //! Incompleteness flag value
    static hash_map_node_base *const rehash_req = reinterpret_cast<hash_map_node_base*>(size_t(3));
    //! Rehashed empty bucket flag
    static hash_map_node_base *const empty_rehashed = reinterpret_cast<hash_map_node_base*>(size_t(0));
    //! base class of concurrent_hash_map
    class hash_map_base {
    public:
        //! Size type
        typedef size_t size_type;
        //! Type of a hash code.
        typedef size_t hashcode_t;
        //! Segment index type
        typedef size_t segment_index_t;
        //! Node base type
        typedef hash_map_node_base node_base;
        //! Bucket type
        struct bucket : tbb::internal::no_copy {
            //! Mutex type for buckets
            typedef spin_rw_mutex mutex_t;
            //! Scoped lock type for mutex
            typedef mutex_t::scoped_lock scoped_t;
            mutex_t mutex;
            node_base *node_list;
        };
        //! Count of segments in the first block
        static size_type const embedded_block = 1;
        //! Count of segments in the first block
        static size_type const embedded_buckets = 1<<embedded_block;
        //! Count of segments in the first block
        static size_type const first_block = 8; //including embedded_block. perfect with bucket size 16, so the allocations are power of 4096
        //! Size of a pointer / table size
        static size_type const pointers_per_table = sizeof(segment_index_t) * 8; // one segment per bit
        //! Segment pointer
        typedef bucket *segment_ptr_t;
        //! Segment pointers table type
        typedef segment_ptr_t segments_table_t[pointers_per_table];
        //! Hash mask = sum of allocated segments sizes - 1
        atomic<hashcode_t> my_mask;
        //! Segment pointers table. Also prevents false sharing between my_mask and my_size
        segments_table_t my_table;
        //! Size of container in stored items
        atomic<size_type> my_size; // It must be in separate cache line from my_mask due to performance effects
        //! Zero segment
        bucket my_embedded_segment[embedded_buckets];

        //! Constructor
        hash_map_base() {
            std::memset( this, 0, pointers_per_table*sizeof(segment_ptr_t) // 32*4=128   or 64*8=512
                + sizeof(my_size) + sizeof(my_mask)  // 4+4 or 8+8
                + embedded_buckets*sizeof(bucket) ); // n*8 or n*16
            for( size_type i = 0; i < embedded_block; i++ ) // fill the table
                my_table[i] = my_embedded_segment + segment_base(i);
            my_mask = embedded_buckets - 1;
            __TBB_ASSERT( embedded_block <= first_block, "The first block number must include embedded blocks");
        }

        //! @return segment index of given index in the array
        static segment_index_t segment_index_of( size_type index ) {
            return segment_index_t( __TBB_Log2( index|1 ) );
        }

        //! @return the first array index of given segment
        static segment_index_t segment_base( segment_index_t k ) {
            return (segment_index_t(1)<<k & ~segment_index_t(1));
        }

        //! @return segment size except for @arg k == 0
        static size_type segment_size( segment_index_t k ) {
            return size_type(1)<<k; // fake value for k==0
        }
        
        //! @return true if @arg ptr is valid pointer
        static bool is_valid( void *ptr ) {
            return reinterpret_cast<size_t>(ptr) > size_t(63);
        }

        //! Initialize buckets
        static void init_buckets( segment_ptr_t ptr, size_type sz, bool is_initial ) {
            if( is_initial ) std::memset(ptr, 0, sz*sizeof(bucket) );
            else for(size_type i = 0; i < sz; i++, ptr++) {
                    *reinterpret_cast<intptr_t*>(&ptr->mutex) = 0;
                    ptr->node_list = rehash_req;
                }
        }
        
        //! Add node @arg n to bucket @arg b
        static void add_to_bucket( bucket *b, node_base *n ) {
            __TBB_ASSERT(b->node_list != rehash_req, NULL);
            n->next = b->node_list;
            b->node_list = n; // its under lock and flag is set
        }

        //! Exception safety helper
        struct enable_segment_failsafe {
            segment_ptr_t *my_segment_ptr;
            enable_segment_failsafe(segments_table_t &table, segment_index_t k) : my_segment_ptr(&table[k]) {}
            ~enable_segment_failsafe() {
                if( my_segment_ptr ) *my_segment_ptr = 0; // indicate no allocation in progress
            }
        };

        //! Enable segment
        void enable_segment( segment_index_t k, bool is_initial = false ) {
            __TBB_ASSERT( k, "Zero segment must be embedded" );
            enable_segment_failsafe watchdog( my_table, k );
            cache_aligned_allocator<bucket> alloc;
            size_type sz;
            __TBB_ASSERT( !is_valid(my_table[k]), "Wrong concurrent assignment");
            if( k >= first_block ) {
                sz = segment_size( k );
                segment_ptr_t ptr = alloc.allocate( sz );
                init_buckets( ptr, sz, is_initial );
#if TBB_USE_THREADING_TOOLS
                // TODO: actually, fence and notification are unnecessary here and below
                itt_store_pointer_with_release_v3( my_table + k, ptr );
#else
                my_table[k] = ptr;// my_mask has release fence
#endif
                sz <<= 1;// double it to get entire capacity of the container
            } else { // the first block
                __TBB_ASSERT( k == embedded_block, "Wrong segment index" );
                sz = segment_size( first_block );
                segment_ptr_t ptr = alloc.allocate( sz - embedded_buckets );
                init_buckets( ptr, sz - embedded_buckets, is_initial );
                ptr -= segment_base(embedded_block);
                for(segment_index_t i = embedded_block; i < first_block; i++) // calc the offsets
#if TBB_USE_THREADING_TOOLS
                    itt_store_pointer_with_release_v3( my_table + i, ptr + segment_base(i) );
#else
                    my_table[i] = ptr + segment_base(i);
#endif
            }
#if TBB_USE_THREADING_TOOLS
            itt_store_pointer_with_release_v3( &my_mask, (void*)(sz-1) );
#else
            my_mask = sz - 1;
#endif
            watchdog.my_segment_ptr = 0;
        }

        //! Get bucket by (masked) hashcode
        bucket *get_bucket( hashcode_t h ) const noexcept { // TODO: add throw() everywhere?
            segment_index_t s = segment_index_of( h );
            h -= segment_base(s);
            segment_ptr_t seg = my_table[s];
            __TBB_ASSERT( is_valid(seg), "hashcode must be cut by valid mask for allocated segments" );
            return &seg[h];
        }

        // internal serial rehashing helper
        void mark_rehashed_levels( hashcode_t h ) throw () {
            segment_index_t s = segment_index_of( h );
            while( segment_ptr_t seg = my_table[++s] )
                if( seg[h].node_list == rehash_req ) {
                    seg[h].node_list = empty_rehashed;
                    mark_rehashed_levels( h + segment_base(s) );
                }
        }

        //! Check for mask race
        // Splitting into two functions should help inlining
        inline bool check_mask_race( const hashcode_t h, hashcode_t &m ) const {
            hashcode_t m_now, m_old = m;
#if TBB_USE_THREADING_TOOLS
            m_now = (hashcode_t) itt_load_pointer_with_acquire_v3( &my_mask );
#else
            m_now = my_mask;
#endif
            if( m_old != m_now )
                return check_rehashing_collision( h, m_old, m = m_now );
            return false;
        }

        //! Process mask race, check for rehashing collision
        bool check_rehashing_collision( const hashcode_t h, hashcode_t m_old, hashcode_t m ) const {
            __TBB_ASSERT(m_old != m, NULL); // TODO?: m arg could be optimized out by passing h = h&m
            if( (h & m_old) != (h & m) ) { // mask changed for this hashcode, rare event
                // condition above proves that 'h' has some other bits set beside 'm_old'
                // find next applicable mask after m_old    //TODO: look at bsl instruction
                for( ++m_old; !(h & m_old); m_old <<= 1 ) // at maximum few rounds depending on the first block size
                    ;
                m_old = (m_old<<1) - 1; // get full mask from a bit
                __TBB_ASSERT((m_old&(m_old+1))==0 && m_old <= m, NULL);
                // check whether it is rehashing/ed
#if TBB_USE_THREADING_TOOLS
                if( itt_load_pointer_with_acquire_v3(&( get_bucket(h & m_old)->node_list )) != rehash_req )
#else
                if( __TBB_load_with_acquire(get_bucket( h & m_old )->node_list) != rehash_req )
#endif
                    return true;
            }
            return false;
        }

        //! Insert a node and check for load factor. @return segment index to enable.
        segment_index_t insert_new_node( bucket *b, node_base *n, hashcode_t mask ) {
            size_type sz = ++my_size; // prefix form is to enforce allocation after the first item inserted
            add_to_bucket( b, n );
            // check load factor
            if( sz >= mask ) { // TODO: add custom load_factor 
                segment_index_t new_seg = segment_index_of( mask+1 );
                __TBB_ASSERT( is_valid(my_table[new_seg-1]), "new allocations must not publish new mask until segment has allocated");
#if TBB_USE_THREADING_TOOLS
                if( !itt_load_pointer_v3(my_table+new_seg)
#else
                if( !my_table[new_seg]
#endif
                  && __TBB_CompareAndSwapW(&my_table[new_seg], 2, 0) == 0 )
                    return new_seg; // The value must be processed
            }
            return 0;
        }

        //! Prepare enough segments for number of buckets
        void reserve(size_type buckets) {
            if( !buckets-- ) return;
            bool is_initial = !my_size;
            for( size_type m = my_mask; buckets > m; m = my_mask )
                enable_segment( segment_index_of( m+1 ), is_initial );
        }
        //! Swap hash_map_bases
        void internal_swap(hash_map_base &table) {
            std::swap(this->my_mask, table.my_mask);
            std::swap(this->my_size, table.my_size);
            for(size_type i = 0; i < embedded_buckets; i++)
                std::swap(this->my_embedded_segment[i].node_list, table.my_embedded_segment[i].node_list);
            for(size_type i = embedded_block; i < pointers_per_table; i++)
                std::swap(this->my_table[i], table.my_table[i]);
        }
    };

    template<typename Iterator>
    class hash_map_range;

    //! Meets requirements of a forward iterator for STL */
    /** Value is either the T or const T type of the container.
        @ingroup containers */ 
    template<typename Container, typename Value>
    class hash_map_iterator
        : public std::iterator<std::forward_iterator_tag,Value>
    {
        typedef Container map_type;
        typedef typename Container::node node;
        typedef hash_map_base::node_base node_base;
        typedef hash_map_base::bucket bucket;

        template<typename C, typename T, typename U>
        friend bool operator==( const hash_map_iterator<C,T>& i, const hash_map_iterator<C,U>& j );

        template<typename C, typename T, typename U>
        friend bool operator!=( const hash_map_iterator<C,T>& i, const hash_map_iterator<C,U>& j );

        template<typename C, typename T, typename U>
        friend ptrdiff_t operator-( const hash_map_iterator<C,T>& i, const hash_map_iterator<C,U>& j );
    
        template<typename C, typename U>
        friend class hash_map_iterator;

        template<typename I>
        friend class hash_map_range;

        void advance_to_next_bucket() { // TODO?: refactor to iterator_base class
            size_t k = my_index+1;
            while( my_bucket && k <= my_map->my_mask ) {
                // Following test uses 2's-complement wizardry
                if( k& (k-2) ) // not the beginning of a segment
                    ++my_bucket;
                else my_bucket = my_map->get_bucket( k );
                my_node = static_cast<node*>( my_bucket->node_list );
                if( hash_map_base::is_valid(my_node) ) {
                    my_index = k; return;
                }
                ++k;
            }
            my_bucket = 0; my_node = 0; my_index = k; // the end
        }
#if !defined(_MSC_VER) || defined(__INTEL_COMPILER)
        template<typename Key, typename T, typename HashCompare, typename A>
        friend class interface4::concurrent_hash_map;
#else
    public: // workaround
#endif
        //! concurrent_hash_map over which we are iterating.
        const Container *my_map;

        //! Index in hash table for current item
        size_t my_index;

        //! Pointer to bucket
        const bucket *my_bucket;

        //! Pointer to node that has current item
        node *my_node;

        hash_map_iterator( const Container &map, size_t index, const bucket *b, node_base *n );

    public:
        //! Construct undefined iterator
        hash_map_iterator() {}
        hash_map_iterator( const hash_map_iterator<Container,typename Container::value_type> &other ) :
            my_map(other.my_map),
            my_index(other.my_index),
            my_bucket(other.my_bucket),
            my_node(other.my_node)
        {}
        Value& operator*() const {
            __TBB_ASSERT( hash_map_base::is_valid(my_node), "iterator uninitialized or at end of container?" );
            return my_node->item;
        }
        Value* operator->() const {return &operator*();}
        hash_map_iterator& operator++();
        
        //! Post increment
        Value* operator++(int) {
            Value* result = &operator*();
            operator++();
            return result;
        }
    };

    template<typename Container, typename Value>
    hash_map_iterator<Container,Value>::hash_map_iterator( const Container &map, size_t index, const bucket *b, node_base *n ) :
        my_map(&map),
        my_index(index),
        my_bucket(b),
        my_node( static_cast<node*>(n) )
    {
        if( b && !hash_map_base::is_valid(n) )
            advance_to_next_bucket();
    }

    template<typename Container, typename Value>
    hash_map_iterator<Container,Value>& hash_map_iterator<Container,Value>::operator++() {
        my_node = static_cast<node*>( my_node->next );
        if( !my_node ) advance_to_next_bucket();
        return *this;
    }

    template<typename Container, typename T, typename U>
    bool operator==( const hash_map_iterator<Container,T>& i, const hash_map_iterator<Container,U>& j ) {
        return i.my_node == j.my_node && i.my_map == j.my_map;
    }

    template<typename Container, typename T, typename U>
    bool operator!=( const hash_map_iterator<Container,T>& i, const hash_map_iterator<Container,U>& j ) {
        return i.my_node != j.my_node || i.my_map != j.my_map;
    }

    //! Range class used with concurrent_hash_map
    /** @ingroup containers */ 
    template<typename Iterator>
    class hash_map_range {
        typedef typename Iterator::map_type map_type;
        Iterator my_begin;
        Iterator my_end;
        mutable Iterator my_midpoint;
        size_t my_grainsize;
        //! Set my_midpoint to point approximately half way between my_begin and my_end.
        void set_midpoint() const;
        template<typename U> friend class hash_map_range;
    public:
        //! Type for size of a range
        typedef std::size_t size_type;
        typedef typename Iterator::value_type value_type;
        typedef typename Iterator::reference reference;
        typedef typename Iterator::difference_type difference_type;
        typedef Iterator iterator;

        //! True if range is empty.
        bool empty() const {return my_begin==my_end;}

        //! True if range can be partitioned into two subranges.
        bool is_divisible() const {
            return my_midpoint!=my_end;
        }
        //! Split range.
        hash_map_range( hash_map_range& r, split ) : 
            my_end(r.my_end),
            my_grainsize(r.my_grainsize)
        {
            r.my_end = my_begin = r.my_midpoint;
            __TBB_ASSERT( !empty(), "Splitting despite the range is not divisible" );
            __TBB_ASSERT( !r.empty(), "Splitting despite the range is not divisible" );
            set_midpoint();
            r.set_midpoint();
        }
        //! type conversion
        template<typename U>
        hash_map_range( hash_map_range<U>& r) : 
            my_begin(r.my_begin),
            my_end(r.my_end),
            my_midpoint(r.my_midpoint),
            my_grainsize(r.my_grainsize)
        {}
#if TBB_DEPRECATED
        //! Init range with iterators and grainsize specified
        hash_map_range( const Iterator& begin_, const Iterator& end_, size_type grainsize_ = 1 ) : 
            my_begin(begin_), 
            my_end(end_),
            my_grainsize(grainsize_)
        {
            if(!my_end.my_index && !my_end.my_bucket) // end
                my_end.my_index = my_end.my_map->my_mask + 1;
            set_midpoint();
            __TBB_ASSERT( grainsize_>0, "grainsize must be positive" );
        }
#endif
        //! Init range with container and grainsize specified
        hash_map_range( const map_type &map, size_type grainsize_ = 1 ) : 
            my_begin( Iterator( map, 0, map.my_embedded_segment, map.my_embedded_segment->node_list ) ),
            my_end( Iterator( map, map.my_mask + 1, 0, 0 ) ),
            my_grainsize( grainsize_ )
        {
            __TBB_ASSERT( grainsize_>0, "grainsize must be positive" );
            set_midpoint();
        }
        const Iterator& begin() const {return my_begin;}
        const Iterator& end() const {return my_end;}
        //! The grain size for this range.
        size_type grainsize() const {return my_grainsize;}
    };

    template<typename Iterator>
    void hash_map_range<Iterator>::set_midpoint() const {
        // Split by groups of nodes
        size_t m = my_end.my_index-my_begin.my_index;
        if( m > my_grainsize ) {
            m = my_begin.my_index + m/2u;
            hash_map_base::bucket *b = my_begin.my_map->get_bucket(m);
            my_midpoint = Iterator(*my_begin.my_map,m,b,b->node_list);
        } else {
            my_midpoint = my_end;
        }
        __TBB_ASSERT( my_begin.my_index <= my_midpoint.my_index,
            "my_begin is after my_midpoint" );
        __TBB_ASSERT( my_midpoint.my_index <= my_end.my_index,
            "my_midpoint is after my_end" );
        __TBB_ASSERT( my_begin != my_midpoint || my_begin == my_end,
            "[my_begin, my_midpoint) range should not be empty" );
    }

    } // internal
//! @endcond

//! Unordered map from Key to T.
/** concurrent_hash_map is associative container with concurrent access.

@par Compatibility
    The class meets all Container Requirements from C++ Standard (See ISO/IEC 14882:2003(E), clause 23.1).

@par Exception Safety
    - Hash function is not permitted to throw an exception. User-defined types Key and T are forbidden from throwing an exception in destructors.
    - If exception happens during insert() operations, it has no effect (unless exception raised by HashCompare::hash() function during grow_segment).
    - If exception happens during operator=() operation, the container can have a part of source items, and methods size() and empty() can return wrong results.

@par Changes since TBB 2.1
    - Replaced internal algorithm and data structure. Patent is pending.
    - Added buckets number argument for constructor

@par Changes since TBB 2.0
    - Fixed exception-safety
    - Added template argument for allocator
    - Added allocator argument in constructors
    - Added constructor from a range of iterators
    - Added several new overloaded insert() methods
    - Added get_allocator()
    - Added swap()
    - Added count()
    - Added overloaded erase(accessor &) and erase(const_accessor&)
    - Added equal_range() [const]
    - Added [const_]pointer, [const_]reference, and allocator_type types
    - Added global functions: operator==(), operator!=(), and swap() 

    @ingroup containers */
template<typename Key, typename T, typename HashCompare, typename Allocator>
class concurrent_hash_map : protected internal::hash_map_base {
    template<typename Container, typename Value>
    friend class internal::hash_map_iterator;

    template<typename I>
    friend class internal::hash_map_range;

public:
    typedef Key key_type;
    typedef T mapped_type;
    typedef std::pair<const Key,T> value_type;
    typedef hash_map_base::size_type size_type;
    typedef ptrdiff_t difference_type;
    typedef value_type *pointer;
    typedef const value_type *const_pointer;
    typedef value_type &reference;
    typedef const value_type &const_reference;
    typedef internal::hash_map_iterator<concurrent_hash_map,value_type> iterator;
    typedef internal::hash_map_iterator<concurrent_hash_map,const value_type> const_iterator;
    typedef internal::hash_map_range<iterator> range_type;
    typedef internal::hash_map_range<const_iterator> const_range_type;
    typedef Allocator allocator_type;

protected:
    friend class const_accessor;
    struct node;
    typedef typename Allocator::template rebind<node>::other node_allocator_type;
    node_allocator_type my_allocator;
    HashCompare my_hash_compare;

    struct node : public node_base {
        value_type item;
        node( const Key &key ) : item(key, T()) {}
        node( const Key &key, const T &t ) : item(key, t) {}
        // exception-safe allocation, see C++ Standard 2003, clause 5.3.4p17
        void *operator new( size_t /*size*/, node_allocator_type &a ) {
            void *ptr = a.allocate(1);
            if(!ptr) 
                tbb::internal::throw_exception(tbb::internal::eid_bad_alloc);
            return ptr;
        }
        // match placement-new form above to be called if exception thrown in constructor
        void operator delete( void *ptr, node_allocator_type &a ) {return a.deallocate(static_cast<node*>(ptr),1); }
    };

    void delete_node( node_base *n ) {
        my_allocator.destroy( static_cast<node*>(n) );
        my_allocator.deallocate( static_cast<node*>(n), 1);
    }

    node *search_bucket( const key_type &key, bucket *b ) const {
        node *n = static_cast<node*>( b->node_list );
        while( is_valid(n) && !my_hash_compare.equal(key, n->item.first) )
            n = static_cast<node*>( n->next );
        __TBB_ASSERT(n != internal::rehash_req, "Search can be executed only for rehashed bucket");
        return n;
    }

    //! bucket accessor is to find, rehash, acquire a lock, and access a bucket
    class bucket_accessor : public bucket::scoped_t {
        bool my_is_writer; // TODO: use it from base type
        bucket *my_b;
    public:
        bucket_accessor( concurrent_hash_map *base, const hashcode_t h, bool writer = false ) { acquire( base, h, writer ); }
        //! find a bucket by masked hashcode, optionally rehash, and acquire the lock
        inline void acquire( concurrent_hash_map *base, const hashcode_t h, bool writer = false ) {
            my_b = base->get_bucket( h );
#if TBB_USE_THREADING_TOOLS
            // TODO: actually, notification is unnecessary here, just hiding double-check
            if( itt_load_pointer_with_acquire_v3(&my_b->node_list) == internal::rehash_req
#else
            if( __TBB_load_with_acquire(my_b->node_list) == internal::rehash_req
#endif
                && try_acquire( my_b->mutex, /*write=*/true ) )
            {
                if( my_b->node_list == internal::rehash_req ) base->rehash_bucket( my_b, h ); //recursive rehashing
                my_is_writer = true;
            }
            else bucket::scoped_t::acquire( my_b->mutex, /*write=*/my_is_writer = writer );
            __TBB_ASSERT( my_b->node_list != internal::rehash_req, NULL);
        }
        //! check whether bucket is locked for write
        bool is_writer() { return my_is_writer; }
        //! get bucket pointer
        bucket *operator() () { return my_b; }
        // TODO: optimize out
        bool upgrade_to_writer() { my_is_writer = true; return bucket::scoped_t::upgrade_to_writer(); }
    };

    // TODO refactor to hash_base
    void rehash_bucket( bucket *b_new, const hashcode_t h ) {
        __TBB_ASSERT( *(intptr_t*)(&b_new->mutex), "b_new must be locked (for write)");
        __TBB_ASSERT( h > 1, "The lowermost buckets can't be rehashed" );
        __TBB_store_with_release(b_new->node_list, internal::empty_rehashed); // mark rehashed
        hashcode_t mask = ( 1u<<__TBB_Log2( h ) ) - 1; // get parent mask from the topmost bit

        bucket_accessor b_old( this, h & mask );

        mask = (mask<<1) | 1; // get full mask for new bucket
        __TBB_ASSERT( (mask&(mask+1))==0 && (h & mask) == h, NULL );
    restart:
        for( node_base **p = &b_old()->node_list, *n = __TBB_load_with_acquire(*p); is_valid(n); n = *p ) {
            hashcode_t c = my_hash_compare.hash( static_cast<node*>(n)->item.first );
#if TBB_USE_ASSERT
            hashcode_t bmask = h & (mask>>1);
            bmask = bmask==0? 1 : ( 1u<<(__TBB_Log2( bmask )+1 ) ) - 1; // minimal mask of parent bucket
            __TBB_ASSERT( (c & bmask) == (h & bmask), "hash() function changed for key in table" );
#endif
            if( (c & mask) == h ) {
                if( !b_old.is_writer() )
                    if( !b_old.upgrade_to_writer() ) {
                        goto restart; // node ptr can be invalid due to concurrent erase
                    }
                *p = n->next; // exclude from b_old
                add_to_bucket( b_new, n );
            } else p = &n->next; // iterate to next item
        }
    }

public:
    
    class accessor;
    //! Combines data access, locking, and garbage collection.
    class const_accessor {
        friend class concurrent_hash_map<Key,T,HashCompare,Allocator>;
        friend class accessor;
        void operator=( const accessor & ) const; // Deny access
        const_accessor( const accessor & );       // Deny access
    public:
        //! Type of value
        typedef const typename concurrent_hash_map::value_type value_type;

        //! True if result is empty.
        bool empty() const {return !my_node;}

        //! Set to null
        void release() {
            if( my_node ) {
                my_lock.release();
                my_node = 0;
            }
        }

        //! Return reference to associated value in hash table.
        const_reference operator*() const {
            __TBB_ASSERT( my_node, "attempt to dereference empty accessor" );
            return my_node->item;
        }

        //! Return pointer to associated value in hash table.
        const_pointer operator->() const {
            return &operator*();
        }

        //! Create empty result
        const_accessor() : my_node(NULL) {}

        //! Destroy result after releasing the underlying reference.
        ~const_accessor() {
            my_node = NULL; // my_lock.release() is called in scoped_lock destructor
        }
    private:
        node *my_node;
        typename node::scoped_t my_lock;
        hashcode_t my_hash;
    };

    //! Allows write access to elements and combines data access, locking, and garbage collection.
    class accessor: public const_accessor {
    public:
        //! Type of value
        typedef typename concurrent_hash_map::value_type value_type;

        //! Return reference to associated value in hash table.
        reference operator*() const {
            __TBB_ASSERT( this->my_node, "attempt to dereference empty accessor" );
            return this->my_node->item;
        }

        //! Return pointer to associated value in hash table.
        pointer operator->() const {
            return &operator*();
        }
    };

    //! Construct empty table.
    concurrent_hash_map(const allocator_type &a = allocator_type())
        : internal::hash_map_base(), my_allocator(a)
    {}

    //! Construct empty table with n preallocated buckets. This number serves also as initial concurrency level.
    concurrent_hash_map(size_type n, const allocator_type &a = allocator_type())
        : my_allocator(a)
    {
        reserve( n );
    }

    //! Copy constructor
    concurrent_hash_map( const concurrent_hash_map& table, const allocator_type &a = allocator_type())
        : internal::hash_map_base(), my_allocator(a)
    {
        internal_copy(table);
    }

    //! Construction with copying iteration range and given allocator instance
    template<typename I>
    concurrent_hash_map(I first, I last, const allocator_type &a = allocator_type())
        : my_allocator(a)
    {
        reserve( std::distance(first, last) ); // TODO: load_factor?
        internal_copy(first, last);
    }

    //! Assignment
    concurrent_hash_map& operator=( const concurrent_hash_map& table ) {
        if( this!=&table ) {
            clear();
            internal_copy(table);
        } 
        return *this;
    }


    //! Rehashes and optionally resizes the whole table.
    /** Useful to optimize performance before or after concurrent operations.
        Also enables using of find() and count() concurrent methods in serial context. */
    void rehash(size_type n = 0);
    
    //! Clear table
    void clear();

    //! Clear table and destroy it.  
    ~concurrent_hash_map() { clear(); }

    //------------------------------------------------------------------------
    // Parallel algorithm support
    //------------------------------------------------------------------------
    range_type range( size_type grainsize=1 ) {
        return range_type( *this, grainsize );
    }
    const_range_type range( size_type grainsize=1 ) const {
        return const_range_type( *this, grainsize );
    }

    //------------------------------------------------------------------------
    // STL support - not thread-safe methods
    //------------------------------------------------------------------------
    iterator begin() {return iterator(*this,0,my_embedded_segment,my_embedded_segment->node_list);}
    iterator end() {return iterator(*this,0,0,0);}
    const_iterator begin() const {return const_iterator(*this,0,my_embedded_segment,my_embedded_segment->node_list);}
    const_iterator end() const {return const_iterator(*this,0,0,0);}
    std::pair<iterator, iterator> equal_range( const Key& key ) { return internal_equal_range(key, end()); }
    std::pair<const_iterator, const_iterator> equal_range( const Key& key ) const { return internal_equal_range(key, end()); }
    
    //! Number of items in table.
    size_type size() const { return my_size; }

    //! True if size()==0.
    bool empty() const { return my_size == 0; }

    //! Upper bound on size.
    size_type max_size() const {return (~size_type(0))/sizeof(node);}

    //! Returns the current number of buckets
    size_type bucket_count() const { return my_mask+1; }

    //! return allocator object
    allocator_type get_allocator() const { return this->my_allocator; }

    //! swap two instances. Iterators are invalidated
    void swap(concurrent_hash_map &table);

    //------------------------------------------------------------------------
    // concurrent map operations
    //------------------------------------------------------------------------

    //! Return count of items (0 or 1)
    size_type count( const Key &key ) const {
        return const_cast<concurrent_hash_map*>(this)->lookup(/*insert*/false, key, NULL, NULL, /*write=*/false );
    }

    //! Find item and acquire a read lock on the item.
    /** Return true if item is found, false otherwise. */
    bool find( const_accessor &result, const Key &key ) const {
        result.release();
        return const_cast<concurrent_hash_map*>(this)->lookup(/*insert*/false, key, NULL, &result, /*write=*/false );
    }

    //! Find item and acquire a write lock on the item.
    /** Return true if item is found, false otherwise. */
    bool find( accessor &result, const Key &key ) {
        result.release();
        return lookup(/*insert*/false, key, NULL, &result, /*write=*/true );
    }
        
    //! Insert item (if not already present) and acquire a read lock on the item.
    /** Returns true if item is new. */
    bool insert( const_accessor &result, const Key &key ) {
        result.release();
        return lookup(/*insert*/true, key, NULL, &result, /*write=*/false );
    }

    //! Insert item (if not already present) and acquire a write lock on the item.
    /** Returns true if item is new. */
    bool insert( accessor &result, const Key &key ) {
        result.release();
        return lookup(/*insert*/true, key, NULL, &result, /*write=*/true );
    }

    //! Insert item by copying if there is no such key present already and acquire a read lock on the item.
    /** Returns true if item is new. */
    bool insert( const_accessor &result, const value_type &value ) {
        result.release();
        return lookup(/*insert*/true, value.first, &value.second, &result, /*write=*/false );
    }

    //! Insert item by copying if there is no such key present already and acquire a write lock on the item.
    /** Returns true if item is new. */
    bool insert( accessor &result, const value_type &value ) {
        result.release();
        return lookup(/*insert*/true, value.first, &value.second, &result, /*write=*/true );
    }

    //! Insert item by copying if there is no such key present already
    /** Returns true if item is inserted. */
    bool insert( const value_type &value ) {
        return lookup(/*insert*/true, value.first, &value.second, NULL, /*write=*/false );
    }

    //! Insert range [first, last)
    template<typename I>
    void insert(I first, I last) {
        for(; first != last; ++first)
            insert( *first );
    }

    //! Erase item.
    /** Return true if item was erased by particularly this call. */
    bool erase( const Key& key );

    //! Erase item by const_accessor.
    /** Return true if item was erased by particularly this call. */
    bool erase( const_accessor& item_accessor ) {
        return exclude( item_accessor, /*readonly=*/ true );
    }

    //! Erase item by accessor.
    /** Return true if item was erased by particularly this call. */
    bool erase( accessor& item_accessor ) {
        return exclude( item_accessor, /*readonly=*/ false );
    }

protected:
    //! Insert or find item and optionally acquire a lock on the item.
    bool lookup( bool op_insert, const Key &key, const T *t, const_accessor *result, bool write );

    //! delete item by accessor
    bool exclude( const_accessor &item_accessor, bool readonly );

    //! Returns an iterator for an item defined by the key, or for the next item after it (if upper==true)
    template<typename I>
    std::pair<I, I> internal_equal_range( const Key& key, I end ) const;

    //! Copy "source" to *this, where *this must start out empty.
    void internal_copy( const concurrent_hash_map& source );

    template<typename I>
    void internal_copy(I first, I last);

    //! Fast find when no concurrent erasure is used. For internal use inside TBB only!
    /** Return pointer to item with given key, or NULL if no such item exists.
        Must not be called concurrently with erasure operations. */
    const_pointer internal_fast_find( const Key& key ) const {
        hashcode_t h = my_hash_compare.hash( key );
#if TBB_USE_THREADING_TOOLS
        hashcode_t m = (hashcode_t) itt_load_pointer_with_acquire_v3( &my_mask );
#else
        hashcode_t m = my_mask;
#endif
        node *n;
    restart:
        __TBB_ASSERT((m&(m+1))==0, NULL);
        bucket *b = get_bucket( h & m );
#if TBB_USE_THREADING_TOOLS
        // TODO: actually, notification is unnecessary here, just hiding double-check
        if( itt_load_pointer_with_acquire_v3(&b->node_list) == internal::rehash_req )
#else
        if( __TBB_load_with_acquire(b->node_list) == internal::rehash_req )
#endif
        {
            bucket::scoped_t lock;
            if( lock.try_acquire( b->mutex, /*write=*/true ) ) {
                if( b->node_list == internal::rehash_req)
                    const_cast<concurrent_hash_map*>(this)->rehash_bucket( b, h & m ); //recursive rehashing
            }
            else lock.acquire( b->mutex, /*write=*/false );
            __TBB_ASSERT(b->node_list!=internal::rehash_req,NULL);
        }
        n = search_bucket( key, b );
        if( n )
            return &n->item;
        else if( check_mask_race( h, m ) )
            goto restart;
        return 0;
    }
};

#if _MSC_VER && !defined(__INTEL_COMPILER)
    // Suppress "conditional expression is constant" warning.
    #pragma warning( push )
    #pragma warning( disable: 4127 )
#endif

template<typename Key, typename T, typename HashCompare, typename A>
bool concurrent_hash_map<Key,T,HashCompare,A>::lookup( bool op_insert, const Key &key, const T *t, const_accessor *result, bool write ) {
    __TBB_ASSERT( !result || !result->my_node, NULL );
    segment_index_t grow_segment;
    bool return_value;
    node *n, *tmp_n = 0;
    hashcode_t const h = my_hash_compare.hash( key );
#if TBB_USE_THREADING_TOOLS
    hashcode_t m = (hashcode_t) itt_load_pointer_with_acquire_v3( &my_mask );
#else
    hashcode_t m = my_mask;
#endif
    restart:
    {//lock scope
        __TBB_ASSERT((m&(m+1))==0, NULL);
        return_value = false;
        // get bucket
        bucket_accessor b( this, h & m );

        // find a node
        n = search_bucket( key, b() );
        if( op_insert ) {
            // [opt] insert a key
            if( !n ) {
                if( !tmp_n ) {
                    if(t) tmp_n = new( my_allocator ) node(key, *t);
                    else  tmp_n = new( my_allocator ) node(key);
                }
                if( !b.is_writer() && !b.upgrade_to_writer() ) { // TODO: improved insertion
                    // Rerun search_list, in case another thread inserted the item during the upgrade.
                    n = search_bucket( key, b() );
                    if( is_valid(n) ) { // unfortunately, it did
                        b.downgrade_to_reader();
                        goto exists;
                    }
                }
                if( check_mask_race(h, m) )
                    goto restart; // b.release() is done in ~b().
                // insert and set flag to grow the container
                grow_segment = insert_new_node( b(), n = tmp_n, m );
                tmp_n = 0;
                return_value = true;
            } else {
    exists:     grow_segment = 0;
            }
        } else { // find or count
            if( !n ) {
                if( check_mask_race( h, m ) )
                    goto restart; // b.release() is done in ~b(). TODO: replace by continue
                return false;
            }
            return_value = true;
            grow_segment = 0;
        }
        if( !result ) goto check_growth;
        // TODO: the following seems as generic/regular operation
        // acquire the item
        if( !result->my_lock.try_acquire( n->mutex, write ) ) {
            // we are unlucky, prepare for longer wait
            tbb::internal::atomic_backoff trials;
            do {
                if( !trials.bounded_pause() ) {
                    // the wait takes really long, restart the operation
                    b.release();
                    __TBB_ASSERT( !op_insert || !return_value, "Can't acquire new item in locked bucket?" );
                    __TBB_Yield();
#if TBB_USE_THREADING_TOOLS
                    m = (hashcode_t) itt_load_pointer_with_acquire_v3( &my_mask );
#else
                    m = my_mask;
#endif
                    goto restart;
                }
            } while( !result->my_lock.try_acquire( n->mutex, write ) );
        }
    }//lock scope
    result->my_node = n;
    result->my_hash = h;
check_growth:
    // [opt] grow the container
    if( grow_segment )
        enable_segment( grow_segment );
    if( tmp_n ) // if op_insert only
        delete_node( tmp_n );
    return return_value;
}

template<typename Key, typename T, typename HashCompare, typename A>
template<typename I>
std::pair<I, I> concurrent_hash_map<Key,T,HashCompare,A>::internal_equal_range( const Key& key, I end_ ) const {
    hashcode_t h = my_hash_compare.hash( key );
    hashcode_t m = my_mask;
    __TBB_ASSERT((m&(m+1))==0, NULL);
    h &= m;
    bucket *b = get_bucket( h );
    while( b->node_list == internal::rehash_req ) {
        m = ( 1u<<__TBB_Log2( h ) ) - 1; // get parent mask from the topmost bit
        b = get_bucket( h &= m );
    }
    node *n = search_bucket( key, b );
    if( !n )
        return std::make_pair(end_, end_);
    iterator lower(*this, h, b, n), upper(lower);
    return std::make_pair(lower, ++upper);
}

template<typename Key, typename T, typename HashCompare, typename A>
bool concurrent_hash_map<Key,T,HashCompare,A>::exclude( const_accessor &item_accessor, bool readonly ) {
    __TBB_ASSERT( item_accessor.my_node, NULL );
    node_base *const n = item_accessor.my_node;
    item_accessor.my_node = NULL; // we ought release accessor anyway
    hashcode_t const h = item_accessor.my_hash;
#if TBB_USE_THREADING_TOOLS
    hashcode_t m = (hashcode_t) itt_load_pointer_with_acquire_v3( &my_mask );
#else
    hashcode_t m = my_mask;
#endif
    do {
        // get bucket
        bucket_accessor b( this, h & m, /*writer=*/true );
        node_base **p = &b()->node_list;
        while( *p && *p != n )
            p = &(*p)->next;
        if( !*p ) { // someone else was the first
            if( check_mask_race( h, m ) )
                continue;
            item_accessor.my_lock.release();
            return false;
        }
        __TBB_ASSERT( *p == n, NULL );
        *p = n->next; // remove from container
        my_size--;
        break;
    } while(true);
    if( readonly ) // need to get exclusive lock
        item_accessor.my_lock.upgrade_to_writer(); // return value means nothing here
    item_accessor.my_lock.release();
    delete_node( n ); // Only one thread can delete it due to write lock on the chain_mutex
    return true;
}

template<typename Key, typename T, typename HashCompare, typename A>
bool concurrent_hash_map<Key,T,HashCompare,A>::erase( const Key &key ) {
    node_base *n;
    hashcode_t const h = my_hash_compare.hash( key );
#if TBB_USE_THREADING_TOOLS
    hashcode_t m = (hashcode_t) itt_load_pointer_with_acquire_v3( &my_mask );
#else
    hashcode_t m = my_mask;
#endif
restart:
    {//lock scope
        // get bucket
        bucket_accessor b( this, h & m );
    search:
        node_base **p = &b()->node_list;
        n = *p;
        while( is_valid(n) && !my_hash_compare.equal(key, static_cast<node*>(n)->item.first ) ) {
            p = &n->next;
            n = *p;
        }
        if( !n ) { // not found, but mask could be changed
            if( check_mask_race( h, m ) )
                goto restart;
            return false;
        }
        else if( !b.is_writer() && !b.upgrade_to_writer() ) {
            if( check_mask_race( h, m ) ) // contended upgrade, check mask
                goto restart;
            goto search;
        }
        *p = n->next;
        my_size--;
    }
    {
        typename node::scoped_t item_locker( n->mutex, /*write=*/true );
    }
    // note: there should be no threads pretending to acquire this mutex again, do not try to upgrade const_accessor!
    delete_node( n ); // Only one thread can delete it due to write lock on the bucket
    return true;
}

template<typename Key, typename T, typename HashCompare, typename A>
void concurrent_hash_map<Key,T,HashCompare,A>::swap(concurrent_hash_map<Key,T,HashCompare,A> &table) {
    std::swap(this->my_allocator, table.my_allocator);
    std::swap(this->my_hash_compare, table.my_hash_compare);
    internal_swap(table);
}

template<typename Key, typename T, typename HashCompare, typename A>
void concurrent_hash_map<Key,T,HashCompare,A>::rehash(size_type sz) {
    reserve( sz ); // TODO: add reduction of number of buckets as well
    hashcode_t mask = my_mask;
    hashcode_t b = (mask+1)>>1; // size or first index of the last segment
    __TBB_ASSERT((b&(b-1))==0, NULL);
    bucket *bp = get_bucket( b ); // only the last segment should be scanned for rehashing
    for(; b <= mask; b++, bp++ ) {
        node_base *n = bp->node_list;
        __TBB_ASSERT( is_valid(n) || n == internal::empty_rehashed || n == internal::rehash_req, "Broken internal structure" );
        __TBB_ASSERT( *reinterpret_cast<intptr_t*>(&bp->mutex) == 0, "concurrent or unexpectedly terminated operation during rehash() execution" );
        if( n == internal::rehash_req ) { // rehash bucket, conditional because rehashing of a previous bucket may affect this one
            hashcode_t h = b; bucket *b_old = bp;
            do {
                __TBB_ASSERT( h > 1, "The lowermost buckets can't be rehashed" );
                hashcode_t m = ( 1u<<__TBB_Log2( h ) ) - 1; // get parent mask from the topmost bit
                b_old = get_bucket( h &= m );
            } while( b_old->node_list == internal::rehash_req );
            // now h - is index of the root rehashed bucket b_old
            mark_rehashed_levels( h ); // mark all non-rehashed children recursively across all segments
            for( node_base **p = &b_old->node_list, *q = *p; is_valid(q); q = *p ) {
                hashcode_t c = my_hash_compare.hash( static_cast<node*>(q)->item.first );
                if( (c & mask) != h ) { // should be rehashed
                    *p = q->next; // exclude from b_old
                    bucket *b_new = get_bucket( c & mask );
                    __TBB_ASSERT( b_new->node_list != internal::rehash_req, "hash() function changed for key in table or internal error" );
                    add_to_bucket( b_new, q );
                } else p = &q->next; // iterate to next item
            }
        }
    }
#if TBB_USE_PERFORMANCE_WARNINGS
    int current_size = int(my_size), buckets = int(mask)+1, empty_buckets = 0, overpopulated_buckets = 0; // usage statistics
    static bool reported = false;
#endif
#if TBB_USE_ASSERT || TBB_USE_PERFORMANCE_WARNINGS
    for( b = 0; b <= mask; b++ ) {// only last segment should be scanned for rehashing
        if( b & (b-2) ) ++bp; // not the beginning of a segment
        else bp = get_bucket( b );
        node_base *n = bp->node_list;
        __TBB_ASSERT( *reinterpret_cast<intptr_t*>(&bp->mutex) == 0, "concurrent or unexpectedly terminated operation during rehash() execution" );
        __TBB_ASSERT( is_valid(n) || n == internal::empty_rehashed, "Broken internal structure" );
#if TBB_USE_PERFORMANCE_WARNINGS
        if( n == internal::empty_rehashed ) empty_buckets++;
        else if( n->next ) overpopulated_buckets++;
#endif
#if TBB_USE_ASSERT
        for( ; is_valid(n); n = n->next ) {
            hashcode_t h = my_hash_compare.hash( static_cast<node*>(n)->item.first ) & mask;
            __TBB_ASSERT( h == b, "hash() function changed for key in table or internal error" );
        }
#endif
    }
#endif // TBB_USE_ASSERT || TBB_USE_PERFORMANCE_WARNINGS
#if TBB_USE_PERFORMANCE_WARNINGS
    if( buckets > current_size) empty_buckets -= buckets - current_size;
    else overpopulated_buckets -= current_size - buckets; // TODO: load_factor?
    if( !reported && buckets >= 512 && ( 2*empty_buckets > current_size || 2*overpopulated_buckets > current_size ) ) {
        tbb::internal::runtime_warning(
            "Performance is not optimal because the hash function produces bad randomness in lower bits in %s.\nSize: %d  Empties: %d  Overlaps: %d",
            typeid(*this).name(), current_size, empty_buckets, overpopulated_buckets );
        reported = true;
    }
#endif
}

template<typename Key, typename T, typename HashCompare, typename A>
void concurrent_hash_map<Key,T,HashCompare,A>::clear() {
    hashcode_t m = my_mask;
    __TBB_ASSERT((m&(m+1))==0, NULL);
#if TBB_USE_ASSERT || TBB_USE_PERFORMANCE_WARNINGS
#if TBB_USE_PERFORMANCE_WARNINGS
    int current_size = int(my_size), buckets = int(m)+1, empty_buckets = 0, overpopulated_buckets = 0; // usage statistics
    static bool reported = false;
#endif
    bucket *bp = 0;
    // check consistency
    for( segment_index_t b = 0; b <= m; b++ ) {
        if( b & (b-2) ) ++bp; // not the beginning of a segment
        else bp = get_bucket( b );
        node_base *n = bp->node_list;
        __TBB_ASSERT( is_valid(n) || n == internal::empty_rehashed || n == internal::rehash_req, "Broken internal structure" );
        __TBB_ASSERT( *reinterpret_cast<intptr_t*>(&bp->mutex) == 0, "concurrent or unexpectedly terminated operation during clear() execution" );
#if TBB_USE_PERFORMANCE_WARNINGS
        if( n == internal::empty_rehashed ) empty_buckets++;
        else if( n == internal::rehash_req ) buckets--;
        else if( n->next ) overpopulated_buckets++;
#endif
#if __TBB_EXTRA_DEBUG
        for(; is_valid(n); n = n->next ) {
            hashcode_t h = my_hash_compare.hash( static_cast<node*>(n)->item.first );
            h &= m;
            __TBB_ASSERT( h == b || get_bucket(h)->node_list == internal::rehash_req, "hash() function changed for key in table or internal error" );
        }
#endif
    }
#if TBB_USE_PERFORMANCE_WARNINGS
    if( buckets > current_size) empty_buckets -= buckets - current_size;
    else overpopulated_buckets -= current_size - buckets; // TODO: load_factor?
    if( !reported && buckets >= 512 && ( 2*empty_buckets > current_size || 2*overpopulated_buckets > current_size ) ) {
        tbb::internal::runtime_warning(
            "Performance is not optimal because the hash function produces bad randomness in lower bits in %s.\nSize: %d  Empties: %d  Overlaps: %d",
            typeid(*this).name(), current_size, empty_buckets, overpopulated_buckets );
        reported = true;
    }
#endif
#endif//TBB_USE_ASSERT || TBB_USE_PERFORMANCE_WARNINGS
    my_size = 0;
    segment_index_t s = segment_index_of( m );
    __TBB_ASSERT( s+1 == pointers_per_table || !my_table[s+1], "wrong mask or concurrent grow" );
    cache_aligned_allocator<bucket> alloc;
    do {
        __TBB_ASSERT( is_valid( my_table[s] ), "wrong mask or concurrent grow" );
        segment_ptr_t buckets_ptr = my_table[s];
        size_type sz = segment_size( s ? s : 1 );
        for( segment_index_t i = 0; i < sz; i++ )
            for( node_base *n = buckets_ptr[i].node_list; is_valid(n); n = buckets_ptr[i].node_list ) {
                buckets_ptr[i].node_list = n->next;
                delete_node( n );
            }
        if( s >= first_block) // the first segment or the next
            alloc.deallocate( buckets_ptr, sz );
        else if( s == embedded_block && embedded_block != first_block )
            alloc.deallocate( buckets_ptr, segment_size(first_block)-embedded_buckets );
        if( s >= embedded_block ) my_table[s] = 0;
    } while(s-- > 0);
    my_mask = embedded_buckets - 1;
}

template<typename Key, typename T, typename HashCompare, typename A>
void concurrent_hash_map<Key,T,HashCompare,A>::internal_copy( const concurrent_hash_map& source ) {
    reserve( source.my_size ); // TODO: load_factor?
    hashcode_t mask = source.my_mask;
    if( my_mask == mask ) { // optimized version
        bucket *dst = 0, *src = 0;
        bool rehash_required = false;
        for( hashcode_t k = 0; k <= mask; k++ ) {
            if( k & (k-2) ) ++dst,src++; // not the beginning of a segment
            else { dst = get_bucket( k ); src = source.get_bucket( k ); }
            __TBB_ASSERT( dst->node_list != internal::rehash_req, "Invalid bucket in destination table");
            node *n = static_cast<node*>( src->node_list );
            if( n == internal::rehash_req ) { // source is not rehashed, items are in previous buckets
                rehash_required = true;
                dst->node_list = internal::rehash_req;
            } else for(; n; n = static_cast<node*>( n->next ) ) {
                add_to_bucket( dst, new( my_allocator ) node(n->item.first, n->item.second) );
                ++my_size; // TODO: replace by non-atomic op
            }
        }
        if( rehash_required ) rehash();
    } else internal_copy( source.begin(), source.end() );
}

template<typename Key, typename T, typename HashCompare, typename A>
template<typename I>
void concurrent_hash_map<Key,T,HashCompare,A>::internal_copy(I first, I last) {
    hashcode_t m = my_mask;
    for(; first != last; ++first) {
        hashcode_t h = my_hash_compare.hash( first->first );
        bucket *b = get_bucket( h & m );
        __TBB_ASSERT( b->node_list != internal::rehash_req, "Invalid bucket in destination table");
        node *n = new( my_allocator ) node(first->first, first->second);
        add_to_bucket( b, n );
        ++my_size; // TODO: replace by non-atomic op
    }
}

} // namespace interface4

using interface4::concurrent_hash_map;


template<typename Key, typename T, typename HashCompare, typename A1, typename A2>
inline bool operator==(const concurrent_hash_map<Key, T, HashCompare, A1> &a, const concurrent_hash_map<Key, T, HashCompare, A2> &b) {
    if(a.size() != b.size()) return false;
    typename concurrent_hash_map<Key, T, HashCompare, A1>::const_iterator i(a.begin()), i_end(a.end());
    typename concurrent_hash_map<Key, T, HashCompare, A2>::const_iterator j, j_end(b.end());
    for(; i != i_end; ++i) {
        j = b.equal_range(i->first).first;
        if( j == j_end || !(i->second == j->second) ) return false;
    }
    return true;
}

template<typename Key, typename T, typename HashCompare, typename A1, typename A2>
inline bool operator!=(const concurrent_hash_map<Key, T, HashCompare, A1> &a, const concurrent_hash_map<Key, T, HashCompare, A2> &b)
{    return !(a == b); }

template<typename Key, typename T, typename HashCompare, typename A>
inline void swap(concurrent_hash_map<Key, T, HashCompare, A> &a, concurrent_hash_map<Key, T, HashCompare, A> &b)
{    a.swap( b ); }

#if _MSC_VER && !defined(__INTEL_COMPILER)
    #pragma warning( pop )
#endif // warning 4127 is back

} // namespace tbb

#endif /* __TBB_concurrent_hash_map_H */
