uint128_t VersionedSlaveCM::sync( const uint128_t& v ) { #if 0 LBLOG( LOG_OBJECTS ) << "sync to v" << v << ", id " << _object->getID() << "." << _object->getInstanceID() << std::endl; #endif if( _version == v ) return _version; if( v == VERSION_HEAD ) { _syncToHead(); return _version; } const uint128_t version = ( v == VERSION_NEXT ) ? _version + 1 : v; LBASSERTINFO( version.high() == 0, "Not a master version: " << version ) LBASSERTINFO( _version <= version, "can't sync to older version of object " << lunchbox::className( _object ) << " " << _object->getID() << " (" << _version << ", " << version <<")" ); while( _version < version ) _unpackOneVersion( _queuedVersions.pop( )); LocalNodePtr node = _object->getLocalNode(); if( node.isValid( )) node->flushCommands(); return _version; }
void memory_write(memory_content& content, address const begin, uint128_t value, bool const write_data_in_big_endian) { byte* b = value.data(); if (write_data_in_big_endian == is_this_little_endian_machine()) std::reverse(b,b + value.size()); memory_write(content,begin,(byte const*)b,value.size()); }
uint32_t ObjectStore::_startSync( Object* object, NodePtr master, const uint128_t& id, const uint32_t instanceID ) { LB_TS_NOT_THREAD( _receiverThread ); LBLOG( LOG_OBJECTS ) << "Syncing " << lunchbox::className( object ) << " with id " << id << std::endl; LBASSERT( object ); LBASSERTINFO( id.isUUID(), id ); if( !object || !id.isUUID( )) { LBWARN << "Invalid object " << object << " or id " << id << std::endl; return LB_UNDEFINED_UINT32; } if( !master ) master = _localNode->connectObjectMaster( id ); if( !master || !master->isReachable( )) { LBWARN << "Mapping of object " << id << " failed, invalid master node" << std::endl; return LB_UNDEFINED_UINT32; } const uint32_t request = _localNode->registerRequest( new ObjectDataIStream ); uint128_t minCachedVersion = VERSION_HEAD; uint128_t maxCachedVersion = VERSION_NONE; uint32_t cacheInstanceID = 0; bool useCache = _checkInstanceCache( id, minCachedVersion, maxCachedVersion, cacheInstanceID ); if( useCache ) { switch( instanceID ) { case CO_INSTANCE_ALL: break; default: if( instanceID == cacheInstanceID ) break; useCache = false; LBCHECK( _instanceCache->release( id, 1 )); break; } } // Use stream expected by MasterCMCommand master->send( CMD_NODE_SYNC_OBJECT ) << VERSION_NEWEST << minCachedVersion << maxCachedVersion << id << uint64_t(0) /* maxVersions */ << request << instanceID << cacheInstanceID << useCache; return request; }
bool RequestHandler::waitRequest( const uint32_t requestID, uint128_t& rUint128, const uint32_t timeout ) { Request::Result result; if( !_impl->waitRequest( requestID, result, timeout )) return false; rUint128.high() = result.rUint128.high; rUint128.low() = result.rUint128.low; return true; }
::zeroeq::Event serializeRequest( const uint128_t& eventType ) { ::zeroeq::Event event( ::zeroeq::vocabulary::EVENT_REQUEST ); flatbuffers::FlatBufferBuilder& fbb = event.getFBB(); RequestBuilder builder( fbb ); builder.add_eventHigh( eventType.high( )); builder.add_eventLow( eventType.low( )); fbb.Finish( builder.Finish( )); return event; }
uint32_t ObjectStore::mapNB( Object* object, const uint128_t& id, const uint128_t& version, NodePtr master ) { LB_TS_NOT_THREAD( _receiverThread ); LBLOG( LOG_OBJECTS ) << "Mapping " << lunchbox::className( object ) << " to id " << id << " version " << version << std::endl; LBASSERT( object ); LBASSERTINFO( id.isUUID(), id ); if( !master ) master = _localNode->connectObjectMaster( id ); if( !master || !master->isReachable( )) { LBWARN << "Mapping of object " << id << " failed, invalid master node" << std::endl; return LB_UNDEFINED_UINT32; } if( !object || !id.isUUID( )) { LBWARN << "Invalid object " << object << " or id " << id << std::endl; return LB_UNDEFINED_UINT32; } const bool isAttached = object->isAttached(); const bool isMaster = object->isMaster(); LBASSERTINFO( !isAttached, *object ); LBASSERT( !isMaster ) ; if( isAttached || isMaster ) { LBWARN << "Invalid object state: attached " << isAttached << " master " << isMaster << std::endl; return LB_UNDEFINED_UINT32; } const uint32_t request = _localNode->registerRequest( object ); uint128_t minCachedVersion = VERSION_HEAD; uint128_t maxCachedVersion = VERSION_NONE; uint32_t masterInstanceID = 0; const bool useCache = _checkInstanceCache( id, minCachedVersion, maxCachedVersion, masterInstanceID ); object->notifyAttach(); master->send( CMD_NODE_MAP_OBJECT ) << version << minCachedVersion << maxCachedVersion << id << object->getMaxVersions() << request << _genNextID( _instanceIDs ) << masterInstanceID << useCache; return request; }
uint128_t VersionedMasterCM::sync( const uint128_t& inVersion ) { LBASSERTINFO( inVersion.high() != 0 || inVersion == VERSION_NEXT || inVersion == VERSION_HEAD, inVersion ); #if 0 LBLOG( LOG_OBJECTS ) << "sync to v" << inVersion << ", id " << _object->getID() << "." << _object->getInstanceID() << std::endl; #endif if( inVersion == VERSION_NEXT ) return _apply( _slaveCommits.pop( )); if( inVersion == VERSION_HEAD ) { uint128_t version = VERSION_NONE; for( ObjectDataIStream* is = _slaveCommits.tryPop(); is; is = _slaveCommits.tryPop( )) { version = _apply( is ); } return version; } // else apply only concrete slave commit return _apply( _slaveCommits.pull( inVersion )); }
void RequestHandler::serveRequest( const uint32_t requestID, const uint128_t& result ) { Request* request = 0; { ScopedFastWrite mutex( _impl->lock ); RequestHashCIter i = _impl->requests.find( requestID ); if( i != _impl->requests.end( )) request = i->second; } if( request ) { request->result.rUint128.low = result.low(); request->result.rUint128.high = result.high(); request->lock.unset(); } }
uint128_t MasterCM::sync( const uint128_t& version ) { EQASSERTINFO( version.high() != 0 || version == VERSION_NEXT || version == VERSION_HEAD, version ); #if 0 EQLOG( LOG_OBJECTS ) << "sync to v" << version << ", id " << _object->getID() << "." << _object->getInstanceID() << std::endl; #endif if( version == VERSION_NEXT ) { ObjectDataIStream* is = _queuedDeltas.pop(); _apply( is ); return _version; } // else if( version == VERSION_HEAD ) { ObjectDataIStream* is = 0; while( _queuedDeltas.tryPop( is )) _apply( is ); return _version; } // else apply only concrete slave commit ObjectDataIStream* is = 0; ObjectDataIStreams unusedStreams; while( !is ) { ObjectDataIStream* candidate = _queuedDeltas.pop(); if( candidate->getVersion() == version ) is = candidate; else unusedStreams.push_back( candidate ); } _apply( is ); _queuedDeltas.pushFront( unusedStreams ); return version; }
// Bitwise Operators template <typename T> T operator&(T lhs, uint128_t rhs){ T out = lhs & (T) rhs.lower(); return out; }
template <typename T> T operator^=(T & lhs, uint128_t rhs){ lhs ^= (T) rhs.lower(); return lhs; }
// Comparison Operators template <typename T> bool operator==(T lhs, uint128_t rhs){ return (!rhs.upper() && ((uint64_t) lhs == rhs.lower())); }
template<> ZEROBUF_INL void toJSON( const uint128_t& value, Json::Value& json ) { json[ "high" ] = Json::UInt64( value.high( )); json[ "low" ] = Json::UInt64( value.low( )); }
template <typename T> T operator*(T lhs, uint128_t rhs){ return lhs * rhs.lower(); }
template <typename T> bool operator<=(T lhs, uint128_t rhs){ if (rhs.upper()) return true; return ((uint64_t) lhs <= rhs.lower()); }
template <typename T> bool operator>=(T lhs, uint128_t rhs){ if (rhs.upper()) return false; return ((uint64_t) lhs >= rhs.lower()); }
template <typename T> bool operator!=(T lhs, uint128_t rhs){ return (rhs.upper() | ((uint64_t) lhs != rhs.lower())); }