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_INDEX_HPP_ )
00043 #define _OESS_1__DB__CLN__SLICE_INDEX_HPP_
00044
00045 #include <map>
00046
00047 #include <oess_1/db/h/declspec.hpp>
00048
00049 #include <oess_1/db/cln/h/slice_index_base.hpp>
00050
00051 namespace oess_1
00052 {
00053
00054 namespace db
00055 {
00056
00057 namespace cln
00058 {
00059
00064 template<
00065
00066 class Item,
00067
00068 class Key,
00069
00070 class Key_extractor >
00071 class slice_index_t :
00072 public slice_index_base_t
00073 {
00074 private :
00077 typedef std::map< Key, oess_1::ent_id_t >
00078 key_map_t;
00079
00082 typedef std::map< oess_1::ent_id_t, Key >
00083 id_map_t;
00084
00086 slice_image_iface_t< Item > * m_slice;
00087
00089 key_map_t m_keys;
00091 id_map_t m_ids;
00092
00094 Key_extractor m_key_extractor;
00095
00096 public :
00098 class iterator
00099 {
00100 private :
00102 typedef typename key_map_t::iterator it_t;
00103
00105 it_t m_it;
00106
00109 slice_image_iface_t< Item > * m_slice;
00110
00112
00116 auto_ptr_3::soft_obj_ptr_t< Item > m_value;
00117
00118 public :
00119 typedef Item * pointer;
00120 typedef Item & reference;
00121
00122 iterator()
00123 :
00124 m_slice( 0 )
00125 {}
00126 iterator(
00127 slice_image_iface_t< Item > * slice,
00128 const it_t & it )
00129 :
00130 m_it( it )
00131 , m_slice( slice )
00132 {}
00133 iterator(
00134 const iterator & o )
00135 {
00136 (*this) = o;
00137 }
00138 ~iterator()
00139 {}
00140
00141 iterator &
00142 operator=(
00143 const iterator & o )
00144 {
00145 if( &o != this )
00146 {
00147 m_value.reset();
00148 m_it = o.m_it;
00149 m_slice = o.m_slice;
00150 }
00151 return *this;
00152 }
00153
00154 reference
00155 operator*()
00156 {
00157 if( !m_value.get() )
00158
00159 m_slice->get( m_it->second, m_value );
00160 return *m_value;
00161 }
00162
00163 pointer
00164 operator->()
00165 {
00166 if( !m_value.get() )
00167
00168 m_slice->get( m_it->second, m_value );
00169 return m_value.get();
00170 }
00171
00172 iterator &
00173 operator++()
00174 {
00175 m_value.reset();
00176 ++m_it;
00177 return *this;
00178 }
00179
00180 iterator
00181 operator++(int)
00182 {
00183 m_value.reset();
00184 return iterator( m_slice, m_it++ );
00185 }
00186
00187 bool
00188 operator==( const iterator & o ) const
00189 {
00190 return ( m_it == o.m_it );
00191 }
00192
00193 bool
00194 operator!=( const iterator & o ) const
00195 {
00196 return ( m_it != o.m_it );
00197 }
00198
00199 const oess_1::ent_id_t &
00200 id() const
00201 {
00202 return m_it->second;
00203 }
00204 };
00205
00207 class const_iterator
00208 {
00209 private :
00211 typedef typename key_map_t::const_iterator it_t;
00212
00214 it_t m_it;
00215
00218 slice_image_iface_t< Item > * m_slice;
00219
00221
00225 auto_ptr_3::soft_obj_ptr_t< Item > m_value;
00226
00227 public :
00228 typedef const Item * pointer;
00229 typedef const Item & reference;
00230
00231 const_iterator()
00232 :
00233 m_slice( 0 )
00234 {}
00235 const_iterator(
00236 slice_image_iface_t< Item > * slice,
00237 const it_t & it )
00238 :
00239 m_it( it )
00240 , m_slice( slice )
00241 {}
00242 const_iterator(
00243 const const_iterator & o )
00244 {
00245 (*this) = o;
00246 }
00247 ~const_iterator()
00248 {}
00249
00250 const_iterator &
00251 operator=(
00252 const const_iterator & o )
00253 {
00254 if( &o != this )
00255 {
00256 m_value.reset();
00257 m_it = o.m_it;
00258 m_slice = o.m_slice;
00259 }
00260 return *this;
00261 }
00262
00263 reference
00264 operator*()
00265 {
00266 if( !m_value.get() )
00267
00268 m_slice->get( m_it->second, m_value );
00269 return *m_value;
00270 }
00271
00272 pointer
00273 operator->()
00274 {
00275 if( !m_value.get() )
00276
00277 m_slice->get( m_it->second, m_value );
00278 return m_value.get();
00279 }
00280
00281 const_iterator &
00282 operator++()
00283 {
00284 m_value.reset();
00285 ++m_it;
00286 return *this;
00287 }
00288
00289 const_iterator
00290 operator++(int)
00291 {
00292 m_value.reset();
00293 return const_iterator( m_slice, m_it++ );
00294 }
00295
00296 bool
00297 operator==( const const_iterator & o ) const
00298 {
00299 return ( m_it == o.m_it );
00300 }
00301
00302 bool
00303 operator!=( const const_iterator & o ) const
00304 {
00305 return ( m_it != o.m_it );
00306 }
00307
00308 const oess_1::ent_id_t &
00309 id() const
00310 {
00311 return m_it->second;
00312 }
00313 };
00314
00315 public:
00318 slice_index_t(
00319 slice_image_iface_t< Item > & slice,
00321 const Key_extractor & key_extractor,
00324 unsigned int attach_flags = 0 )
00325 :
00326 m_slice( &slice )
00327 , m_key_extractor( key_extractor )
00328 {
00329 m_slice->attach( *this, attach_flags );
00330 }
00331 virtual ~slice_index_t()
00332 {}
00333
00335 iterator
00336 begin()
00337 {
00338 return iterator( m_slice, m_keys.begin() );
00339 }
00340
00342 const_iterator
00343 begin() const
00344 {
00345 return const_iterator( m_slice, m_keys.begin() );
00346 }
00347
00349 iterator
00350 end()
00351 {
00352 return iterator( m_slice, m_keys.end() );
00353 }
00354
00356 const_iterator
00357 end() const
00358 {
00359 return const_iterator( m_slice, m_keys.end() );
00360 }
00361
00363
00367 iterator
00368 find( const Key & o )
00369 {
00370 return iterator( m_slice, m_keys.find( o ) );
00371 }
00372
00374
00378 const_iterator
00379 find( const Key & o ) const
00380 {
00381 return const_iterator( m_slice, m_keys.find( o ) );
00382 }
00383
00385
00389 iterator
00390 lower_bound( const Key & o )
00391 {
00392 return iterator( m_slice, m_keys.lower_bound( o ) );
00393 }
00394
00396
00400 const_iterator
00401 lower_bound( const Key & o ) const
00402 {
00403 return const_iterator( m_slice, m_keys.lower_bound( o ) );
00404 }
00405
00407
00411 iterator
00412 upper_bound( const Key & o )
00413 {
00414 return iterator( m_slice, m_keys.upper_bound( o ) );
00415 }
00416
00418
00422 const_iterator
00423 upper_bound( const Key & o ) const
00424 {
00425 return const_iterator( m_slice, m_keys.upper_bound( o ) );
00426 }
00427
00429
00433 void
00434 erase( const iterator & it )
00435 {
00436 if( it != end() )
00437 {
00438
00439
00440
00441
00442
00443 oess_1::ent_id_t id_for_erasing = it.id();
00444 m_slice->erase( id_for_erasing );
00445 }
00446 }
00447
00449
00453 void
00454 erase( const Key & o )
00455 {
00456 erase( find( o ) );
00457 }
00458
00460
00463 unsigned int
00464 size() const
00465 {
00466 return m_keys.size();
00467 }
00468
00473 virtual void
00474 on_clear()
00475 {
00476 m_keys.clear();
00477 m_ids.clear();
00478 }
00479
00484 virtual void
00485 on_insert(
00486 const oess_1::ent_id_t & id,
00487 const oess_1::stdsn::serializable_t & o )
00488 {
00489 const Item & real_obj = dynamic_cast< const Item & >( o );
00490 Key k( m_key_extractor( real_obj ) );
00491
00492 m_keys[ k ] = id;
00493 m_ids[ id ] = k;
00494 }
00495
00497 virtual void
00498 on_erase(
00499 const oess_1::ent_id_t & id )
00500 {
00501 typename id_map_t::iterator it_id( m_ids.find( id ) );
00502 if( it_id != m_ids.end() )
00503 {
00504 m_keys.erase( it_id->second );
00505 m_ids.erase( it_id );
00506 }
00507 }
00508
00510 virtual void
00511 on_update(
00512 const oess_1::ent_id_t & id,
00513 const oess_1::stdsn::serializable_t & o )
00514 {
00515 typename id_map_t::iterator it_id( m_ids.find( id ) );
00516 if( it_id != m_ids.end() )
00517 {
00518 const Item & real_obj = dynamic_cast< const Item & >( o );
00519 Key k( m_key_extractor( real_obj ) );
00520
00521
00522 m_keys.erase( it_id->second );
00523
00524 m_keys[ k ] = id;
00525 it_id->second = k;
00526 }
00527 }
00528
00530 virtual void
00531 on_attach()
00532 {
00533
00534 }
00535
00537 virtual void
00538 on_detach()
00539 {
00540
00541 m_keys.clear();
00542 m_ids.clear();
00543 m_slice = 0;
00544 }
00545
00547 };
00548
00549 }
00550
00551 }
00552
00553 }
00554
00555 #endif