Ticket #5787: optimize_multi_index.patch

File optimize_multi_index.patch, 16.7 KB (added by voznesensky@…, 11 years ago)

Patch to optimize hashed_non_unique index of multi_index

  • boost_1_47_0/boost/multi_index/detail/bucket_array.hpp

    diff -N -dur --strip-trailing-cr old/boost_1_47_0/boost/multi_index/detail/bucket_array.hpp new/boost_1_47_0/boost/multi_index/detail/bucket_array.hpp
    old new  
    1616#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
    1717#include <algorithm>
    1818#include <boost/multi_index/detail/auto_space.hpp>
    19 #include <boost/multi_index/detail/hash_index_node.hpp>
     19//#include <boost/multi_index/detail/hash_index_node.hpp>
     20//#include <boost/multi_index/detail/hash_index_dbl_node.hpp>
    2021#include <boost/multi_index/detail/prevent_eti.hpp>
    2122#include <boost/noncopyable.hpp>
    2223#include <cstddef>
     
    8283  }
    8384};
    8485
    85 template<typename Allocator>
     86template<typename Allocator, typename NodeImpl>
    8687class bucket_array:public bucket_array_base
    8788{
    88   typedef typename prevent_eti<
    89     Allocator,
    90     hashed_index_node_impl<
    91       typename boost::detail::allocator::rebind_to<
    92         Allocator,
    93         char
    94       >::type
    95     >
    96   >::type                                           node_impl_type;
     89  typedef typename prevent_eti<Allocator,NodeImpl>::type
     90                                                    node_impl_type;
    9791
    9892public:
    9993  typedef typename node_impl_type::pointer          pointer;
     
    164158#endif
    165159};
    166160
    167 template<typename Allocator>
    168 void swap(bucket_array<Allocator>& x,bucket_array<Allocator>& y)
     161template<typename Allocator, typename NodeImpl>
     162void swap(bucket_array<Allocator,NodeImpl>& x,
     163  bucket_array<Allocator,NodeImpl>& y)
    169164{
    170165  x.swap(y);
    171166}
     
    188183namespace detail{
    189184#endif
    190185
    191 template<class Archive,typename Allocator>
     186template<class Archive,typename Allocator,typename NodeImpl>
    192187inline void load_construct_data(
    193   Archive&,boost::multi_index::detail::bucket_array<Allocator>*,
     188  Archive&,boost::multi_index::detail::bucket_array<Allocator,NodeImpl>*,
    194189  const unsigned int)
    195190{
    196191  throw_exception(
  • boost_1_47_0/boost/multi_index/detail/hash_index_dbl_node.hpp

    diff -N -dur --strip-trailing-cr old/boost_1_47_0/boost/multi_index/detail/hash_index_dbl_node.hpp new/boost_1_47_0/boost/multi_index/detail/hash_index_dbl_node.hpp
    old new  
     1/* Copyright 2003-2008 Joaquin M Lopez Munoz.
     2 * Distributed under the Boost Software License, Version 1.0.
     3 * (See accompanying file LICENSE_1_0.txt or copy at
     4 * http://www.boost.org/LICENSE_1_0.txt)
     5 *
     6 * See http://www.boost.org/libs/multi_index for library home page.
     7 */
     8
     9#ifndef BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_DBL_NODE_HPP
     10#define BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_DBL_NODE_HPP
     11
     12#if defined(_MSC_VER)&&(_MSC_VER>=1200)
     13#pragma once
     14#endif
     15
     16#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
     17#include <boost/detail/allocator_utilities.hpp>
     18#include <boost/multi_index/detail/prevent_eti.hpp>
     19#include <functional>
     20
     21namespace boost{
     22
     23namespace multi_index{
     24
     25namespace detail{
     26
     27/* double-linked node for use by hashed_index */
     28
     29template<typename Allocator>
     30struct hashed_index_dbl_node_impl
     31{
     32  typedef typename prevent_eti<
     33    Allocator,
     34    typename boost::detail::allocator::rebind_to<
     35      Allocator,hashed_index_dbl_node_impl
     36    >::type
     37  >::type::pointer                                pointer;
     38  typedef typename prevent_eti<
     39    Allocator,
     40    typename boost::detail::allocator::rebind_to<
     41      Allocator,hashed_index_dbl_node_impl
     42    >::type
     43  >::type::const_pointer                          const_pointer;
     44
     45  pointer& next(){return next_;}
     46  pointer  next()const{return next_;}
     47  pointer& prev(){return prev_;}
     48  pointer  prev()const{return prev_;}
     49
     50  /* algorithmic stuff */
     51
     52  static void increment(pointer& x,pointer bbegin,pointer bend)
     53  {
     54    std::less_equal<pointer> leq;
     55
     56    x=x->next();
     57    if(leq(bbegin,x)&&leq(x,bend)){ /* bucket node */
     58      do{
     59        ++x;
     60      }while(x->next()==x);
     61      x=x->next();
     62    }
     63  }
     64
     65  static void link(pointer x,pointer pos)
     66  {
     67    x->next()=pos->next();
     68    pos->next()=x;
     69    x->prev()=pos;
     70    x->next()->prev()=x;
     71  };
     72
     73  static void unlink(pointer x)
     74  {
     75    x->prev()->next()=x->next();
     76    x->next()->prev()=x->prev();
     77  }
     78
     79  static pointer prev(pointer x)
     80  {
     81    return x->prev();
     82  }
     83
     84  static void unlink_next(pointer x)
     85  {
     86    x->next()=x->next()->next();
     87    x->next()->prev()=x;
     88  }
     89
     90private:
     91  pointer next_;
     92  pointer prev_;
     93};
     94
     95template<typename Super>
     96struct hashed_index_dbl_node_trampoline:
     97  prevent_eti<
     98    Super,
     99    hashed_index_dbl_node_impl<
     100      typename boost::detail::allocator::rebind_to<
     101        typename Super::allocator_type,
     102        char
     103      >::type
     104    >
     105  >::type
     106{
     107  typedef typename prevent_eti<
     108    Super,
     109    hashed_index_dbl_node_impl<
     110      typename boost::detail::allocator::rebind_to<
     111        typename Super::allocator_type,
     112        char
     113      >::type
     114    >
     115  >::type impl_type;
     116};
     117
     118template<typename Super>
     119struct hashed_index_dbl_node:Super,hashed_index_dbl_node_trampoline<Super>
     120{
     121private:
     122  typedef hashed_index_dbl_node_trampoline<Super> trampoline;
     123
     124public:
     125  typedef typename trampoline::impl_type     impl_type;
     126  typedef typename trampoline::pointer       impl_pointer;
     127  typedef typename trampoline::const_pointer const_impl_pointer;
     128
     129  impl_pointer impl()
     130  {
     131    return static_cast<impl_pointer>(
     132      static_cast<impl_type*>(static_cast<trampoline*>(this)));
     133  }
     134
     135  const_impl_pointer impl()const
     136  {
     137    return static_cast<const_impl_pointer>(
     138      static_cast<const impl_type*>(static_cast<const trampoline*>(this)));
     139  }
     140
     141  static hashed_index_dbl_node* from_impl(impl_pointer x)
     142  {
     143    return static_cast<hashed_index_dbl_node*>(
     144      static_cast<trampoline*>(&*x));
     145  }
     146
     147  static const hashed_index_dbl_node* from_impl(const_impl_pointer x)
     148  {
     149    return static_cast<const hashed_index_dbl_node*>(
     150      static_cast<const trampoline*>(&*x));
     151  }
     152
     153  static void increment(
     154    hashed_index_dbl_node*& x,impl_pointer bbegin,impl_pointer bend)
     155  {
     156    impl_pointer xi=x->impl();
     157    trampoline::increment(xi,bbegin,bend);
     158    x=from_impl(xi);
     159  }
     160};
     161
     162} /* namespace multi_index::detail */
     163
     164} /* namespace multi_index */
     165
     166} /* namespace boost */
     167
     168#endif
  • boost_1_47_0/boost/multi_index/hashed_index.hpp

    diff -N -dur --strip-trailing-cr old/boost_1_47_0/boost/multi_index/hashed_index.hpp new/boost_1_47_0/boost/multi_index/hashed_index.hpp
    old new  
    1 /* Copyright 2003-2011 Joaquin M Lopez Munoz.
     1/* Copyright 2003-2010 Joaquin M Lopez Munoz.
    22 * Distributed under the Boost Software License, Version 1.0.
    33 * (See accompanying file LICENSE_1_0.txt or copy at
    44 * http://www.boost.org/LICENSE_1_0.txt)
     
    2626#include <boost/multi_index/detail/bucket_array.hpp>
    2727#include <boost/multi_index/detail/hash_index_iterator.hpp>
    2828#include <boost/multi_index/detail/index_node_base.hpp>
     29#include <boost/multi_index/detail/hash_index_node.hpp>
     30#include <boost/multi_index/detail/hash_index_dbl_node.hpp>
    2931#include <boost/multi_index/detail/modify_key_adaptor.hpp>
    3032#include <boost/multi_index/detail/safe_ctr_proxy.hpp>
    3133#include <boost/multi_index/detail/safe_mode.hpp>
     
    6769
    6870template<
    6971  typename KeyFromValue,typename Hash,typename Pred,
    70   typename SuperMeta,typename TagList,typename Category
     72  typename SuperMeta,typename TagList,typename Category,
     73  template <typename> class NodeType
    7174>
    7275class hashed_index:
    7376  BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type
     
    7679#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
    7780  ,public safe_ctr_proxy_impl<
    7881    hashed_index_iterator<
    79       hashed_index_node<typename SuperMeta::type::node_type>,
    80       bucket_array<typename SuperMeta::type::final_allocator_type> >,
    81     hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category> >
     82      NodeType<typename SuperMeta::type::node_type>,
     83      bucket_array<
     84        typename SuperMeta::type::final_allocator_type,
     85        typename NodeType<typename SuperMeta::type::node_type>::impl_type
     86      >
     87    >,
     88    hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category,
     89      NodeType<typename SuperMeta::type::node_type> > >
    8290#else
    8391  ,public safe_mode::safe_container<
    84     hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category> >
     92    hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category,
     93      NodeType<typename SuperMeta::type::node_type> > >
    8594#endif
    8695#endif
    8796
     
    99108  typedef typename SuperMeta::type                   super;
    100109
    101110protected:
    102   typedef hashed_index_node<
    103     typename super::node_type>                       node_type;
     111  typedef NodeType<
     112    typename SuperMeta::type::node_type>             node_type;
    104113
    105114private:
    106115  typedef typename node_type::impl_type              node_impl_type;
    107116  typedef typename node_impl_type::pointer           node_impl_pointer;
    108117  typedef bucket_array<
    109     typename super::final_allocator_type>            bucket_array_type;
     118    typename super::final_allocator_type,
     119    typename NodeType<node_type>::impl_type
     120  >                                                  bucket_array_type;
    110121
    111122public:
    112123  /* types */
     
    196207   * not supposed to be created on their own. No range ctor either.
    197208   */
    198209
    199   hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& operator=(
    200     const hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x)
     210  hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category,NodeType>&
     211    operator=(const hashed_index<
     212      KeyFromValue,Hash,Pred,SuperMeta,TagList,Category,NodeType>& x)
    201213  {
    202214    this->final()=x.final();
    203215    return *this;
     
    405417    this->final_clear_();
    406418  }
    407419
    408   void swap(hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x)
     420  void swap(hashed_index<
     421    KeyFromValue,Hash,Pred,SuperMeta,TagList,Category,NodeType>& x)
    409422  {
    410423    BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT;
    411424    this->final_swap_(x.final());
     
    605618    hash(tuples::get<2>(args_list.get_head())),
    606619    eq(tuples::get<3>(args_list.get_head())),
    607620    buckets(al,header()->impl(),tuples::get<0>(args_list.get_head())),
    608     mlf(1.0f),
     621    mlf(1.0),
    609622    first_bucket(buckets.size())
    610623  {
    611624    calculate_max_load();
    612625  }
    613626
    614   hashed_index(
    615     const hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x):
     627  hashed_index(const hashed_index<
     628      KeyFromValue,Hash,Pred,SuperMeta,TagList,Category,NodeType>& x):
    616629    super(x),
    617630
    618631#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
     
    663676#endif
    664677
    665678  void copy_(
    666     const hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x,
     679    const hashed_index<
     680      KeyFromValue,Hash,Pred,SuperMeta,TagList,Category,NodeType>& x,
    667681    const copy_map_type& map)
    668682  {
    669683    for(node_impl_pointer begin_org=x.buckets.begin(),
     
    757771  }
    758772
    759773  void swap_(
    760     hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x)
     774    hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category,NodeType>& x)
    761775  {
    762776    std::swap(key,x.key);
    763777    std::swap(hash,x.hash);
     
    10941108    node_impl_pointer                  bend=buckets.end();
    10951109    node_impl_pointer                  pbuc=x->next();
    10961110
    1097     while(!leq(bbegin,pbuc)||!leq(pbuc,bend))pbuc=pbuc->next();
     1111    /*while(!leq(bbegin,pbuc)||!leq(pbuc,bend))pbuc=pbuc->next();*/
     1112    if(!leq(bbegin,pbuc)||!leq(pbuc,bend))
     1113      pbuc = buckets.at(buckets.position(
     1114        hash(key(node_type::from_impl(pbuc)->value()))));
    10981115    if(buc!=static_cast<std::size_t>(pbuc-bbegin))return false;
    10991116
    11001117    node_impl_pointer y=x;
     
    11151132    node_impl_pointer                  bend=buckets.end();
    11161133    node_impl_pointer                  pbuc=x->next();
    11171134
    1118     while(!leq(bbegin,pbuc)||!leq(pbuc,bend))pbuc=pbuc->next();
     1135    /*while(!leq(bbegin,pbuc)||!leq(pbuc,bend))pbuc=pbuc->next();*/
     1136    if(!leq(bbegin,pbuc)||!leq(pbuc,bend))
     1137      pbuc = buckets.at(buckets.position(
     1138        hash(key(node_type::from_impl(pbuc)->value()))));
    11191139    if(buc!=static_cast<std::size_t>(pbuc-bbegin))return false;
    1120 
     1140   
    11211141    node_impl_pointer y=x->next();
    11221142    if(y!=pbuc){
    11231143      if(eq(k,key(node_type::from_impl(y)->value()))){
     
    11731193
    11741194template<
    11751195  typename KeyFromValue,typename Hash,typename Pred,
    1176   typename SuperMeta,typename TagList,typename Category
     1196  typename SuperMeta,typename TagList,typename Category,
     1197  template <class> class NodeType
    11771198>
    11781199void swap(
    1179   hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x,
    1180   hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& y)
     1200  hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category,NodeType>& x,
     1201  hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category,NodeType>& y)
    11811202{
    11821203  x.swap(y);
    11831204}
     
    12071228  {
    12081229    typedef detail::hashed_index<
    12091230      key_from_value_type,hash_type,pred_type,
    1210       SuperMeta,tag_list_type,detail::hashed_unique_tag> type;
     1231      SuperMeta,tag_list_type,detail::hashed_unique_tag,
     1232      detail::hashed_index_node> type;
    12111233  };
    12121234};
    12131235
     
    12321254  {
    12331255    typedef detail::hashed_index<
    12341256      key_from_value_type,hash_type,pred_type,
    1235       SuperMeta,tag_list_type,detail::hashed_non_unique_tag> type;
     1257      SuperMeta,tag_list_type,detail::hashed_non_unique_tag,
     1258      detail::hashed_index_node> type;
     1259  };
     1260};
     1261
     1262template<typename Arg1,typename Arg2,typename Arg3,typename Arg4>
     1263struct hashed_dbl_unique
     1264{
     1265  typedef typename detail::hashed_index_args<
     1266    Arg1,Arg2,Arg3,Arg4>                           index_args;
     1267  typedef typename index_args::tag_list_type::type tag_list_type;
     1268  typedef typename index_args::key_from_value_type key_from_value_type;
     1269  typedef typename index_args::hash_type           hash_type;
     1270  typedef typename index_args::pred_type           pred_type;
     1271
     1272  template<typename Super>
     1273  struct node_class
     1274  {
     1275    typedef detail::hashed_index_dbl_node<Super> type;
     1276  };
     1277
     1278  template<typename SuperMeta>
     1279  struct index_class
     1280  {
     1281    typedef detail::hashed_index<
     1282      key_from_value_type,hash_type,pred_type,
     1283      SuperMeta,tag_list_type,detail::hashed_unique_tag,
     1284      detail::hashed_index_dbl_node> type;
     1285  };
     1286};
     1287
     1288template<typename Arg1,typename Arg2,typename Arg3,typename Arg4>
     1289struct hashed_dbl_non_unique
     1290{
     1291  typedef typename detail::hashed_index_args<
     1292    Arg1,Arg2,Arg3,Arg4>                           index_args;
     1293  typedef typename index_args::tag_list_type::type tag_list_type;
     1294  typedef typename index_args::key_from_value_type key_from_value_type;
     1295  typedef typename index_args::hash_type           hash_type;
     1296  typedef typename index_args::pred_type           pred_type;
     1297
     1298  template<typename Super>
     1299  struct node_class
     1300  {
     1301    typedef detail::hashed_index_dbl_node<Super> type;
     1302  };
     1303
     1304  template<typename SuperMeta>
     1305  struct index_class
     1306  {
     1307    typedef detail::hashed_index<
     1308      key_from_value_type,hash_type,pred_type,
     1309      SuperMeta,tag_list_type,detail::hashed_non_unique_tag,
     1310      detail::hashed_index_dbl_node> type;
    12361311  };
    12371312};
    12381313
  • boost_1_47_0/boost/multi_index/hashed_index_fwd.hpp

    diff -N -dur --strip-trailing-cr old/boost_1_47_0/boost/multi_index/hashed_index_fwd.hpp new/boost_1_47_0/boost/multi_index/hashed_index_fwd.hpp
    old new  
    2323
    2424template<
    2525  typename KeyFromValue,typename Hash,typename Pred,
    26   typename SuperMeta,typename TagList,typename Category
     26  typename SuperMeta,typename TagList,typename Category,
     27  template <class> class NodeType
    2728>
    2829class hashed_index;
    2930
    3031template<
    3132  typename KeyFromValue,typename Hash,typename Pred,
    32   typename SuperMeta,typename TagList,typename Category
     33  typename SuperMeta,typename TagList,typename Category,
     34  template <class> class NodeType
    3335>
    3436void swap(
    35   hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x,
    36   hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& y);
     37  hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category,NodeType>& x,
     38  hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category,NodeType>& y);
    3739
    3840} /* namespace multi_index::detail */
    3941
     
    5153>
    5254struct hashed_non_unique;
    5355
     56template<
     57  typename Arg1,typename Arg2=mpl::na,
     58  typename Arg3=mpl::na,typename Arg4=mpl::na
     59>
     60struct hashed_dbl_unique;
     61
     62template<
     63  typename Arg1,typename Arg2=mpl::na,
     64  typename Arg3=mpl::na,typename Arg4=mpl::na
     65>
     66struct hashed_dbl_non_unique;
     67
    5468} /* namespace multi_index */
    5569
    5670} /* namespace boost */