[complement-svn] SF.net SVN: complement: [1639] trunk/complement/explore/test/virtual_time
Status: Pre-Alpha
Brought to you by:
complement
From: <com...@us...> - 2007-07-25 06:55:40
|
Revision: 1639 http://complement.svn.sourceforge.net/complement/?rev=1639&view=rev Author: complement Date: 2007-07-24 23:55:38 -0700 (Tue, 24 Jul 2007) Log Message: ----------- more information checked within unit test; evolution of VTDispatch Modified Paths: -------------- trunk/complement/explore/test/virtual_time/test/unit_test.cc trunk/complement/explore/test/virtual_time/vtime.cc trunk/complement/explore/test/virtual_time/vtime.h Modified: trunk/complement/explore/test/virtual_time/test/unit_test.cc =================================================================== --- trunk/complement/explore/test/virtual_time/test/unit_test.cc 2007-07-24 07:49:03 UTC (rev 1638) +++ trunk/complement/explore/test/virtual_time/test/unit_test.cc 2007-07-25 06:55:38 UTC (rev 1639) @@ -449,15 +449,16 @@ vtime_obj_rec ob; const group_type gr0 = 0; - const group_type gr1 = 0; + const group_type gr1 = 1; + const group_type gr2 = 2; const oid_type obj0 = 0; const oid_type obj1 = 1; const oid_type obj2 = 2; ob.add_group( gr0 ); - ob.add_group_member( gr0, obj0 ); - ob.add_group_member( gr0, obj1 ); - ob.add_group_member( gr0, obj2 ); + // ob.add_group_member( gr0, obj0 ); + // ob.add_group_member( gr0, obj1 ); + // ob.add_group_member( gr0, obj2 ); // gvtime gvt; // gvt[gr0][obj1] = 1; @@ -471,12 +472,30 @@ mess_bad.grp = mess.grp = gr0; mess_bad.mess = mess.mess = "data"; - EXAM_CHECK( ob.deliver(mess) ); // ack + // cerr << ob.vt[gr0] << endl; + // cerr << "===========\n"; + vtime chk; + + EXAM_REQUIRE( (chk <= ob.vt[gr0]) && (chk >= ob.vt[gr0]) ); + + EXAM_REQUIRE( ob.deliver(mess) ); // ack + + chk[obj1] += 1; + + EXAM_REQUIRE( (chk <= ob.vt[gr0]) && (chk >= ob.vt[gr0]) ); + + // cerr << ob.vt[gr0] << endl; + // cerr << "===========\n"; + ++mess.gvt[gr0][obj1]; - EXAM_CHECK( ob.deliver(mess) ); // ack + EXAM_REQUIRE( ob.deliver(mess) ); // ack + chk[obj1] += 1; + + EXAM_REQUIRE( (chk <= ob.vt[gr0]) && (chk >= ob.vt[gr0]) ); + ++mess.gvt[gr0][obj1]; try { @@ -484,16 +503,25 @@ EXAM_ERROR( "exception expected" ); } catch ( const out_of_range& ) { + EXAM_REQUIRE( (chk <= ob.vt[gr0]) && (chk >= ob.vt[gr0]) ); } mess_bad.gvt[gr0][obj1] = mess.gvt[gr0][obj1] + 1; - EXAM_CHECK( !ob.deliver(mess_bad) ); // nac: too new (out of order) + EXAM_REQUIRE( !ob.deliver(mess_bad) ); // nac: too new (out of order) - EXAM_CHECK( ob.deliver(mess) ); // ack + EXAM_REQUIRE( (chk <= ob.vt[gr0]) && (chk >= ob.vt[gr0]) ); + EXAM_REQUIRE( ob.deliver(mess) ); // ack + + chk[obj1] += 1; + EXAM_REQUIRE( (chk <= ob.vt[gr0]) && (chk >= ob.vt[gr0]) ); + mess_bad.gvt[gr0][obj1] = ++mess.gvt[gr0][obj1]; + // cerr << ob.vt[gr0] << endl; + // cerr << "===========\n"; + // ---- VTmess mess2; @@ -508,22 +536,90 @@ EXAM_CHECK( !ob.deliver(mess_bad) ); // nac: obj0 don't seen mess from obj2, but obj1 seen mess from obj2 - EXAM_CHECK( ob.deliver(mess2) ); // ack: obj0 see first mess from obj2 + EXAM_REQUIRE( (chk <= ob.vt[gr0]) && (chk >= ob.vt[gr0]) ); + EXAM_REQUIRE( ob.deliver(mess2) ); // ack: obj0 see first mess from obj2 + + chk[obj2] += 1; + EXAM_REQUIRE( (chk <= ob.vt[gr0]) && (chk >= ob.vt[gr0]) ); + ++mess2.gvt[gr0][obj2]; - EXAM_CHECK( ob.deliver(mess_bad) ); // ack: now obj0 and obj1 sync dependency from obj2 + EXAM_REQUIRE( ob.deliver(mess_bad) ); // ack: now obj0 and obj1 sync dependency from obj2 + // cerr << ob.vt[gr0] << endl; + // cerr << "===========\n"; + + chk[obj1] += 1; + EXAM_REQUIRE( (chk <= ob.vt[gr0]) && (chk >= ob.vt[gr0]) ); + mess_bad.gvt[gr0][obj1] = ++mess.gvt[gr0][obj1]; mess.gvt[gr0][obj2] = 1; + mess_bad.gvt[gr0][obj2] = 0; // ---- - ob.add_group( gr0 ); - ob.add_group_member( gr1, obj0 ); - ob.add_group_member( gr1, obj1 ); - ob.add_group_member( gr1, obj2 ); + ob.add_group( gr1 ); + // ob.add_group_member( gr1, obj0 ); + // ob.add_group_member( gr1, obj1 ); + // ob.add_group_member( gr1, obj2 ); + mess_bad.grp = gr2; + + vtime chk1; + + try { + EXAM_CHECK( ob.deliver(mess_bad) ); // nac: ob not member of group gr2 + EXAM_ERROR( "exception expected" ); + } + catch ( const domain_error& ) { + EXAM_REQUIRE( (chk <= ob.vt[gr0]) && (chk >= ob.vt[gr0]) ); + EXAM_REQUIRE( (chk1 <= ob.vt[gr1]) && (chk1 >= ob.vt[gr1]) ); + EXAM_REQUIRE( (chk1 <= ob.vt[gr2]) && (chk1 >= ob.vt[gr2]) ); + } + + // ---- + + mess_bad.grp = gr0; + mess_bad.gvt[gr1][obj2] = 1; + + EXAM_REQUIRE( !ob.deliver(mess_bad) ); // nac: obj1 recieve new event in group gr1 from obj2 + + EXAM_REQUIRE( (chk <= ob.vt[gr0]) && (chk >= ob.vt[gr0]) ); + EXAM_REQUIRE( (chk1 <= ob.vt[gr1]) && (chk1 >= ob.vt[gr1]) ); + + // cerr << "===========\n"; + // cerr << ob.vt[gr0] << endl; + // cerr << "===========\n"; + + VTmess mess3; + + mess3.code = 1; + mess3.src = obj2; + mess3.gvt[gr1][obj2] = 1; + mess3.grp = gr1; + mess3.mess = "data"; + + EXAM_REQUIRE( ob.deliver(mess3) ); // ack: see event from obj2 in group gr1 + + EXAM_REQUIRE( (chk <= ob.vt[gr0]) && (chk >= ob.vt[gr0]) ); + chk1[obj2] += 1; + EXAM_REQUIRE( (chk1 <= ob.vt[gr1]) && (chk1 >= ob.vt[gr1]) ); + + ++mess3.gvt[gr1][obj2]; + + // cerr << "===========\n"; + // cerr << /* ob.vt[gr0] */ mess_bad.gvt[gr0] << endl; + // cerr << /* ob.vt[gr0] */ mess_bad.gvt[gr1] << endl; + // cerr << "===========\n"; + + // cerr << "2 ==========\n"; + EXAM_REQUIRE( ob.deliver(mess_bad) ); // ack: now we know about event in group gr1 + + chk[obj1] += 1; + EXAM_REQUIRE( (chk <= ob.vt[gr0]) && (chk >= ob.vt[gr0]) ); + EXAM_REQUIRE( (chk1 <= ob.vt[gr1]) && (chk1 >= ob.vt[gr1]) ); + return EXAM_RESULT; } Modified: trunk/complement/explore/test/virtual_time/vtime.cc =================================================================== --- trunk/complement/explore/test/virtual_time/vtime.cc 2007-07-24 07:49:03 UTC (rev 1638) +++ trunk/complement/explore/test/virtual_time/vtime.cc 2007-07-25 06:55:38 UTC (rev 1639) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <07/07/23 20:32:22 ptr> +// -*- C++ -*- Time-stamp: <07/07/25 10:22:27 ptr> #include "vtime.h" @@ -319,6 +319,23 @@ return false; } +bool vtime_obj_rec::deliver_delayed( const VTmess& m ) +{ + // cout << self_id() << " " << ev.value().mess << endl; + + // cout << ev.value().gvt.gvt << endl; + + if ( order_correct_delayed( m ) ) { + lvt[m.src] += m.gvt.gvt; + lvt[m.src][m.grp][m.src] = vt.gvt[m.grp][m.src] + 1; + sup( vt.gvt[m.grp], lvt[m.src][m.grp] ); + // cout << vt.gvt << endl; + return true; + } + + return false; +} + bool vtime_obj_rec::order_correct( const VTmess& m ) { if ( groups.find( m.grp ) == groups.end() ) { @@ -327,62 +344,115 @@ gvtime gvt( m.gvt ); - if ( vt.gvt[m.grp][m.src] + 1 != gvt[m.grp][m.src] ) { + if ( (vt.gvt[m.grp][m.src] + 1) != gvt[m.grp][m.src] ) { // cerr << "1" << endl; // cerr << vt.gvt[m.grp][m.src] << "\n" // << gvt[m.grp][m.src] // << endl; - if ( vt.gvt[m.grp][m.src] + 1 > gvt[m.grp][m.src] ) { + if ( (vt.gvt[m.grp][m.src] + 1) > gvt[m.grp][m.src] ) { throw out_of_range( "duplicate or wrong VT message" ); } return false; } vtime xvt = lvt[m.src][m.grp] + gvt[m.grp]; - xvt[m.src] = 0; + xvt[m.src] = 0; // force exclude message originator, it checked above if ( !(xvt <= vt[m.grp]) ) { - cerr << "2" << endl; - cerr << xvt << "\n\n" - << vt[m.grp] << endl; + // cerr << "2" << endl; + // cerr << xvt << "\n\n" << vt[m.grp] << endl; return false; } + // check side casuality (via groups other then message's group) for ( groups_container_type::const_iterator l = groups.begin(); l != groups.end(); ++l ) { - if ( *l != m.grp ) { - xvt = lvt[m.src][*l] + gvt[*l]; - if ( !(xvt <= vt[*l]) ) { - cerr << "3" << endl; - cerr << "group " << *l << xvt << "\n\n" - << vt[*l] << endl; - return false; - } + if ( (*l != m.grp) && !((lvt[m.src][*l] + gvt[*l]) <= vt[*l]) ) { + // cerr << "3" << endl; + // cerr << "group " << *l << xvt << "\n\n" << vt[*l] << endl; + return false; } } return true; } -void VTDispatcher::VTDispatch( const VTmess& m ) +bool vtime_obj_rec::order_correct_delayed( const VTmess& m ) { - gid_map_type::const_iterator g = grmap.find( m.grp ); - if ( g != grmap.end() ) { - for ( std::list<oid_type>::const_iterator o = g->second.begin(); o != g->second.end(); ++o ) { - vt_map_type::iterator i = vtmap.find( *o ); - if ( i != vtmap.end() ) { - if ( i->second.deliver( m ) ) { - stem::Event ev( m.code ); - ev.dest(i->first); - ev.value() = m.mess; - Send( ev ); - } + gvtime gvt( m.gvt ); + + if ( (vt.gvt[m.grp][m.src] + 1) != gvt[m.grp][m.src] ) { + return false; + } + + vtime xvt = lvt[m.src][m.grp] + gvt[m.grp]; + xvt[m.src] = 0; // force exclude message originator, it checked above + + if ( !(xvt <= vt[m.grp]) ) { + return false; + } + + // check side casuality (via groups other then message's group) + for ( groups_container_type::const_iterator l = groups.begin(); l != groups.end(); ++l ) { + if ( (*l != m.grp) && !((lvt[m.src][*l] + gvt[*l]) <= vt[*l]) ) { + return false; + } + } + + return true; +} + +void VTDispatcher::VTDispatch( const stem::Event_base<VTmess>& m ) +{ + pair<gid_map_type::const_iterator,gid_map_type::const_iterator> range = grmap.equal_range( m.value().grp ); + + for ( gid_map_type::const_iterator o = range.first; o != range.second; ++o ) { + vt_map_type::iterator i = vtmap.find( o->second ); + if ( i != vtmap.end() || i->first == m.src() ) { // not for nobody and not for self + continue; + } + try { + if ( i->second.deliver( m.value() ) ) { + stem::Event ev( m.value().code ); + ev.dest(i->first); + ev.src(m.src()); + ev.value() = m.value().mess; + Forward( ev ); + bool more; + do { + more = false; + for ( vtime_obj_rec::dpool_t::iterator j = i->second.dpool.begin(); j != i->second.dpool.end(); ) { + if ( i->second.deliver_delayed( j->second->value() ) ) { + stem::Event evd( j->second->value().code ); + evd.dest(i->first); + ev.src(m.src()); + evd.value() = j->second->value().mess; + Forward( evd ); + delete j->second; + i->second.dpool.erase( j++ ); + more = true; + } else { + ++j; + } + } + } while ( more ); + } else { + i->second.dpool.push_back( make_pair( 0, new Event_base<VTmess>(m) ) ); // 0 should be timestamp } } + catch ( const out_of_range& ) { + } + catch ( const domain_error& ) { + } } } +void VTDispatcher::VTSend( const stem::Event& e ) +{ +} + DEFINE_RESPONSE_TABLE( VTDispatcher ) - EV_T_( ST_NULL, MESS, VTDispatch, VTmess ) + // EV_T_( ST_NULL, MESS, VTDispatch, VTmess ) + EV_Event_base_T_( ST_NULL, MESS, VTDispatch, VTmess ) END_RESPONSE_TABLE char *Init_buf[128]; Modified: trunk/complement/explore/test/virtual_time/vtime.h =================================================================== --- trunk/complement/explore/test/virtual_time/vtime.h 2007-07-24 07:49:03 UTC (rev 1638) +++ trunk/complement/explore/test/virtual_time/vtime.h 2007-07-25 06:55:38 UTC (rev 1639) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <07/07/23 21:33:09 ptr> +// -*- C++ -*- Time-stamp: <07/07/25 09:07:25 ptr> #ifndef __vtime_h #define __vtime_h @@ -168,19 +168,25 @@ void add_group( group_type g ) { groups.insert(g); } - void add_group_member( group_type g, oid_type p ) - { vt[g][p]; } + // void add_group_member( group_type g, oid_type p ) + // { vt[g][p]; } bool deliver( const VTmess& ev ); + bool deliver_delayed( const VTmess& ev ); stem::addr_type addr; // stem address of object delta_vtime_type lvt; // last seen VT of neighbours gvtime vt; // VT of object groups_container_type groups; // member of groups // delay pool should be here + typedef std::pair<int,stem::Event_base<VTmess>*> delay_item_t; + typedef std::list<delay_item_t> dpool_t; + dpool_t dpool; + private: bool order_correct( const VTmess& ); + bool order_correct_delayed( const VTmess& ); }; class VTDispatcher : @@ -194,13 +200,13 @@ stem::EventHandler( id ) { } - void VTDispatch( const VTmess& ); + void VTDispatch( const stem::Event_base<VTmess>& ); void VTSend( const stem::Event& e ); private: typedef std::hash_map<oid_type, vtime_obj_rec> vt_map_type; - typedef std::hash_map<group_type, std::list<oid_type> > gid_map_type; + typedef std::hash_multimap<group_type, oid_type> gid_map_type; // oid_type map_gid( group_type ); // gid_type -> (oid_type, oid_type, ...) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |