00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #ifndef SETASSOC_TABLE_H
00053 #define SETASSOC_TABLE_H
00054
00055 #include <stdexcept>
00056 #include <algorithm>
00057 #include <functional>
00058 #include <cassert>
00059 #include <vector>
00060 #include <map>
00061
00062
00063 #include "shttl_types.h"
00064 #include "std_hasher.h"
00065 #include "lru.h"
00066 #include "nlu.h"
00067
00068
00069 namespace shttl
00070 {
00071
00072
00073 template < typename BodyType, typename BodyPtrType, typename LineType >
00074 class setassoc_table_iterator_base
00075 {
00076 public:
00077
00078 typedef BodyType body_type;
00079 typedef BodyPtrType body_ptr_type;
00080 typedef LineType line_type;
00081 typedef typename body_type::size_type size_type;
00082
00083 static const size_type invalid_index = body_type::invalid_index;
00084 static const size_type invalid_way = body_type::invalid_way;
00085
00086 setassoc_table_iterator_base(
00087 body_ptr_type body = NULL,
00088 size_type index = invalid_index,
00089 size_type way = invalid_way
00090 ) :
00091 m_body ( body ),
00092 m_index( index ),
00093 m_way ( way )
00094 {
00095 }
00096
00097 size_type way() const
00098 {
00099 return m_way;
00100 }
00101
00102 size_type index() const
00103 {
00104 return m_index;
00105 }
00106
00107
00108 const body_type* body() const
00109 {
00110 return m_body;
00111 }
00112
00113 bool operator != ( const setassoc_table_iterator_base& rhs ) const
00114 {
00115 return !((*this) == rhs);
00116 }
00117
00118 bool operator == ( const setassoc_table_iterator_base& rhs ) const
00119 {
00120 return
00121 ( m_body == rhs.m_body ) &&
00122 ( m_index == rhs.m_index ) &&
00123 ( m_way == rhs.m_way );
00124 }
00125
00126
00127 setassoc_table_iterator_base& operator++()
00128 {
00129 SHTTL_ASSERT( m_index < m_body->set_num() );
00130 SHTTL_ASSERT( m_way < m_body->way_num() );
00131 m_way++;
00132 if( m_way == m_body->way_num() ){
00133 m_way = 0;
00134 m_index++;
00135 }
00136 return *this;
00137 }
00138
00139
00140 setassoc_table_iterator_base operator++(int)
00141 {
00142 setassoc_table_iterator_base tmp = *this;
00143 ++*this;
00144 return tmp;
00145 }
00146
00147 line_type* operator->()
00148 {
00149 return &m_body->at( *this );
00150 }
00151
00152 line_type& operator*()
00153 {
00154 return m_body->at( *this );
00155 }
00156
00157 protected:
00158
00159 body_ptr_type m_body;
00160 size_type m_index;
00161 size_type m_way;
00162
00163 };
00164
00165
00166 template <
00167 typename BodyType,
00168 typename BodyPtrType,
00169 typename LineType,
00170 typename IteratorType
00171 >
00172 class setassoc_table_const_iterator_base :
00173 public setassoc_table_iterator_base< BodyType, BodyPtrType, LineType >
00174 {
00175
00176 public:
00177
00178 typedef
00179 setassoc_table_iterator_base<
00180 BodyType,
00181 BodyPtrType,
00182 LineType
00183 >
00184 base_type;
00185
00186 typedef
00187 setassoc_table_const_iterator_base<
00188 BodyType,
00189 BodyPtrType,
00190 LineType,
00191 IteratorType
00192 >
00193 this_type;
00194
00195 typedef IteratorType iterator;
00196 typedef typename base_type::body_ptr_type body_ptr_type;
00197 typedef typename base_type::size_type size_type;
00198 typedef typename base_type::line_type line_type;
00199
00200
00201 setassoc_table_const_iterator_base(
00202 body_ptr_type body = NULL,
00203 size_type index = base_type::invalid_index,
00204 size_type way = base_type::invalid_way
00205 ) : base_type( body, index, way )
00206 {
00207 }
00208
00209 setassoc_table_const_iterator_base(
00210 const iterator &ref
00211 ) :
00212 base_type( ref.body(), ref.index(), ref.way() )
00213 {
00214 }
00215
00216 bool operator != ( const this_type& rhs ) const
00217 {
00218 return *static_cast<const base_type*>(this) != rhs;
00219 }
00220
00221 bool operator == ( const this_type& rhs ) const
00222 {
00223 return *static_cast<const base_type*>(this) == rhs;
00224 }
00225
00226 line_type* operator->()
00227 {
00228 return &m_body->at( *this );
00229 }
00230
00231 line_type& operator*()
00232 {
00233 return m_body->at( *this );
00234 }
00235
00236 protected:
00237 using base_type::m_body;
00238
00239 };
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 template <
00251 typename line_type,
00252 typename strage_type
00253 >
00254 class setassoc_table_set_vector
00255 {
00256
00257 public:
00258
00259 typedef typename strage_type::size_type size_type;
00260 typedef typename line_type::tag_type tag_type;
00261 typedef typename line_type::value_type value_type;
00262
00263 static const size_type invalid_index = strage_type::invalid_index;
00264 static const size_type invalid_way = strage_type::invalid_way;
00265
00266 setassoc_table_set_vector(
00267 strage_type* lines,
00268 size_type way_num,
00269 size_type offset
00270 ) :
00271 m_strage ( lines ),
00272 m_way_num( way_num ),
00273 m_offset ( offset )
00274 {
00275 }
00276
00277
00278 inline size_type find( const tag_type tag ) const
00279 {
00280 for( size_type w = 0; w < m_way_num; w++ ){
00281 const line_type& line = at( w );
00282 if( line.tag == tag && line.valid ){
00283 return w;
00284 }
00285 }
00286 return invalid_way;
00287 }
00288
00289
00290 size_type find_free_way() const
00291 {
00292 for( size_type w = 0; w < m_way_num; w++ ){
00293 if( !at( w ).valid )
00294 return w;
00295 }
00296 return invalid_way;
00297 }
00298
00299
00300 void invalidate( const size_type way )
00301 {
00302 if( way == invalid_way )
00303 return;
00304
00305 assert_valid_way( way );
00306 at( way ).valid = false;
00307 }
00308
00309
00310 bool read( size_type way, line_type* line ) const
00311 {
00312 if( way == invalid_way )
00313 return false;
00314
00315 assert_valid_way( way );
00316 if( line ){
00317 *line = at( way );
00318 }
00319 return at( way ).valid;
00320 }
00321
00322 void write(
00323 const size_type way,
00324 const tag_type tag,
00325 const value_type &val = value_type()
00326 ){
00327 if(way == invalid_way)
00328 return;
00329
00330 assert_valid_way(way);
00331
00332
00333 SHTTL_ASSERT( find(tag) == invalid_way || find( tag ) == way );
00334
00335
00336 at( way ) = line_type( tag, val, true );
00337 }
00338
00339
00340 void clear()
00341 {
00342 for( size_type w = 0; w < m_way_num; w++ ){
00343 at( w ).valid = false;
00344 }
00345 }
00346
00347 line_type& at( size_type way )
00348 {
00349 return m_strage->at( way + m_offset );
00350 }
00351
00352 const line_type& at( size_type way ) const
00353 {
00354 return m_strage->at( way + m_offset );
00355 }
00356
00357 protected:
00358
00359 strage_type* m_strage;
00360 size_type m_way_num;
00361 size_type m_offset;
00362
00363 void assert_valid_way( size_type way ) const
00364 {
00365 SHTTL_ASSERT( 0 <= way && way < m_way_num );
00366 }
00367
00368 };
00369
00370 template < typename line_type >
00371 class setassoc_table_strage_vector
00372 {
00373 public:
00374
00375 typedef setassoc_table_strage_vector< line_type > this_type;
00376 typedef size_t size_type;
00377 typedef std::vector<line_type> strage_type;
00378
00379 typedef setassoc_table_set_vector<
00380 line_type,
00381 this_type
00382 > set_type;
00383
00384 typedef setassoc_table_set_vector<
00385 const line_type,
00386 const this_type
00387 > const_set_type;
00388
00389 static const size_type invalid_index = ~((size_type)0);
00390 static const size_type invalid_way = ~((size_type)0);
00391
00392 line_type& at( size_type index )
00393 {
00394 return m_body.at( index );
00395 }
00396
00397 const line_type& at( size_type index ) const
00398 {
00399 return m_body.at( index );
00400 }
00401
00402 set_type get_set( size_type index )
00403 {
00404 size_type offset = index*m_way_num;
00405 return set_type(
00406 this,
00407 m_way_num,
00408 offset
00409 );
00410 }
00411
00412 const_set_type get_set( size_type index ) const
00413 {
00414 size_type offset = index*m_way_num;
00415 return const_set_type(
00416 this,
00417 m_way_num,
00418 offset
00419 );
00420 }
00421
00422 void resize( size_type set_num, size_type way_num )
00423 {
00424 m_set_num = set_num;
00425 m_way_num = way_num;
00426 m_body.resize( set_num*way_num, line_type() );
00427 }
00428
00429 protected:
00430
00431 size_type m_set_num;
00432 size_type m_way_num;
00433 strage_type m_body;
00434
00435 };
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446 template <
00447 typename line_type,
00448 typename strage_type
00449 >
00450 class setassoc_table_set_map
00451 {
00452
00453 public:
00454
00455 typedef typename strage_type::size_type size_type;
00456 typedef typename line_type::key_type tag_type;
00457 typedef typename line_type::value_type value_type;
00458
00459 typedef typename strage_type::line_map_type line_map_type;
00460 typedef typename strage_type::invalid_map_type invalid_map_type;
00461
00462 static const size_type invalid_index = strage_type::invalid_index;
00463 static const size_type invalid_way = strage_type::invalid_way;
00464
00465 setassoc_table_set_map(
00466 strage_type* lines,
00467 size_type way_num,
00468 size_type index,
00469 size_type offset
00470 ) :
00471 m_strage ( lines ),
00472 m_way_num( way_num ),
00473 m_index ( index ),
00474 m_offset ( offset )
00475 {
00476 }
00477
00478
00479 size_type find( const tag_type tag ) const
00480 {
00481 line_map_type& strage_set = m_strage->get_line_map( m_index );
00482 typename line_map_type::iterator strage_line = strage_set.find( tag );
00483
00484 size_type found = invalid_way;
00485 if( strage_line != strage_set.end() && strage_line->second->valid ){
00486 found =
00487 strage_line->second - m_strage->get_set_strage_iterator( m_index );
00488 }
00489
00490 #ifdef SHTTL_SET_ASSOC_TABLE_VALIDATE_STRAGE_MAP
00491 size_type linear_found = invalid_way;
00492 for( size_type w = 0; w < m_way_num; w++ ){
00493 const line_type& line = at( w );
00494 if( line.key == tag && line.valid ){
00495 linear_found = w;
00496 break;
00497 }
00498 }
00499 SHTTL_ASSERT( linear_found == found );
00500 #endif
00501
00502 return found;
00503 }
00504
00505
00506 size_type find_free_way() const
00507 {
00508
00509 invalid_map_type& invalid_set = m_strage->get_invalid_map( m_index );
00510 typename invalid_map_type::iterator invalid_line = invalid_set.begin();
00511 size_type found = invalid_way;
00512 if( invalid_line != invalid_set.end() ){
00513 found = invalid_line->second;
00514 }
00515
00516 #ifdef SHTTL_SET_ASSOC_TABLE_VALIDATE_STRAGE_MAP
00517 size_type linear_found = invalid_way;
00518 for( size_type w = 0; w < m_way_num; w++ ){
00519 if( !at( w ).valid ){
00520 linear_found = w;
00521 break;
00522 }
00523 }
00524 SHTTL_ASSERT( linear_found == found );
00525 #endif
00526
00527 return found;
00528 }
00529
00530
00531 void invalidate( const size_type way )
00532 {
00533 if( way == invalid_way )
00534 return;
00535
00536 assert_valid_way( way );
00537 at( way ).valid = false;
00538
00539 m_strage->get_invalid_map( m_index )[ way ] = way;
00540 }
00541
00542 bool read( size_type way, line_type* line ) const
00543 {
00544 if( way == invalid_way )
00545 return false;
00546
00547 assert_valid_way( way );
00548 if( line ){
00549 *line = at( way );
00550 }
00551 return at( way ).valid;
00552 }
00553
00554 void write(
00555 const size_type way,
00556 const tag_type tag,
00557 const value_type &val = value_type()
00558 ){
00559 if(way == invalid_way)
00560 return;
00561
00562 assert_valid_way(way);
00563
00564
00565 SHTTL_ASSERT( find(tag) == invalid_way || find( tag ) == way );
00566
00567
00568 typename strage_type::strage_type::iterator line =
00569 m_strage->get_set_strage_iterator( m_index ) + way;
00570
00571 line_map_type& strage_set = m_strage->get_line_map( m_index );
00572 typename line_map_type::iterator old_line = strage_set.find( at( way ).key );
00573 if( old_line->second == line ){
00574 strage_set.erase( old_line );
00575 }
00576
00577 at( way ) = line_type( tag, val, true );
00578
00579 strage_set[ tag ] = line;
00580 m_strage->get_invalid_map( m_index ).erase( way );
00581 }
00582
00583
00584 void clear()
00585 {
00586 for( size_type way = 0; way < m_way_num; way++ ){
00587 at( way ).valid = false;
00588
00589 m_strage->get_invalid_map( m_index )[ way ] = way;
00590 }
00591 }
00592
00593 line_type& at( size_type way )
00594 {
00595 return m_strage->at( way + m_offset );
00596 }
00597
00598 const line_type& at( size_type way ) const
00599 {
00600 return m_strage->at( way + m_offset );
00601 }
00602
00603 protected:
00604
00605 strage_type* m_strage;
00606 size_type m_way_num;
00607 size_type m_index;
00608 size_type m_offset;
00609
00610 void assert_valid_way( size_type way ) const
00611 {
00612 SHTTL_ASSERT( 0 <= way && way < m_way_num );
00613 }
00614
00615 };
00616
00617 template < typename line_type >
00618 class setassoc_table_strage_map
00619 {
00620 public:
00621
00622 typedef setassoc_table_strage_map< line_type > this_type;
00623 typedef size_t size_type;
00624 typedef std::vector<line_type> strage_type;
00625
00626 typedef typename line_type::key_type key_type;
00627 typedef typename line_type::value_type value_type;
00628
00629 typedef
00630 setassoc_table_set_map<
00631 line_type,
00632 this_type
00633 >
00634 set_type;
00635
00636 typedef
00637 setassoc_table_set_map<
00638 const line_type,
00639 const this_type
00640 >
00641 const_set_type;
00642
00643 typedef
00644 std::map<
00645 key_type,
00646 typename strage_type::iterator
00647 >
00648 line_map_type;
00649
00650 typedef
00651 std::map<
00652 size_type,
00653 size_type
00654 >
00655 invalid_map_type;
00656
00657 static const size_type invalid_index = ~((size_type)0);
00658 static const size_type invalid_way = ~((size_type)0);
00659
00660 line_type& at( size_type index )
00661 {
00662 return m_body.at( index );
00663 }
00664
00665 const line_type& at( size_type index ) const
00666 {
00667 return m_body.at( index );
00668 }
00669
00670 set_type get_set( size_type index )
00671 {
00672 size_type offset = index*m_way_num;
00673 return set_type(
00674 this,
00675 m_way_num,
00676 index,
00677 offset
00678 );
00679 }
00680
00681 const_set_type get_set( size_type index ) const
00682 {
00683 size_type offset = index*m_way_num;
00684 return const_set_type(
00685 this,
00686 m_way_num,
00687 index,
00688 offset
00689 );
00690 }
00691
00692 line_map_type& get_line_map( size_type index ){
00693 return m_line_map[ index ];
00694 }
00695
00696 invalid_map_type& get_invalid_map( size_type index ){
00697 return m_invalid_map[ index ];
00698 }
00699
00700 typename strage_type::iterator get_set_strage_iterator( size_type index )
00701 {
00702 return m_body.begin() + index * m_way_num;
00703 }
00704
00705 void resize( size_type set_num, size_type way_num )
00706 {
00707 m_set_num = set_num;
00708 m_way_num = way_num;
00709
00710 m_body.clear();
00711 m_body.resize( set_num*way_num, line_type() );
00712
00713 m_line_map.clear();
00714 m_line_map.resize( set_num );
00715
00716 m_invalid_map.clear();
00717 m_invalid_map.resize( set_num );
00718
00719 for( size_type index = 0; index < set_num; index++ ){
00720
00721 set_type set = get_set( index );
00722 line_map_type& set_line_map = m_line_map[ index ];
00723 invalid_map_type& set_invalid_map = m_invalid_map[ index ];
00724 typename strage_type::iterator set_iterator = get_set_strage_iterator( index );
00725
00726
00727 for( size_type way = 0; way < way_num; way++ ){
00728 line_type& line = set.at( way );
00729 if( line.valid ){
00730 set_line_map[ line.key ] = set_iterator + way;
00731 }
00732 else{
00733 set_invalid_map[ way ] = way;
00734 }
00735 }
00736
00737 }
00738 }
00739
00740 protected:
00741
00742 size_type m_set_num;
00743 size_type m_way_num;
00744
00745 strage_type m_body;
00746
00747
00748
00749
00750 struct line_map_allocator : public std::allocator<line_map_type>
00751 {
00752 };
00753 struct invalid_map_allocator : public std::allocator<invalid_map_type>
00754 {
00755 };
00756 std::vector< line_map_type, line_map_allocator > m_line_map;
00757 std::vector< invalid_map_type, invalid_map_allocator > m_invalid_map;
00758
00759 };
00760
00761
00762 template < typename PairType >
00763 struct setassoc_table_line_base
00764 {
00765 typedef typename PairType::first_type tag_type;
00766 typedef typename PairType::second_type value_type;
00767
00768 tag_type tag;
00769 value_type value;
00770 bool valid;
00771
00772 setassoc_table_line_base(
00773 const tag_type& tag_arg = tag_type(),
00774 const value_type& value_arg = value_type(),
00775 const bool& valid_arg = false
00776 ) :
00777 tag ( tag_arg ),
00778 value( value_arg ),
00779 valid( valid_arg )
00780 {
00781 }
00782 };
00783
00784
00785
00786
00787
00788 template<
00789 typename PairType,
00790 typename Hasher = std_hasher< typename PairType::first_type >,
00791 typename Replacer = lru< typename PairType::first_type >,
00792 typename Strage =
00793 setassoc_table_strage_vector<
00794 setassoc_table_line_base< PairType >
00795 >
00796 >
00797 class setassoc_table
00798 {
00799 public:
00800
00801
00802
00803 typedef
00804 setassoc_table< PairType, Hasher, Replacer, Strage >
00805 this_type;
00806
00807 typedef PairType pair_type;
00808 typedef Hasher hasher_type;
00809 typedef Replacer replacer_type;
00810 typedef Strage strage_type;
00811
00812 typedef typename pair_type::first_type key_type;
00813 typedef typename pair_type::second_type value_type;
00814 typedef typename hasher_type::size_type hasher_size_type;
00815
00816 typedef typename strage_type::set_type set_type;
00817 typedef typename strage_type::const_set_type const_set_type;
00818 typedef typename strage_type::size_type size_type;
00819
00820 static const size_type invalid_index = strage_type::invalid_index;
00821 static const size_type invalid_way = strage_type::invalid_way;
00822
00823 typedef
00824 setassoc_table_line_base< pair_type >
00825 line_type;
00826
00827
00828 typedef
00829 setassoc_table_iterator_base<
00830 this_type,
00831 this_type*,
00832 line_type
00833 >
00834 iterator;
00835
00836 typedef
00837 setassoc_table_const_iterator_base<
00838 this_type,
00839 const this_type*,
00840 const line_type,
00841 iterator
00842 >
00843 const_iterator;
00844
00845
00846
00847
00848 size_type set_num() const
00849 {
00850 return (size_type)m_hasher.size();
00851 }
00852
00853 size_type way_num() const
00854 {
00855 return m_way_num;
00856 }
00857
00858
00859 size_type size() const
00860 {
00861 return set_num() * way_num();
00862 }
00863
00864
00865
00866 setassoc_table(
00867 const hasher_type &hasher,
00868 const size_type way_num
00869 ) :
00870 m_replacer(),
00871 m_hasher ( hasher ),
00872 m_way_num ( way_num )
00873 {
00874 m_replacer.construct( hasher.size(), way_num );
00875 m_strage.resize( hasher.size(), way_num );
00876 }
00877
00878 ~setassoc_table()
00879 {
00880 }
00881
00882
00883 iterator find( const key_type key )
00884 {
00885 hasher_size_type index = m_hasher.index( key );
00886 key_type tag = m_hasher.tag( key );
00887
00888 const set_type& set = m_strage.get_set( (size_type)index );
00889 size_type way = set.find( tag );
00890 if( way != invalid_way )
00891 return iterator( this, index, way );
00892 else
00893 return end();
00894 }
00895
00896
00897 iterator read( const key_type key, value_type* val = NULL )
00898 {
00899 iterator id = find( key );
00900
00901
00902 if( id != end() ){
00903 if( val ){
00904 *val = at( id ).value;
00905 }
00906 touch( id, key );
00907 }
00908
00909 return id;
00910 }
00911
00912
00913 iterator write(
00914 const key_type key,
00915 const value_type &val = value_type(),
00916 bool* ref_replaced = NULL,
00917 key_type* ref_replaced_key = NULL,
00918 line_type* ref_replaced_line = NULL
00919 ){
00920 hasher_size_type key_index = index( key );
00921 set_type set = m_strage.get_set( key_index );
00922 bool replaced = false;
00923
00924
00925 iterator id = find( key );
00926 if( id == end() ){
00927
00928
00929 size_type way = set.find_free_way();
00930
00931
00932 if( way == invalid_way ){
00933 way = m_replacer.target( key_index );
00934 replaced = true;
00935 }
00936
00937 id = iterator( this, key_index, way );
00938 }
00939
00940 if( ref_replaced ){
00941 *ref_replaced = replaced;
00942 }
00943
00944 if( replaced && ref_replaced_line ){
00945 *ref_replaced_line = set.at( id.way() );
00946 }
00947
00948 if( replaced && ref_replaced_key ){
00949 *ref_replaced_key = m_hasher.rebuild( ref_replaced_line->tag, id.index() );
00950 }
00951
00952 key_type tag = m_hasher.tag( key );
00953 set.write( id.way(), tag, val );
00954
00955 touch( id, key );
00956 return id;
00957 }
00958
00959
00960 iterator invalidate( const key_type key )
00961 {
00962 iterator id = find( key );
00963 if( id != end() && at(id).valid ){
00964 m_strage.get_set( id.index() ).invalidate( id.way() );
00965 }
00966 return id;
00967 }
00968
00969 void touch( iterator id, const key_type key )
00970 {
00971 m_replacer.touch( id.index(), id.way(), key );
00972 }
00973
00974 void clear()
00975 {
00976 for( size_type i = 0; i < set_num(); i++ ){
00977 m_strage.get_set( i ).clear();
00978 }
00979 }
00980
00981 hasher_size_type index( const key_type key ) const
00982 {
00983 return m_hasher.index( key );
00984 }
00985
00986
00987
00988
00989 line_type& at( iterator id )
00990 {
00991 return m_strage.get_set( id.index() ).at( id.way() );
00992 };
00993
00994 const line_type& at( const_iterator id ) const
00995 {
00996 return m_strage.get_set( id.index() ).at( id.way() );
00997 };
00998
00999 iterator begin()
01000 {
01001 return iterator( this, 0, 0 );
01002 }
01003
01004 iterator end()
01005 {
01006 return iterator( this, set_num(), 0 );
01007 }
01008
01009 const_iterator begin() const
01010 {
01011 return const_iterator( this, 0, 0 );
01012 }
01013
01014 const_iterator end() const
01015 {
01016 return const_iterator( this, set_num(), 0 );
01017 }
01018
01019 iterator begin_set( hasher_size_type index )
01020 {
01021 return iterator( this, index, 0 );
01022 }
01023
01024 iterator end_set( hasher_size_type index )
01025 {
01026 return iterator( this, index+1, 0 );
01027 }
01028
01029 const_iterator begin_set( hasher_size_type index ) const
01030 {
01031 return const_iterator( this, index, 0 );
01032 }
01033
01034 const_iterator end_set( hasher_size_type index ) const
01035 {
01036 return const_iterator( this, index+1, 0 );
01037 }
01038
01039
01040
01041
01042
01043 replacer_type& get_replacer()
01044 {
01045 return m_replacer;
01046 };
01047
01048 hasher_type& get_hasher()
01049 {
01050 return m_hasher;
01051 }
01052
01053
01054 protected:
01055
01056 replacer_type m_replacer;
01057 hasher_type m_hasher;
01058 size_type m_way_num;
01059
01060 strage_type m_strage;
01061
01062
01063 setassoc_table(
01064 const setassoc_table& ref
01065 )
01066 {
01067 }
01068
01069
01070 };
01071
01072 }
01073
01074 #endif // SETASSOC_TABLE_H