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
00042 #if !defined( _OESS_1__DB__CLN__SLICE_NONUNIQUE_INDEX_HPP_ )
00043 #define _OESS_1__DB__CLN__SLICE_NONUNIQUE_INDEX_HPP_
00044
00045 #include <map>
00046 #include <iterator>
00047
00048 #include <oess_1/db/h/declspec.hpp>
00049
00050 #include <oess_1/db/cln/h/slice_index_base.hpp>
00051
00052 namespace oess_1
00053 {
00054
00055 namespace db
00056 {
00057
00058 namespace cln
00059 {
00060
00065 template<
00066
00067 class Item,
00068
00069 class Key,
00070
00071 class Key_extractor >
00072 class slice_nonunique_index_t :
00073 public slice_index_base_t
00074 {
00075 private :
00078 typedef std::multimap< Key, oess_1::ent_id_t >
00079 key_map_t;
00080
00083 typedef std::map< oess_1::ent_id_t, Key >
00084 id_map_t;
00085
00087 slice_image_iface_t< Item > * m_slice;
00088
00090 key_map_t m_keys;
00092 id_map_t m_ids;
00093
00095 Key_extractor m_key_extractor;
00096
00097 public :
00099 class iterator
00100 : public std::iterator<
00101 std::forward_iterator_tag,
00102 Item >
00103 {
00104 typedef std::iterator< std::forward_iterator_tag, Item > base_type_t;
00105 private :
00107 typedef typename key_map_t::iterator it_t;
00108
00110 it_t m_it;
00111
00114 slice_image_iface_t< Item > * m_slice;
00115
00117
00121 auto_ptr_3::soft_obj_ptr_t< Item > m_value;
00122
00123 public :
00124 iterator()
00125 :
00126 m_slice( 0 )
00127 {}
00128 iterator(
00129 slice_image_iface_t< Item > * slice,
00130 const it_t & it )
00131 :
00132 m_it( it )
00133 , m_slice( slice )
00134 {}
00135 iterator(
00136 const iterator & o )
00137 : m_it( o.m_it )
00138 , m_slice( o.m_slice )
00139 {}
00140 ~iterator()
00141 {}
00142
00143 iterator &
00144 operator=(
00145 const iterator & o )
00146 {
00147 iterator t( o );
00148 swap( t );
00149 return *this;
00150 }
00151
00152 void
00153 swap( iterator & o )
00154 {
00155 std::swap( m_it, o.m_it );
00156 std::swap( m_slice, o.m_slice );
00157 m_value.swap( o.m_value );
00158 }
00159
00160 typename base_type_t::reference
00161 operator*()
00162 {
00163 if( !m_value.get() )
00164
00165 m_slice->get( m_it->second, m_value );
00166 return *m_value;
00167 }
00168
00169 typename base_type_t::pointer
00170 operator->()
00171 {
00172 if( !m_value.get() )
00173
00174 m_slice->get( m_it->second, m_value );
00175 return m_value.get();
00176 }
00177
00178 iterator &
00179 operator++()
00180 {
00181 m_value.reset();
00182 ++m_it;
00183 return *this;
00184 }
00185
00186 iterator
00187 operator++(int)
00188 {
00189 m_value.reset();
00190 return iterator( m_slice, m_it++ );
00191 }
00192
00193 bool
00194 operator==( const iterator & o ) const
00195 {
00196 return ( m_it == o.m_it );
00197 }
00198
00199 bool
00200 operator!=( const iterator & o ) const
00201 {
00202 return ( m_it != o.m_it );
00203 }
00204
00205 const oess_1::ent_id_t &
00206 id() const
00207 {
00208 return m_it->second;
00209 }
00210 };
00211
00213 class const_iterator
00214 : public std::iterator<
00215 std::forward_iterator_tag,
00216 Item,
00217 ptrdiff_t,
00218 const Item *,
00219 const Item & >
00220 {
00221 private :
00223 typedef typename key_map_t::const_iterator it_t;
00224
00226 it_t m_it;
00227
00230 slice_image_iface_t< Item > * m_slice;
00231
00233
00237 auto_ptr_3::soft_obj_ptr_t< Item > m_value;
00238
00239 public :
00240 typedef const Item * pointer;
00241 typedef const Item & reference;
00242
00243 const_iterator()
00244 :
00245 m_slice( 0 )
00246 {}
00247 const_iterator(
00248 slice_image_iface_t< Item > * slice,
00249 const it_t & it )
00250 :
00251 m_it( it )
00252 , m_slice( slice )
00253 {}
00254 const_iterator(
00255 const const_iterator & o )
00256 : m_it( o.m_it )
00257 , m_slice( o.m_slice )
00258 {}
00259 ~const_iterator()
00260 {}
00261
00262 const_iterator &
00263 operator=(
00264 const const_iterator & o )
00265 {
00266 const_iterator t( o );
00267 swap( t );
00268 return *this;
00269 }
00270
00271 void
00272 swap( const_iterator & o )
00273 {
00274 std::swap( m_it, o.m_it );
00275 std::swap( m_slice, o.m_slice );
00276 m_value.swap( o.m_value );
00277 }
00278
00279 reference
00280 operator*()
00281 {
00282 if( !m_value.get() )
00283
00284 m_slice->get( m_it->second, m_value );
00285 return *m_value;
00286 }
00287
00288 pointer
00289 operator->()
00290 {
00291 if( !m_value.get() )
00292
00293 m_slice->get( m_it->second, m_value );
00294 return m_value.get();
00295 }
00296
00297 const_iterator &
00298 operator++()
00299 {
00300 m_value.reset();
00301 ++m_it;
00302 return *this;
00303 }
00304
00305 const_iterator
00306 operator++(int)
00307 {
00308 m_value.reset();
00309 return const_iterator( m_slice, m_it++ );
00310 }
00311
00312 bool
00313 operator==( const const_iterator & o ) const
00314 {
00315 return ( m_it == o.m_it );
00316 }
00317
00318 bool
00319 operator!=( const const_iterator & o ) const
00320 {
00321 return ( m_it != o.m_it );
00322 }
00323
00324 const oess_1::ent_id_t &
00325 id() const
00326 {
00327 return m_it->second;
00328 }
00329 };
00330
00331 public:
00334 slice_nonunique_index_t(
00335 slice_image_iface_t< Item > & slice,
00337 const Key_extractor & key_extractor,
00340 unsigned int attach_flags = 0 )
00341 :
00342 m_slice( &slice )
00343 , m_key_extractor( key_extractor )
00344 {
00345 m_slice->attach( *this, attach_flags );
00346 }
00347 virtual ~slice_nonunique_index_t()
00348 {}
00349
00351 iterator
00352 begin()
00353 {
00354 return iterator( m_slice, m_keys.begin() );
00355 }
00356
00358 const_iterator
00359 begin() const
00360 {
00361 return const_iterator( m_slice, m_keys.begin() );
00362 }
00363
00365 iterator
00366 end()
00367 {
00368 return iterator( m_slice, m_keys.end() );
00369 }
00370
00372 const_iterator
00373 end() const
00374 {
00375 return const_iterator( m_slice, m_keys.end() );
00376 }
00377
00379
00383 iterator
00384 find( const Key & o )
00385 {
00386 return iterator( m_slice, m_keys.find( o ) );
00387 }
00388
00390
00394 const_iterator
00395 find( const Key & o ) const
00396 {
00397 return const_iterator( m_slice, m_keys.find( o ) );
00398 }
00399
00401
00405 iterator
00406 lower_bound( const Key & o )
00407 {
00408 return iterator( m_slice, m_keys.lower_bound( o ) );
00409 }
00410
00412
00416 const_iterator
00417 lower_bound( const Key & o ) const
00418 {
00419 return const_iterator( m_slice, m_keys.lower_bound( o ) );
00420 }
00421
00423
00427 iterator
00428 upper_bound( const Key & o )
00429 {
00430 return iterator( m_slice, m_keys.upper_bound( o ) );
00431 }
00432
00434
00438 const_iterator
00439 upper_bound( const Key & o ) const
00440 {
00441 return const_iterator( m_slice, m_keys.upper_bound( o ) );
00442 }
00443
00445
00449 void
00450 erase( const iterator & it )
00451 {
00452 if( it != end() )
00453 {
00454
00455
00456
00457
00458
00459 oess_1::ent_id_t id_for_erasing = it.id();
00460 m_slice->erase( id_for_erasing );
00461 }
00462 }
00463
00465
00471 void
00472 erase( const Key & o )
00473 {
00474
00475
00476
00477 iterator it = find( o );
00478 while( it != end() )
00479 {
00480 erase( it );
00481 it = find( o );
00482 }
00483 }
00484
00486 unsigned int
00487 size() const
00488 {
00489 return m_keys.size();
00490 }
00491
00496 virtual void
00497 on_clear()
00498 {
00499 m_keys.clear();
00500 m_ids.clear();
00501 }
00502
00507 virtual void
00508 on_insert(
00509 const oess_1::ent_id_t & id,
00510 const oess_1::stdsn::serializable_t & o )
00511 {
00512 const Item & real_obj = dynamic_cast< const Item & >( o );
00513 Key k( m_key_extractor( real_obj ) );
00514
00515 insert_pair( k, id );
00516 m_ids[ id ] = k;
00517 }
00518
00520 virtual void
00521 on_erase(
00522 const oess_1::ent_id_t & id )
00523 {
00524 typename id_map_t::iterator it_id( m_ids.find( id ) );
00525 if( it_id != m_ids.end() )
00526 {
00527 remove_pair( it_id->second, id );
00528 m_ids.erase( it_id );
00529 }
00530 }
00531
00533 virtual void
00534 on_update(
00535 const oess_1::ent_id_t & id,
00536 const oess_1::stdsn::serializable_t & o )
00537 {
00538 typename id_map_t::iterator it_id( m_ids.find( id ) );
00539 if( it_id != m_ids.end() )
00540 {
00541 const Item & real_obj = dynamic_cast< const Item & >( o );
00542 Key k( m_key_extractor( real_obj ) );
00543
00544 if( k < it_id->second || k > it_id->second )
00545 {
00546 remove_pair( it_id->second, id );
00547 insert_pair( k, id );
00548 it_id->second = k;
00549 }
00550 }
00551 }
00552
00554 virtual void
00555 on_attach()
00556 {
00557
00558 }
00559
00561 virtual void
00562 on_detach()
00563 {
00564
00565 m_keys.clear();
00566 m_ids.clear();
00567 m_slice = 0;
00568 }
00569
00572 private :
00574 void
00575 insert_pair(
00576 const Key & k,
00577 const oess_1::ent_id_t & id )
00578 {
00579 m_keys.insert( typename key_map_t::value_type( k, id ) );
00580 }
00581
00583 void
00584 remove_pair(
00585 const Key & k,
00586 const oess_1::ent_id_t & id )
00587 {
00588 for( typename key_map_t::iterator it = m_keys.lower_bound( k ),
00589 it_end = m_keys.upper_bound( k );
00590 it != it_end; ++it )
00591 if( it->second == id )
00592 {
00593 m_keys.erase( it );
00594 return;
00595 }
00596 }
00597 };
00598
00599 }
00600
00601 }
00602
00603 }
00604
00605 #endif
00606