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 #include <iostream>
00033 #include <fstream>
00034 #include <cerrno>
00035 #include <cstring>
00036 #include <cstdlib>
00037 #include <cstdio>
00038
00039 #include <time.h>
00040
00041 #include <map>
00042 #include <string>
00043
00044 #include <auto_ptr_3/h/obj_ptr.hpp>
00045
00046 #include <oess_1/defs/h/ex.hpp>
00047
00048 #include <oess_1/stdsn/h/inout_templ.hpp>
00049
00050 #include <oess_1/db/cln/h/local_db.hpp>
00051
00052 using namespace std;
00053
00054
00055
00056
00057 class app_data_t :
00058 public oess_1::stdsn::serializable_t
00059 {
00060 OESS_SERIALIZER( app_data_t )
00061 public :
00062 app_data_t();
00063 app_data_t(
00064 const std::string & s );
00065 app_data_t(
00066 const app_data_t & o );
00067 virtual ~app_data_t();
00068
00069 app_data_t &
00070 operator=(
00071 const app_data_t & o );
00072
00073 const std::string &
00074 query_data() const;
00075
00076 void
00077 set_data( const std::string & s );
00078
00079 private :
00080 std::string m_data;
00081 };
00082
00083 app_data_t::app_data_t()
00084 {
00085 }
00086
00087 app_data_t::app_data_t(
00088 const std::string & s ) :
00089 m_data( s )
00090 {
00091 }
00092
00093 app_data_t::app_data_t(
00094 const app_data_t & o )
00095 {
00096 (*this) = o;
00097 }
00098
00099 app_data_t::~app_data_t()
00100 {
00101 }
00102
00103 app_data_t &
00104 app_data_t::operator=(
00105 const app_data_t & o )
00106 {
00107 if( &o != this ) {
00108 m_data = o.m_data;
00109 }
00110
00111 return *this;
00112 }
00113
00114 const std::string &
00115 app_data_t::query_data() const
00116 {
00117 return m_data;
00118 }
00119
00120 void
00121 app_data_t::set_data( const std::string & s )
00122 {
00123 m_data = s;
00124 }
00125
00126
00127
00128
00129 class recovery_data_t :
00130 public oess_1::stdsn::serializable_t
00131 {
00132 OESS_SERIALIZER( recovery_data_t )
00133 public :
00134 recovery_data_t();
00135 recovery_data_t(
00136 const app_data_t & app_data,
00137 oess_1::uint_t & live_time );
00138 recovery_data_t(
00139 const recovery_data_t & o );
00140 virtual ~recovery_data_t();
00141
00142 recovery_data_t &
00143 operator=(
00144 const recovery_data_t & o );
00145
00146
00147 oess_1::uint_t
00148 decrement_live_time(
00149 oess_1::uint_t delta );
00150
00151 private :
00152 app_data_t m_app_data;
00153 oess_1::uint_t m_live_time;
00154 oess_1::uint_t m_time_to_death;
00155 };
00156
00157 recovery_data_t::recovery_data_t() :
00158 m_live_time( 0 ),
00159 m_time_to_death( 0 )
00160 {
00161 }
00162
00163 recovery_data_t::recovery_data_t(
00164 const app_data_t & app_data,
00165 oess_1::uint_t & live_time ) :
00166 m_app_data( app_data ),
00167 m_live_time( live_time ),
00168 m_time_to_death( live_time )
00169 {
00170 }
00171
00172 recovery_data_t::recovery_data_t(
00173 const recovery_data_t & o ) :
00174 m_live_time( 0 ),
00175 m_time_to_death( 0 )
00176 {
00177 (*this) = o;
00178 }
00179
00180 recovery_data_t::~recovery_data_t()
00181 {
00182 }
00183
00184 recovery_data_t &
00185 recovery_data_t::operator=(
00186 const recovery_data_t & o )
00187 {
00188 if( &o != this ) {
00189 m_app_data = o.m_app_data;
00190 m_live_time = o.m_live_time;
00191 m_time_to_death = o.m_time_to_death;
00192 }
00193
00194 return *this;
00195 }
00196
00197 oess_1::uint_t
00198 recovery_data_t::decrement_live_time(
00199 oess_1::uint_t delta )
00200 {
00201 if( delta > m_time_to_death )
00202 delta = m_time_to_death;
00203
00204 return ( m_time_to_death -= delta );
00205 }
00206
00207 #include "main.ddl.cpp"
00208
00209
00210
00211
00212 class app_t {
00213 public :
00214 app_t(
00215
00216 oess_1::db::cln::db_t * db,
00217 const std::string & slice_name );
00218 ~app_t();
00219
00220 void
00221 next_work_time(
00222 oess_1::uint_t delta );
00223
00224 enum {
00225 e_max_obj_count = 5000,
00226 e_max_live_time = 5
00227 };
00228
00229 private :
00230 typedef std::map< oess_1::ent_id_t, recovery_data_t >
00231 recovery_data_map_t;
00232
00233 oess_1::db::cln::db_t * m_db_ptr;
00234 std::string m_slice_name;
00235
00236 recovery_data_map_t m_contents;
00237
00238 void
00239 process_loaded_data(
00240 oess_1::uint_t delta );
00241
00242 void
00243 create_new_objects();
00244 };
00245
00246 app_t::app_t(
00247 oess_1::db::cln::db_t * db,
00248 const std::string & slice_name )
00249 : m_db_ptr( db )
00250 , m_slice_name( slice_name )
00251 {
00252 m_db_ptr->slice_create( slice_name );
00253
00254 std::cout << "Load DB content..." << std::endl;
00255 oess_1::ent_id_t ent_id;
00256 do
00257 {
00258 ent_id = m_db_ptr->ent_find_next( m_slice_name, ent_id );
00259 if( ent_id )
00260 {
00261 recovery_data_t d;
00262 m_db_ptr->ent_load( ent_id, d );
00263
00264 m_contents.insert( recovery_data_map_t::
00265 value_type( ent_id, d ) );
00266
00267
00268 }
00269 } while( ent_id );
00270
00271 std::cout << "\nDB content loaded: "
00272 << m_contents.size() << std::endl;
00273 }
00274
00275 app_t::~app_t()
00276 {
00277 }
00278
00279 void
00280 app_t::next_work_time(
00281 oess_1::uint_t delta )
00282 {
00283 clock_t s = clock(), f;
00284
00285 process_loaded_data( delta );
00286
00287 f = clock();
00288 std::cout << "\ntime 1: "
00289 << ((double)( f - s )) / CLOCKS_PER_SEC
00290 << "\n" << std::endl;
00291 s = f;
00292
00293 create_new_objects();
00294
00295 f = clock();
00296 std::cout << "\ntime 2: "
00297 << ((double)( f - s )) / CLOCKS_PER_SEC
00298 << "\n" << std::endl;
00299
00300 std::cout << "Capacity: " << m_contents.size() << std::endl;
00301
00302 }
00303
00304 void
00305 app_t::process_loaded_data(
00306 oess_1::uint_t delta )
00307 {
00308 std::cout << "remove processed data... " << std::flush;
00309 unsigned int removed_objs = 0;
00310
00311
00312
00313 for( recovery_data_map_t::iterator
00314 it = m_contents.begin();
00315 it != m_contents.end(); ) {
00316 recovery_data_t & d = (*it).second;
00317
00318 if( !d.decrement_live_time( delta ) ) {
00319 const oess_1::ent_id_t & id = (*it).first;
00320
00321
00322 m_db_ptr->ent_destroy( id );
00323 m_contents.erase( it++ );
00324
00325 ++removed_objs;
00326 }
00327 else
00328 ++it;
00329 }
00330
00331
00332
00333 std::cout << removed_objs << std::endl;
00334 }
00335
00336 void
00337 app_t::create_new_objects()
00338 {
00339 int obj_to_create = 0;
00340 if( m_contents.size() < e_max_obj_count )
00341 {
00342 obj_to_create = e_max_obj_count - m_contents.size();
00343 obj_to_create = ( rand() % obj_to_create );
00344 }
00345
00346 std::cout << "Create new " << obj_to_create
00347 << " object(s)..." << std::flush;
00348
00349
00350
00351 char sz_app_data[ 32 ];
00352 for( int i = 0; i != obj_to_create; ++i ) {
00353 sprintf( sz_app_data, "app_data #%d", i );
00354
00355 oess_1::uint_t live_time = 1 + ( rand() % e_max_live_time );
00356
00357 app_data_t app_data( sz_app_data );
00358 recovery_data_t d( app_data, live_time );
00359
00360 oess_1::ent_id_t ent_id = m_db_ptr->ent_create(
00361 m_slice_name, d );
00362
00363 m_contents.insert( recovery_data_map_t::
00364 value_type( ent_id, d ) );
00365
00366
00367 }
00368
00369
00370
00371 std::cout << std::endl;
00372 }
00373
00374 int
00375 main( int, char ** ) {
00376 try {
00377 const std::string phys_db_name( "./sample/app_recovery/db" );
00378
00379 oess_1::db::cln::local_db_t db( phys_db_name,
00380 oess_1::db::storage::load_cfg_file(
00381 "./sample/app_recovery/template.cfg" ) );
00382
00383 app_t app( db.query_db(), "slice_1" );
00384
00385 for( int i = 0; i != 15; ++i )
00386 {
00387 app.next_work_time( 1 );
00388 }
00389
00390 return 0;
00391 }
00392 catch( oess_1::ex_t & x ) {
00393 std::cerr << "*** " << x.query_err_code() << " ***"
00394 << std::endl;
00395 }
00396 catch( const std::exception & x ) {
00397 std::cerr << "### " << x.what() << " ###" << std::endl;
00398 }
00399 catch( ... ) {
00400 std::cerr << "Oops! Unknown exception!" << std::endl;
00401 }
00402
00403 return 1;
00404
00405 }