sample/app_recovery/main.cpp

00001 /*
00002 
00003 Copyright (c) 2002-2005, Yauheni Akhotnikau
00004 All rights reserved.
00005 
00006 Redistribution and use in source and binary forms, with or without
00007 modification, are permitted provided that the following conditions are met:
00008 
00009 - Redistributions of source code must retain the above copyright notice, this
00010 list of conditions and the following disclaimer.
00011 
00012 - Redistributions in binary form must reproduce the above copyright notice, this
00013 list of conditions and the following disclaimer in the documentation and/or
00014 other materials provided with the distribution.
00015 
00016 - The name of the author may not be used to endorse or promote products derived
00017 from this software without specific prior written permission.
00018 
00019 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
00020 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00021 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
00022 EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00023 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00024 OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00026 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
00027 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
00028 OF SUCH DAMAGE.
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 // app_data_t
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 // recovery_data_t
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     // Возвращает 0, если время жизни истекло
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 // app_t
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, //50000,
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 //        std::cout << ent_id << " ";
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 //  oess_1::db::cln::transaction_t trx( *m_db_ptr );
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 //      std::cout << id << " ";
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 //  trx.commit();
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 //  oess_1::db::cln::transaction_t trx( *m_db_ptr );
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 //    std::cout << "[" << ent_id << ", " << live_time << "] ";
00367   }
00368 
00369 //  trx.commit();
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 }

Документация по ObjESSty. Последние изменения: Fri Oct 13 18:35:35 2006. Создано системой  doxygen 1.4.7
Hosted by uCoz