iWARPEM_Status_t ExtractNextMessage( iWARPEM_Message_Hdr_t **aHdr, char **aData, iWARPEM_StreamId_t *aClientId ) { iWARPEM_Status_t status = IWARPEM_SUCCESS; pthread_spin_lock( &mAccessLock ); if( ! RecvDataAvailable() ) { BegLogLine( FXLOG_IT_API_O_SOCKETS_MULTIPLEX_LOG ) << "No data available in ReadBuffer. Reading new set of data." << EndLogLine; switch( mReceiveBuffer->FillFromSocket( mRouterConnFd ) ) { case IWARPEM_SUCCESS: break; default: status = IWARPEM_ERRNO_CONNECTION_RESET; BegLogLine( FXLOG_IT_API_O_SOCKETS_MULTIPLEX_LOG ) << "Error while reading data from router endpoint." << EndLogLine; pthread_spin_unlock( &mAccessLock ); return status; } } pthread_spin_unlock( &mAccessLock ); size_t rlen = sizeof( iWARPEM_Multiplexed_Msg_Hdr_t ); iWARPEM_Multiplexed_Msg_Hdr_t *MultHdr = (iWARPEM_Multiplexed_Msg_Hdr_t*)mReceiveBuffer->GetHdrPtr( &rlen ); AssertLogLine( rlen == sizeof( iWARPEM_Multiplexed_Msg_Hdr_t ) ) << "Retrieval of HdrPtr failed: len=" << rlen << " expected=" << sizeof(iWARPEM_Multiplexed_Msg_Hdr_t) << EndLogLine; MultHdr->ClientID = ntohs( MultHdr->ClientID ); *aClientId = MultHdr->ClientID; rlen = sizeof( iWARPEM_Message_Hdr_t ); *aHdr = (iWARPEM_Message_Hdr_t*)mReceiveBuffer->GetHdrPtr( &rlen ); AssertLogLine( rlen == sizeof( iWARPEM_Message_Hdr_t ) ) << "Retrieval of HdrPtr failed: len=" << rlen << " expected=" << sizeof(iWARPEM_Multiplexed_Msg_Hdr_t) << EndLogLine; (*aHdr)->EndianConvert(); rlen = (*aHdr)->mTotalDataLen; if( rlen ) rlen = mReceiveBuffer->GetData( aData, &rlen ); AssertLogLine( rlen == (*aHdr)->mTotalDataLen ) << "Retrieval of HdrPtr failed: len=" << rlen << " expected=" << sizeof(iWARPEM_Multiplexed_Msg_Hdr_t) << EndLogLine; BegLogLine( FXLOG_IT_API_O_SOCKETS_MULTIPLEX_LOG ) << "Extracted new client message: " << " socket: " << mRouterConnFd << " client: " << MultHdr->ClientID << " MsgHdrSize: " << sizeof( iWARPEM_Multiplexed_Msg_Hdr_t ) << " MsgPldSize: " << (*aHdr)->mTotalDataLen << " Processed: " << mReceiveBuffer->GetDataLen() << EndLogLine; return status; }
// ??? We should allow the user to set a compare function on skv_store_t // ??? Default behaviour should be lexicographical order bool operator<( const skv_store_t& aStore ) const { BegLogLine( SKV_STORE_T_LOG ) << "skv_store_t::operator<():: Entering " << EndLogLine; int MinDataSize = min( mSize(), aStore.mSize() ); AssertLogLine( mData != NULL ) << "skv_store_t::operator<():: ERROR: " << " mData != NULL " << EndLogLine; AssertLogLine( aStore.mData != NULL ) << "skv_store_t::operator<():: ERROR: " << " aStore.mData != NULL " << EndLogLine; int rc = memcmp( mData, aStore.mData, MinDataSize ); BegLogLine( SKV_STORE_T_LOG ) << "skv_store_t::operator<():: " << " MinDataSize: " << MinDataSize << " mSize: " << mSize() << " aStore.mSize: " << aStore.mSize() << " rc: " << rc << EndLogLine; return ( rc < 0 ); }
static inline skv_status_t insert_lookup_sequence( skv_local_kv_t *aLocalKV, skv_server_ccb_t *aCommand, skv_cmd_RIU_req_t **aReq, skv_local_kv_cookie_t *aCookie, skv_lmr_triplet_t *aValueRep ) { // we have copied all Req data into response buffer already at cmd init skv_cmd_RIU_req_t *Req = (skv_cmd_RIU_req_t *) aCommand->GetSendBuff(); // convert only if it's the first time we arrive here... if( aCommand->GetCommandClass() == SKV_COMMAND_CLASS_IMMEDIATE ) Req->EndianConvert() ; *aReq = Req; if( FlagBasedLock( aLocalKV, Req, aCommand ) != SKV_SUCCESS ) { BegLogLine( ( SKV_SERVER_LOCK_LOG | SKV_SERVER_INSERT_LOG ) ) << "skv_server_insert_command_sm::Execute()::" << " record is locked." << EndLogLine; return SKV_ERRNO_RECORD_IS_LOCKED; } // Check if the key is in the buffer int KeySize = Req->mKeyValue.mKeySize; BegLogLine( SKV_SERVER_INSERT_LOG ) << "skv_server_insert_command_sm:: Lookup with flags: " << (void*)( (uintptr_t)Req->mFlags & (SKV_COMMAND_RIU_INSERT_EXPANDS_VALUE | SKV_COMMAND_RIU_INSERT_OVERWRITE_VALUE_ON_DUP | SKV_COMMAND_RIU_UPDATE | SKV_COMMAND_RIU_APPEND) ) << EndLogLine; AssertLogLine( Req->mKeyValue.mKeySize >= 0 && Req->mKeyValue.mKeySize < SKV_KEY_LIMIT ) << "skv_server_insert_command_sm:: Execute():: ERROR: " << "Req->mKeyValue.mKeySize: " << Req->mKeyValue.mKeySize << EndLogLine; AssertLogLine( (Req->mFlags & SKV_COMMAND_RIU_INSERT_KEY_FITS_IN_CTL_MSG) || (Req->mFlags & SKV_COMMAND_RIU_INSERT_KEY_VALUE_FIT_IN_CTL_MSG) ) << "skv_server_insert_command_sm:: Execute():: ERROR: " << " Assume that key fits into the control message" << EndLogLine; // Check if the key exists return aLocalKV->Lookup( Req->mPDSId, Req->mKeyValue.mData, KeySize, Req->mFlags, aValueRep, aCookie ); }
static skv_status_t Release( skv_client_server_conn_t* aConn, skv_client_ccb_t* aCCB ) { /********************************************************************** * Release resources **********************************************************************/ // Command is completed, release resources int CommandOrd = aCCB->GetCmdOrd(); aConn->ReleaseCmdOrdinal( CommandOrd ); aCCB->mCCBMgrIF->AddToDoneCCBQueue( aCCB ); skv_cmd_RIU_flags_t Flags = aCCB->mCommand.mCommandBundle.mCommandRetrieve.mFlags; if( !( Flags & SKV_COMMAND_RIU_RETRIEVE_VALUE_FIT_IN_CTL_MSG ) ) { // Release LMRs it_lmr_handle_t lmrHdl = aCCB->mCommand.mCommandBundle.mCommandRetrieve.mValueBufferRef.mValueLMR; it_status_t status = it_lmr_free( lmrHdl ); AssertLogLine( status == IT_SUCCESS ) << "skv_client_release_command_sm::Release():: ERROR:: it_lmr_free() failed" << " lmr: " << (void *) lmrHdl << " status: " << status << EndLogLine; } return SKV_SUCCESS; /**********************************************************************/ }
static inline void insert_post_rdma( skv_server_ep_state_t *aEPState, skv_local_kv_t *aLocalKV, int aCommandOrdinal, skv_cmd_RIU_req_t *aReq, skv_lmr_triplet_t *aValueRepForRdmaRead, int* aSeqNo, int aMyRank ) { skv_server_cookie_t Cookie; Cookie.Init( aEPState, *aSeqNo, aCommandOrdinal ); it_dto_cookie_t* DtoCookie = (it_dto_cookie_t*) &Cookie; it_dto_flags_t dto_flags = (it_dto_flags_t) (IT_COMPLETION_FLAG | IT_NOTIFY_FLAG); gSKVServerInsertRDMAReadStart.HitOE( SKV_SERVER_INSERT_TRACE, "SKVServerInsertRdmaRead", aMyRank, gSKVServerInsertRDMAReadStart ); aLocalKV->RDMABoundsCheck( "Insert1", (char *) aValueRepForRdmaRead->GetAddr(), aValueRepForRdmaRead->GetLen() ); BegLogLine( SKV_SERVER_INSERT_LOG ) << "skv_server_insert_command_sm:: Execute():: Before rdma_read " << " LMR triplet { " << " len: " << aValueRepForRdmaRead->GetLen() << " addr: " << (void *) aValueRepForRdmaRead->GetAddr() << " lmr: " << (void *) aValueRepForRdmaRead->GetLMRHandle() << " } " << " RMR info " << " rmr addr: " << (void *) aReq->mRMRTriplet.GetAddr() << " rmr context: " << (void *) aReq->mRMRTriplet.GetRMRContext() << EndLogLine; // rdma_read the value it_status_t itstatus = it_post_rdma_read( aEPState->mEPHdl, aValueRepForRdmaRead->GetTripletPtr(), 1, *DtoCookie, dto_flags, (it_rdma_addr_t) aReq->mRMRTriplet.GetAddr(), aReq->mRMRTriplet.GetRMRContext() ); gSKVServerInsertRDMAReadFinis.HitOE( SKV_SERVER_INSERT_TRACE, "SKVServerInsertRdmaRead", aMyRank, gSKVServerInsertRDMAReadFinis ); AssertLogLine( itstatus == IT_SUCCESS ) << "skv_server_insert_command_sm::Execute():: ERROR: " << " istatus: " << itstatus << EndLogLine; }
/*** * skv_server_t::InitNewStateForEP:: * Desc: Initiates the state for a new EP * input: * returns: SKV_SUCCESS or SKV_ERR_NO_EVENT ***/ skv_status_t skv_server_network_event_manager_if_t:: FinalizeEPState( skv_server_epstate_map_t *aEPStateMap, it_ep_handle_t aEP, skv_server_ep_state_t* aStateForEP ) { AssertLogLine( aStateForEP != NULL ) << "skv_server_t::FinalizeEPState(): ERROR: " << " aEP: " << (void *) aEP << EndLogLine; aStateForEP->Closing(); skv_server_finalizable_associated_ep_state_list_t::iterator iter = aStateForEP->mAssociatedStateList->begin(); skv_server_finalizable_associated_ep_state_list_t::iterator end = aStateForEP->mAssociatedStateList->end(); for( ; iter != end; iter++ ) { switch( iter->mStateType ) { case SKV_SERVER_FINALIZABLE_ASSOCIATED_EP_STATE_CREATE_CURSOR_TYPE: { skv_server_cursor_hdl_t ServCursorHdl = (skv_server_cursor_hdl_t) iter->mState; ServCursorHdl->Finalize(); free( ServCursorHdl ); break; } default: StrongAssertLogLine( 0 ) << "FinalizeEPState(): ERROR:: " << " iter->mStateType: " << iter->mStateType << EndLogLine; } } aEPStateMap->erase( aEP ); aStateForEP->Finalize(); BegLogLine(SKV_SERVER_CLEANUP_LOG) << "free(aStateForEP= " << (void *) aStateForEP << " )" << EndLogLine ; bzero( aStateForEP, sizeof( skv_server_ep_state_t ) ); delete aStateForEP; it_ep_free( aEP ); BegLogLine( SKV_SERVER_CLEANUP_LOG ) << "skv_server::FinalizeEPState(): completed " << EndLogLine; return SKV_SUCCESS; }
static inline skv_status_t insert_command_completion( skv_local_kv_t *aLocalKV, skv_status_t aRC, skv_server_ep_state_t *aEPState, skv_cmd_RIU_req_t *aReq, skv_server_ccb_t *aCommand, int aCommandOrdinal, int *aSeqNo ) { skv_cmd_insert_cmpl_t *Cmpl; Cmpl = (skv_cmd_insert_cmpl_t *) aReq; BegLogLine( SKV_SERVER_INSERT_LOG ) << "skv_server_insert_command_sm::Execute()::" << " completing insert with status: " << skv_status_to_string( aRC ) << EndLogLine; AssertLogLine( Cmpl != NULL ) << "skv_server_insert_command_sm::Execute():: ERROR: " << EndLogLine; FlagBasedUnlock( aLocalKV, aCommand ); if( aRC != SKV_SUCCESS ) Cmpl->mHdr.mEvent = SKV_CLIENT_EVENT_ERROR; else Cmpl->mHdr.mEvent = SKV_CLIENT_EVENT_CMD_COMPLETE; Cmpl->mStatus = aRC; Cmpl->EndianConvert() ; skv_status_t status = aEPState->Dispatch( aCommand, aSeqNo, aCommandOrdinal ); AssertLogLine( status == SKV_SUCCESS ) << "skv_server_insert_command_sm::Execute():: ERROR: " << " status: " << skv_status_to_string( status ) << EndLogLine; return status; }
skv_array_queue_t() { len = 0; AssertLogLine( SKV_ARRAY_QUEUE_SIZE < SKV_MAX_ARRAY_QUEUE_SIZE ) << "skv_array_queue_t(): requested length exceeds limit of " << SKV_MAX_ARRAY_QUEUE_SIZE << EndLogLine; Memory = new T[SKV_ARRAY_QUEUE_SIZE + 1]; head = 0; tail = 0; }
void pop() { if( (len > 0) && ((len%SKV_ARRAY_QUEUE_SIZE) == len) ) { tail = (tail + 1) % SKV_ARRAY_QUEUE_SIZE; len--; } else AssertLogLine( 1 ) << "skv_array_queue_t::pop(): queue underflow" << EndLogLine; }
// needs to make sure to not change the status of the receive buffer iWARPEM_Status_t GetNextMessageType( iWARPEM_Msg_Type_t *aMsgType, iWARPEM_StreamId_t *aClient ) { iWARPEM_Status_t status = IWARPEM_SUCCESS; pthread_spin_lock( &mAccessLock ); if( ! RecvDataAvailable() ) { BegLogLine( FXLOG_IT_API_O_SOCKETS_MULTIPLEX_LOG ) << "No data available in ReadBuffer. Reading new set of data." << EndLogLine; status = mReceiveBuffer->FillFromSocket( mRouterConnFd ); switch( status ) { case IWARPEM_SUCCESS: break; default: BegLogLine( 1 ) << "Error while reading data from router endpoint." << EndLogLine; *aClient = IWARPEM_INVALID_CLIENT_ID; *aMsgType = iWARPEM_UNKNOWN_REQ_TYPE; pthread_spin_unlock( &mAccessLock ); return status; } } pthread_spin_unlock( &mAccessLock ); size_t hdrlen = sizeof( iWARPEM_Multiplexed_Msg_Hdr_t ); iWARPEM_Multiplexed_Msg_Hdr_t *MultHdr = (iWARPEM_Multiplexed_Msg_Hdr_t*)mReceiveBuffer->GetHdrPtr( &hdrlen, 0 ); AssertLogLine( hdrlen == sizeof( iWARPEM_Multiplexed_Msg_Hdr_t ) ) << "Retrieval of HdrPtr failed: len=" << hdrlen << " expected=" << sizeof(iWARPEM_Multiplexed_Msg_Hdr_t) << EndLogLine; MultHdr->ClientID = be64toh( MultHdr->ClientID ); *aClient = MultHdr->ClientID; // advance the hdr ptr ourselves to peek into MsgType without advancing the receive buffer ptr char *HdrData = (char*)MultHdr; HdrData += sizeof( iWARPEM_Multiplexed_Msg_Hdr_t ); HdrData = (char*)mReceiveBuffer->AlignedHeaderPosition( HdrData ); iWARPEM_Message_Hdr_t *MsgPtr = (iWARPEM_Message_Hdr_t*)HdrData; BegLogLine( FXLOG_IT_API_O_SOCKETS_MULTIPLEX_LOG ) << "Retrieving msg_type: " << MsgPtr->mMsg_Type << " from client: " << *aClient << " readptr@: " << (void*)(MsgPtr) << " len: " << MsgPtr->mTotalDataLen << EndLogLine; *aMsgType = MsgPtr->mMsg_Type; return status; }
void push( const T element ) { Memory[head] = element; len++; AssertLogLine( len < SKV_ARRAY_QUEUE_SIZE ) << "skv_array_queue_t::push(): Queue overflow" << " size: " << len << " max: " << SKV_ARRAY_QUEUE_SIZE << EndLogLine; head = (head + 1) % SKV_ARRAY_QUEUE_SIZE; }
// ??? We should allow the user to set a compare function on skv_store_t // ??? Default behaviour should be lexicographical order bool operator==( const skv_store_t& aStore ) const { BegLogLine( SKV_STORE_T_LOG ) << "skv_store_t::operator==():: Entering " << EndLogLine; AssertLogLine( mData != NULL ) << "skv_store_t::operator==():: ERROR: " << " mData != NULL " << EndLogLine; AssertLogLine( aStore.mData != NULL ) << "skv_store_t::operator==():: ERROR: " << " aStore.mData != NULL " << EndLogLine; if( mSize() == aStore.mSize() ) { return (memcmp( mData, aStore.mData, mSize() ) == 0); } else return 0; }
void Init( char* aData, int aSize ) { AssertLogLine( aSize >= 0 ) << "skv_store_t::Init():: ERROR: " << " aSize: " << aSize << EndLogLine; mData = aData; mSizeBE = htonl(aSize); BegLogLine(SKV_SERVER_ENDIAN_LOG) << "Endian-converting " << aSize << " to " << (void *) (intptr_t)mSizeBE << EndLogLine ; }
// if *aClient is passed as NULL, data is extracted without the multiplexed message header - pure raw retrieval // user has to make sure that this doesn't break the protocol!! iWARPEM_Status_t ExtractRawData( char *aBuffer, int aSize, int *aRecvd, iWARPEM_StreamId_t *aClient = NULL ) { iWARPEM_Status_t status = IWARPEM_SUCCESS; pthread_spin_lock( &mAccessLock ); if( ! RecvDataAvailable() ) { BegLogLine( FXLOG_IT_API_O_SOCKETS_MULTIPLEX_LOG ) << "No data available in ReadBuffer. Reading new set of data." << EndLogLine; status = mReceiveBuffer->FillFromSocket( mRouterConnFd ); switch( status ) { case IWARPEM_SUCCESS: break; default: BegLogLine( FXLOG_IT_API_O_SOCKETS_MULTIPLEX_LOG ) << "Error while reading data from router endpoint." << EndLogLine; pthread_spin_unlock( &mAccessLock ); return status; } } pthread_spin_unlock( &mAccessLock ); // data can only be an iWARPEM_Message_Hdr_t if the client is requested too if( aClient != NULL ) { size_t hdrlen = sizeof( iWARPEM_Multiplexed_Msg_Hdr_t ); iWARPEM_Multiplexed_Msg_Hdr_t *MultHdr = (iWARPEM_Multiplexed_Msg_Hdr_t*)mReceiveBuffer->GetHdrPtr( &hdrlen ); AssertLogLine( hdrlen == sizeof( iWARPEM_Multiplexed_Msg_Hdr_t ) ) << "Retrieval of HdrPtr failed: len=" << hdrlen << " expected=" << sizeof(iWARPEM_Multiplexed_Msg_Hdr_t) << EndLogLine; MultHdr->ClientID = be64toh( MultHdr->ClientID ); *aClient = MultHdr->ClientID; hdrlen = sizeof( iWARPEM_Message_Hdr_t ); char* databuf = mReceiveBuffer->GetHdrPtr( &hdrlen ); memcpy( aBuffer, databuf, hdrlen ); } else if( aSize ) mReceiveBuffer->GetData( &aBuffer, (size_t*)&aSize ); return IWARPEM_SUCCESS; }
/***************************************** * Remove and deallocate the old from the local store *****************************************/ static inline skv_status_t RemoveLocal( skv_cmd_RIU_req_t *aReq, int aKeySize, char *aAddr, skv_pds_manager_if_t *aPDSManager ) { skv_status_t status = aPDSManager->Remove( aReq->mPDSId, aReq->mKeyValue.mData, aKeySize ); AssertLogLine( status == SKV_SUCCESS ) << "skv_local_kv_inmem::RemoveLocal():: ERROR: " << " status: " << skv_status_to_string( status ) << EndLogLine; return status; }
static skv_status_t Release( skv_client_server_conn_t* aConn, skv_client_ccb_t* aCCB ) { BegLogLine( SKV_CLIENT_ACTIVE_BCAST_COMMAND_SM_LOG ) << "skv_client_active_bcast_command_sm::Release(): Entering" << EndLogLine; /********************************************************************** * Release resources **********************************************************************/ // Command is completed, release resources int CommandOrd = aCCB->GetCmdOrd(); aConn->ReleaseCmdOrdinal( CommandOrd ); aCCB->mCCBMgrIF->AddToDoneCCBQueue( aCCB ); // Release LMRs it_lmr_handle_t lmrHdl = aCCB->mCommand.mCommandBundle.mCommandActiveBcast.mBufferLMRHdl; BegLogLine( SKV_CLIENT_ACTIVE_BCAST_COMMAND_SM_LOG ) << "skv_client_active_bcast_command_sm::Release(): About to call it_lmr_free( ): " << " lmr: " << (void *) lmrHdl << EndLogLine; it_status_t status = it_lmr_free( lmrHdl ); AssertLogLine( status == IT_SUCCESS ) << "skv_client_active_bcast_command_sm::Release(): ERROR:: it_lmr_free() failed" << " lmr: " << (void *) lmrHdl << " status: " << status << EndLogLine; BegLogLine( SKV_CLIENT_ACTIVE_BCAST_COMMAND_SM_LOG ) << "skv_client_active_bcast_command_sm::Release(): Leaving" << EndLogLine; return SKV_SUCCESS; /**********************************************************************/ }
static inline skv_status_t dist_post_response( skv_server_ep_state_t *aEPState, skv_server_ccb_t *aCommand, int aCommandOrdinal, int *aSeqNo, skv_status_t rc, skv_distribution_t *aDist ) { // Get the distribution skv_cmd_retrieve_dist_resp_t* RetrieveDistResp = (skv_cmd_retrieve_dist_resp_t *) aCommand->GetSendBuff(); // RetrieveDistResp->mHdr = RetrieveDistReq->mHdr; RetrieveDistResp->mHdr.mEvent = SKV_CLIENT_EVENT_CMD_COMPLETE; RetrieveDistResp->mStatus = SKV_SUCCESS; memcpy( (char *) & RetrieveDistResp->mDist, (char *) aDist, sizeof( skv_distribution_t ) ); RetrieveDistResp->EndianConvert() ; skv_status_t status = aEPState->Dispatch( aCommand, aSeqNo, aCommandOrdinal ); BegLogLine( SKV_SERVER_RETRIEVE_DIST_LOG ) << "skv_server_retrieve_dist_command_sm::dist_post_response():: " << " Sending to client: " << *RetrieveDistResp << EndLogLine; AssertLogLine( status == SKV_SUCCESS ) << "skv_server_retrieve_dist_command_sm::Execute():: ERROR: " << " status: " << skv_status_to_string( status ) << EndLogLine; return status; }
int WaitForEvents( int aMaxEventCount ) { AssertLogLine( aMaxEventCount >= SKV_SERVER_AEVD_EVENTS_MAX_COUNT ) << "ERROR: " << " aMaxEventCount: " << aMaxEventCount << " SKV_SERVER_AEVD_EVENTS_MAX_COUNT: " << SKV_SERVER_AEVD_EVENTS_MAX_COUNT << EndLogLine; size_t itEventCount = 0; // \todo this is not the right place because we're in the event source here, not in the sink it_status_t istatus = itx_aevd_wait( mAevd_Hdl, 0, SKV_SERVER_AEVD_EVENTS_MAX_COUNT, mAevdEvents, &itEventCount ); StrongAssertLogLine( istatus == IT_SUCCESS ) << "ERROR: " << " istatus: " << istatus << EndLogLine; return itEventCount; }
/*** * skv_client_internal_t::GetNextLocalElement:: * Desc: Get the next element in the cursor pointed to a node id * returns: SKV_SUCCESS on success or error code ***/ skv_status_t skv_client_internal_t:: GetNextLocalElement( skv_client_cursor_handle_t aCursorHdl, char* aRetrievedKeyBuffer, int* aRetrievedKeySize, int aRetrievedKeyMaxSize, char* aRetrievedValueBuffer, int* aRetrievedValueSize, int aRetrievedValueMaxSize, skv_cursor_flags_t aFlags ) { BegLogLine( SKV_CLIENT_CURSOR_LOG ) << "skv_client_internal_t::GetNextLocalElement():: Entering..." << EndLogLine; StrongAssertLogLine( mState = SKV_CLIENT_STATE_CONNECTED ) << "skv_client_internal_t::GetNextLocalElement():: ERROR:: " << " mState: " << mState << EndLogLine; AssertLogLine( aCursorHdl->mCachedKeysCount > 0 ) << "skv_client_internal_t::GetNextLocalElement():: ERROR:: aCursorHdl->mCachedKeysCount > 0 " << " aCursorHdl->mCachedKeysCount: " << aCursorHdl->mCachedKeysCount << EndLogLine; if( aCursorHdl->mCurrentCachedKeyIdx == aCursorHdl->mCachedKeysCount ) { // Reached the end of the cached records char* StartingKeyBuffer = aCursorHdl->mPrevCachedKey + sizeof(int); int StartingKeyBufferSize = *((int *) aCursorHdl->mPrevCachedKey); BegLogLine( SKV_CLIENT_CURSOR_LOG ) << "Endian-converting StartingKeyBufferSize=" << StartingKeyBufferSize << EndLogLine ; StartingKeyBufferSize=ntohl(StartingKeyBufferSize) ; skv_status_t status = RetrieveNKeys( aCursorHdl, StartingKeyBuffer, StartingKeyBufferSize, aFlags ); if( status != SKV_SUCCESS ) return status; } skv_status_t status = RetrieveNextCachedKey( aCursorHdl, aRetrievedKeyBuffer, aRetrievedKeySize, aRetrievedKeyMaxSize, aRetrievedValueBuffer, aRetrievedValueSize, aRetrievedValueMaxSize, aFlags ); BegLogLine( SKV_CLIENT_CURSOR_LOG ) << "skv_client_internal_t::GetNextLocalElement():: Leaving..." << EndLogLine; return status; }
/*** * skv_client_internal_t::GetFirstLocalElement:: * Desc: Get the first element in the cursor * returns: SKV_SUCCESS on success or error code ***/ skv_status_t skv_client_internal_t:: GetFirstLocalElement( skv_client_cursor_handle_t aCursorHdl, char* aRetrievedKeyBuffer, int* aRetrievedKeySize, int aRetrievedKeyMaxSize, char* aRetrievedValueBuffer, int* aRetrievedValueSize, int aRetrievedValueMaxSize, skv_cursor_flags_t aFlags ) { BegLogLine( SKV_CLIENT_RETRIEVE_N_KEYS_DIST_LOG ) << "skv_client_internal_t::GetFirstLocalElement():: Entering..." << EndLogLine; StrongAssertLogLine( mState = SKV_CLIENT_STATE_CONNECTED ) << "skv_client_internal_t::GetFirstLocalElement():: ERROR:: " << " mState: " << mState << EndLogLine; int StartSizeToRetrieve = 0; char* StartToRetrive = NULL; if( aFlags & SKV_CURSOR_WITH_STARTING_KEY_FLAG ) { StartToRetrive = aRetrievedKeyBuffer; StartSizeToRetrieve = *aRetrievedKeySize; } BegLogLine( SKV_CLIENT_CURSOR_LOG ) << "Endian-converting StartSizeToRetrieve=" << StartSizeToRetrieve << EndLogLine ; StartSizeToRetrieve=ntohl(StartSizeToRetrieve) ; skv_status_t status = RetrieveNKeys( aCursorHdl, StartToRetrive, StartSizeToRetrieve, (skv_cursor_flags_t) ( (int)aFlags | SKV_CURSOR_RETRIEVE_FIRST_ELEMENT_FLAG )); // return only if there were no keys retrieved. if( ( aCursorHdl->mCurrentCachedKeyIdx == aCursorHdl->mCachedKeysCount ) && ( status != SKV_SUCCESS ) ) return status; AssertLogLine( aCursorHdl->mCachedKeysCount > 0 ) << "skv_client_internal_t::GetFirstLocalElement():: ERROR:: " << " aCursorHdl->mCachedKeysCount: " << aCursorHdl->mCachedKeysCount << EndLogLine; status = RetrieveNextCachedKey( aCursorHdl, aRetrievedKeyBuffer, aRetrievedKeySize, aRetrievedKeyMaxSize, aRetrievedValueBuffer, aRetrievedValueSize, aRetrievedValueMaxSize, aFlags ); BegLogLine( SKV_CLIENT_CURSOR_LOG ) << "skv_client_internal_t::GetFirstLocalElement():: Leaving..." << EndLogLine; return status; }
/*** * skv_client_internal_t::RetrieveNKeys:: * returns: SKV_SUCCESS on success or error code ***/ skv_status_t skv_client_internal_t:: RetrieveNKeys( skv_client_cursor_handle_t aCursorHdl, char* aStartingKeyBuffer, int aStartingKeyBufferSize, skv_cursor_flags_t aFlags ) { BegLogLine( SKV_CLIENT_RETRIEVE_N_KEYS_DIST_LOG ) << "skv_client_internal_t::RetrieveNKeys():: Entering..." << EndLogLine; StrongAssertLogLine( mState = SKV_CLIENT_STATE_CONNECTED ) << "skv_client_internal_t::RetrieveNKeys()::" << " aFlags: " << aFlags << " mState: " << mState << EndLogLine; /************************************************** * Check limits *************************************************/ BegLogLine(SKV_CLIENT_RETRIEVE_N_KEYS_DIST_LOG) << "aStartingKeyBufferSize=" << aStartingKeyBufferSize << " SKV_KEY_LIMIT=" << SKV_KEY_LIMIT << EndLogLine ; if( aStartingKeyBufferSize > SKV_KEY_LIMIT ) { BegLogLine(SKV_CLIENT_RETRIEVE_N_KEYS_DIST_LOG) << "Returning SKV_ERRNO_KEY_TOO_LARGE" << EndLogLine ; return SKV_ERRNO_KEY_TOO_LARGE; } // Starting a new command, get a command control block skv_client_ccb_t* CmdCtrlBlk; skv_status_t rsrv_status = mCommandMgrIF.Reserve( & CmdCtrlBlk ); if( rsrv_status != SKV_SUCCESS ) return rsrv_status; /*************************************************/ /************************************************** * Init cursor state *************************************************/ aCursorHdl->ResetCurrentCachedState(); /*************************************************/ /****************************************************** * Set the client-server protocol send ctrl msg buffer *****************************************************/ char* SendCtrlMsgBuff = CmdCtrlBlk->GetSendBuff(); int RoomForData = SKV_CONTROL_MESSAGE_SIZE - sizeof( skv_cmd_retrieve_n_keys_req_t ) - SKV_CHECKSUM_BYTES; AssertLogLine( RoomForData >= 0 ) << "skv_client_internal_t::RetrieveNKeys():: ERROR:: " << " RoomForData: " << RoomForData << " sizeof( skv_cmd_retrieve_n_keys_KeyFitsInMsg_req_t ): " << sizeof( skv_cmd_retrieve_n_keys_req_t ) << " SKV_CONTROL_MESSAGE_SIZE: " << SKV_CONTROL_MESSAGE_SIZE << EndLogLine; int KeyFitsInCtrlMsg = (aStartingKeyBufferSize <= RoomForData); skv_cmd_retrieve_n_keys_req_t* Req = (skv_cmd_retrieve_n_keys_req_t *) SendCtrlMsgBuff; // If the key fits into the control message it's safe to // send the list of buffers to cached keys Req->Init( aCursorHdl->mCurrentNodeId, & mConnMgrIF, aCursorHdl->mPdsId, SKV_COMMAND_RETRIEVE_N_KEYS, SKV_SERVER_EVENT_TYPE_IT_DTO_RETRIEVE_N_KEYS_CMD, CmdCtrlBlk, aFlags, aStartingKeyBuffer, aStartingKeyBufferSize, KeyFitsInCtrlMsg, aCursorHdl->mKeysDataLMRHdl, aCursorHdl->mKeysDataRMRHdl, aCursorHdl->mCachedKeys, SKV_CLIENT_MAX_CURSOR_KEYS_TO_CACHE ); /*****************************************************/ Req->EndianConvert() ; BegLogLine(SKV_CLIENT_RETRIEVE_N_KEYS_DIST_LOG) << "mEventType=" << Req->mHdr.mEventType << EndLogLine ; BegLogLine( SKV_CLIENT_RETRIEVE_N_KEYS_DIST_LOG ) << "skv_client_internal_t: Created RetrieveN request:" << " KeyDataAddr: " << (uint64_t)aCursorHdl->mCachedKeys << EndLogLine; /****************************************************** * Transit the CCB to an appropriate state *****************************************************/ CmdCtrlBlk->Transit( SKV_CLIENT_COMMAND_STATE_WAITING_FOR_VALUE_TX_ACK ); /*****************************************************/ /****************************************************** * Set the local client state used on response *****************************************************/ CmdCtrlBlk->mCommand.mType = SKV_COMMAND_RETRIEVE_N_KEYS; CmdCtrlBlk->mCommand.mCommandBundle.mCommandRetrieveNKeys.mCachedKeysCountPtr = & aCursorHdl->mCachedKeysCount; CmdCtrlBlk->mCommand.mCommandBundle.mCommandRetrieveNKeys.mCachedKeysCountMax = SKV_CLIENT_MAX_CURSOR_KEYS_TO_CACHE; /*****************************************************/ BegLogLine(SKV_CLIENT_RETRIEVE_N_KEYS_DIST_LOG) << "mEventType=" << Req->mHdr.mEventType << EndLogLine ; skv_status_t status = mConnMgrIF.Dispatch( aCursorHdl->mCurrentNodeId, CmdCtrlBlk ); AssertLogLine( status == SKV_SUCCESS ) << "skv_client_internal_t::RetrieveNKeys():: " << " status: " << skv_status_to_string( status ) << EndLogLine; BegLogLine(SKV_CLIENT_RETRIEVE_N_KEYS_DIST_LOG) << "mEventType=" << Req->mHdr.mEventType << EndLogLine ; status = Wait( CmdCtrlBlk ); status=(skv_status_t) ntohl(status) ; BegLogLine(SKV_CLIENT_RETRIEVE_N_KEYS_DIST_LOG) << "mEventType=" << Req->mHdr.mEventType << EndLogLine ; BegLogLine( SKV_CLIENT_RETRIEVE_N_KEYS_DIST_LOG ) << "skv_client_internal_t::RetrieveNKeys():: Leaving..." << " status: " << skv_status_to_string( status ) << EndLogLine; return status; }
/*** * skv_client_internal_t::RetrieveNextCachedKey:: * NOTE: Assumes that the key exists in cache * returns: SKV_SUCCESS on success or error code ***/ skv_status_t skv_client_internal_t:: RetrieveNextCachedKey( skv_client_cursor_handle_t aCursorHdl, char* aRetrievedKeyBuffer, int* aRetrievedKeySize, int aRetrievedKeyMaxSize, char* aRetrievedValueBuffer, int* aRetrievedValueSize, int aRetrievedValueMaxSize, skv_cursor_flags_t aFlags ) { BegLogLine( SKV_CLIENT_RETRIEVE_N_KEYS_DIST_LOG ) << "skv_client_internal_t::RetrieveNextCachedKey():: Entering: " << " aCursorHdl: " << (void *) aCursorHdl << " aRetrievedKeyBuffer: " << (void *) aRetrievedKeyBuffer << " *aRetrievedKeySize: " << *aRetrievedKeySize << " aRetrievedKeyMaxSize: " << aRetrievedKeyMaxSize << " aRetrievedValueBuffer: " << (void *) aRetrievedValueBuffer << " aRetrievedValueSize: " << aRetrievedValueSize << " aRetrievedValueMaxSize: " << aRetrievedValueMaxSize << " mCurrentCachedKey: " << (void*)aCursorHdl->mCurrentCachedKey << " mCachedKeys: " << (void*)aCursorHdl->mCachedKeys << " aFlags: " << aFlags << " Key: " << *(int*)(aCursorHdl->mCurrentCachedKey + sizeof(int)) << EndLogLine; BegLogLine( SKV_CLIENT_RETRIEVE_N_KEYS_DATA_LOG ) << " CachedKeys@"<< (void*)aCursorHdl->mCachedKeys << ": " << HexDump( aCursorHdl->mCachedKeys, SKV_CACHED_KEYS_BUFFER_SIZE ) << EndLogLine; AssertLogLine( aCursorHdl->mCurrentCachedKey >= aCursorHdl->mCachedKeys && aCursorHdl->mCurrentCachedKey < (aCursorHdl->mCachedKeys + SKV_CACHED_KEYS_BUFFER_SIZE ) ) << "skv_client_internal_t::RetrieveNextCachedKey():: ERROR:: " << " aCursorHdl->mCurrentCachedKey: " << (void *) aCursorHdl->mCurrentCachedKey << " aCursorHdl->mCachedKeysCount: " << aCursorHdl->mCachedKeysCount << EndLogLine; int CachedKeySize = *((int *) aCursorHdl->mCurrentCachedKey ); BegLogLine(SKV_CLIENT_RETRIEVE_N_KEYS_DIST_LOG) << "Endian-converting cached key size=" << CachedKeySize << EndLogLine ; CachedKeySize=htonl(CachedKeySize) ; if( CachedKeySize > aRetrievedKeyMaxSize ) { BegLogLine( SKV_CLIENT_RETRIEVE_N_KEYS_DIST_LOG ) << "skv_client_internal_t::RetrieveNextCachedKey():: Leaving with ERROR:: " << " CachedKeySize: " << CachedKeySize << " aRetrievedKeyMaxSize: " << aRetrievedKeyMaxSize << " SKV_ERRNO_KEY_SIZE_OVERFLOW" << EndLogLine; return SKV_ERRNO_KEY_SIZE_OVERFLOW; } *aRetrievedKeySize = CachedKeySize; char* SrcKeyBuffer = aCursorHdl->mCurrentCachedKey + sizeof(int); memcpy( aRetrievedKeyBuffer, SrcKeyBuffer, CachedKeySize ); BegLogLine( SKV_CLIENT_RETRIEVE_N_KEYS_DIST_LOG ) << "skv_client_internal_t::RetrieveNextCachedKey():: " << " CachedKeySize: " << CachedKeySize << " aCursorHdl->mCurrentCachedKeyIdx: " << aCursorHdl->mCurrentCachedKeyIdx << " aCursorHdl->mCachedKeysCount: " << aCursorHdl->mCachedKeysCount << " Now retrieving value..." << EndLogLine; skv_status_t status = Retrieve( & aCursorHdl->mPdsId, aRetrievedKeyBuffer, *aRetrievedKeySize, aRetrievedValueBuffer, aRetrievedValueMaxSize, aRetrievedValueSize, 0, SKV_COMMAND_RIU_FLAGS_NONE ); // Need to set this, to be able to have access to the last key. // This is the starting key for the next batch of keys if( (aCursorHdl->mCurrentCachedKeyIdx + 1) == aCursorHdl->mCachedKeysCount ) aCursorHdl->mPrevCachedKey = aCursorHdl->mCurrentCachedKey; aCursorHdl->mCurrentCachedKey += (sizeof( int ) + CachedKeySize ); aCursorHdl->mCurrentCachedKeyIdx++; BegLogLine( SKV_CLIENT_RETRIEVE_N_KEYS_DIST_LOG ) << "skv_client_internal_t::RetrieveNextCachedKey():: Leaving " << EndLogLine; return status; }
static skv_status_t Execute( skv_client_conn_manager_if_t * aConnMgrIF, skv_client_server_conn_t* aConn, skv_client_ccb_t* aCCB ) { char* RecvBuff = aCCB->GetRecvBuff(); skv_server_to_client_cmd_hdr_t* Hdr = (skv_server_to_client_cmd_hdr_t *) RecvBuff; skv_client_command_state_t State = aCCB->mState; skv_client_event_t Event = Hdr->mEvent; BegLogLine( SKV_CLIENT_RETRIEVE_COMMAND_SM_LOG ) << "skv_client_retrieve_command_sm::Execute:: Entering... " << " State: " << skv_client_command_state_to_string( State ) << " Event: " << skv_client_event_to_string( Event ) << EndLogLine; skv_status_t status = SKV_SUCCESS; switch( State ) { case SKV_CLIENT_COMMAND_STATE_IDLE: case SKV_CLIENT_COMMAND_STATE_DONE: { StrongAssertLogLine( 0 ) << "skv_client_retrieve_command_sm::Execute:: ERROR:: Invalid State: " << " State: " << skv_client_command_state_to_string( State ) << EndLogLine; break; } case SKV_CLIENT_COMMAND_STATE_WAITING_FOR_VALUE_TX_ACK: { switch( Event ) { case SKV_CLIENT_EVENT_RDMA_WRITE_VALUE_ACK: { // Operation has completed. skv_cmd_retrieve_value_rdma_write_ack_t* Ack = (skv_cmd_retrieve_value_rdma_write_ack_t *) RecvBuff; int retrievedSize = Ack->mValue.mValueSize; // if the server indicates that there's more data, then only get the amount that fits into user buffer! if( Ack->mStatus == SKV_ERRNO_VALUE_TOO_LARGE ) { retrievedSize = aCCB->mCommand.mCommandBundle.mCommandRetrieve.mValueRequestedSize; // Ack->mStatus = SKV_SUCCESS; } // get value data out of response if flags indicate that it fit if( aCCB->mCommand.mCommandBundle.mCommandRetrieve.mFlags & SKV_COMMAND_RIU_RETRIEVE_VALUE_FIT_IN_CTL_MSG ) { void* valueBuffer = aCCB->mCommand.mCommandBundle.mCommandRetrieve.mValueBufferRef.mValueAddr; BegLogLine( SKV_CLIENT_RETRIEVE_COMMAND_SM_LOG ) << "skv_client_retrieve_command_sm::Execute(): about to copy retrieved data" << " uBuf: " << (void*)valueBuffer << " rBuf: " << (void*)Ack->mValue.mData << " size: " << retrievedSize << " CCB: " << (void*)aCCB << " value: " << (void*)(*(uint64_t*)(Ack->mValue.mData)) #ifdef SKV_DEBUG_MSG_MARKER << " msg: " << Ack->mHdr.mMarker #endif << EndLogLine; memcpy( valueBuffer, Ack->mValue.mData, retrievedSize ); } aCCB->mStatus = Ack->mStatus; // user wanted to know the actual retrieved size if( aCCB->mCommand.mCommandBundle.mCommandRetrieve.mValueRetrievedSize != NULL ) *aCCB->mCommand.mCommandBundle.mCommandRetrieve.mValueRetrievedSize = Ack->mValue.mValueSize; status = Release( aConn, aCCB ); AssertLogLine( status == SKV_SUCCESS ) << "skv_client_retrieve_command_sm::Execute():: ERROR:: Release failed: " << " status: " << status << EndLogLine; aCCB->Transit( SKV_CLIENT_COMMAND_STATE_DONE ); break; } case SKV_CLIENT_EVENT_ERROR: { // Server returned an error. skv_cmd_err_resp_t* ErrResp = (skv_cmd_err_resp_t *) RecvBuff; BegLogLine( SKV_CLIENT_RETRIEVE_COMMAND_SM_LOG ) << "skv_client_retrieve_command_sm::Execute:: ERROR response from server: " << " status: " << ErrResp->mStatus << EndLogLine; aCCB->mStatus = ErrResp->mStatus; status = Release( aConn, aCCB ); AssertLogLine( status == SKV_SUCCESS ) << "skv_client_retrieve_command_sm::Execute():: ERROR:: Release failed: " << " status: " << status << EndLogLine; aCCB->Transit( SKV_CLIENT_COMMAND_STATE_DONE ); break; } default: { StrongAssertLogLine( 0 ) << "skv_client_retrieve_command_sm::Execute:: ERROR:: Invalid State: " << " State: " << skv_client_command_state_to_string( State ) << " Event: " << skv_client_event_to_string( Event ) << EndLogLine; break; } } break; } default: { StrongAssertLogLine( 0 ) << "skv_client_retrieve_command_sm::ProcessCCB:: ERROR:: Invalid State: " << " State: " << skv_client_command_state_to_string( State ) << EndLogLine; break; } } BegLogLine( SKV_CLIENT_RETRIEVE_COMMAND_SM_LOG ) << "skv_client_retrieve_command_sm::Execute:: Leaving... " << EndLogLine; return status; }
iWARPEM_Status_t InsertMessage( iWARPEM_StreamId_t aClientID, const iWARPEM_Message_Hdr_t* aHdr, const char *aData, int aSize, bool aForceNoFlush = false ) { if( aSize > IT_API_MULTIPLEX_SOCKET_BUFFER_SIZE - sizeof( it_api_multiplexed_socket_message_header_t ) ) { BegLogLine( 1 ) << "Requested message size exceeds send buffer size." << " MAX: " << IT_API_MULTIPLEX_SOCKET_BUFFER_SIZE << " actual: " << aSize << EndLogLine; return IWARPEM_SUCCESS; } iWARPEM_Status_t status = IWARPEM_SUCCESS; if( GetSendSpace() < aSize ) { AssertLogLine( aForceNoFlush == false ) << "Remaining size too small for message but parameters prevent flush." << " remaining=" << GetSendSpace() << " aSize=" << aSize << EndLogLine; status = FlushSendBuffer(); BegLogLine( FXLOG_IT_API_O_SOCKETS_MULTIPLEX_LOG ) << "Remaining space is too small. Sending existing data first.." << " req_size: " << aSize << " rem_space: " << GetSendSpace() << EndLogLine; } pthread_spin_lock( &mAccessLock ); // create the multiplex header from the client id iWARPEM_StreamId_t *client = (iWARPEM_StreamId_t*)&aClientID; mSendBuffer->AddHdr( (const char*)client, sizeof( iWARPEM_StreamId_t ) ); if( aHdr ) mSendBuffer->AddHdr( (const char*)aHdr, sizeof( iWARPEM_Message_Hdr_t ) ); if( aSize > 0 ) mSendBuffer->AddData( aData, aSize ); pthread_spin_unlock( &mAccessLock ); #if (FXLOG_IT_API_O_SOCKETS_MULTIPLEX_LOG != 0) iWARPEM_Msg_Type_t MsgType = iWARPEM_UNKNOWN_REQ_TYPE; if( aHdr ) { MsgType = aHdr->mMsg_Type; } BegLogLine( FXLOG_IT_API_O_SOCKETS_MULTIPLEX_LOG ) << "Inserted Message to send buffer: " << " ClientId: " << aClientID << " msg_size: " << aSize << " msg_type: " << iWARPEM_Msg_Type_to_string( MsgType ) << " bytes in buffer: " << mSendBuffer->GetDataLen() << EndLogLine; #endif #ifdef MULTIPLEX_STATISTICS mMsgCount++; #endif mNeedsBufferFlush = true; // initiate a send of data once we've filled up the buffer beyond a threshold if( (!aForceNoFlush) && ( mSendBuffer->FlushRecommended() ) ) { BegLogLine( FXLOG_IT_API_O_SOCKETS_MULTIPLEX_LOG ) << "Buffer reached threshold fill state. Flushing..." << EndLogLine; status = FlushSendBuffer(); } return status; }
static skv_status_t Execute( skv_server_internal_event_manager_if_t* aEventQueueManager, skv_local_kv_t *aLocalKV, skv_server_ep_state_t *aEPState, int aCommandOrdinal, skv_server_event_t *aEvent, int *aSeqNo ) { skv_server_ccb_t* Command = aEPState->GetCommandForOrdinal( aCommandOrdinal ); skv_server_command_state_t State = Command->mState; // skv_server_event_type_t EventType = aEvent->mEventType; skv_server_event_type_t EventType = aEvent->mCmdEventType; BegLogLine( SKV_SERVER_RETRIEVE_DIST_LOG ) << "skv_server_retrieve_dist_command_sm::Execute:: " << " State: " << State << " EventType: " << EventType << " Command: " << (void *) Command << EndLogLine; switch( State ) { case SKV_SERVER_COMMAND_STATE_LOCAL_KV_INDEX_OP: { switch( EventType ) { case SKV_SERVER_EVENT_TYPE_LOCAL_KV_ERROR: case SKV_SERVER_EVENT_TYPE_LOCAL_KV_CMPL: { BegLogLine( SKV_SERVER_RETRIEVE_DIST_LOG ) << "skv_server_retrieve_dist_command_sm::Execute():: returned from async" << " PDSId: " << Command->mLocalKVData.mPDSOpen.mPDSId << EndLogLine; skv_status_t status = dist_post_response( aEPState, Command, aCommandOrdinal, aSeqNo, Command->mLocalKVrc, Command->mLocalKVData.mDistribution.mDist ); Command->Transit( SKV_SERVER_COMMAND_STATE_INIT ); break; } default: { StrongAssertLogLine( 0 ) << "skv_server_retrieve_dist_command_sm:: Execute():: ERROR: Event not recognized" << " CommandState: " << Command->mState << " EventType: " << EventType << EndLogLine; break; } } break; } case SKV_SERVER_COMMAND_STATE_INIT: { switch( EventType ) { case SKV_SERVER_EVENT_TYPE_IT_DTO_RETRIEVE_DIST_CMD: { AssertLogLine( sizeof(skv_cmd_retrieve_dist_resp_t) <= SKV_CONTROL_MESSAGE_SIZE ) << "skv_server_retrieve_dist_command_sm::Execute():: ERROR: " << " sizeof( skv_cmd_retrieve_dist_resp_t ): " << sizeof( skv_cmd_retrieve_dist_resp_t ) << " SKV_CONTROL_MESSAGE_SIZE: " << SKV_CONTROL_MESSAGE_SIZE << EndLogLine; skv_distribution_t *dist; skv_local_kv_cookie_t *cookie = &Command->mLocalKVCookie; cookie->Set( aCommandOrdinal, aEPState ); skv_status_t status = aLocalKV->GetDistribution( &dist, cookie ); switch( status ) { case SKV_ERRNO_LOCAL_KV_EVENT: create_multi_stage( aEPState, aLocalKV, Command, aCommandOrdinal ); Command->Transit( SKV_SERVER_COMMAND_STATE_LOCAL_KV_INDEX_OP ); break; case SKV_ERRNO_COMMAND_LIMIT_REACHED: create_multi_stage( aEPState, aLocalKV, Command, aCommandOrdinal ); aEventQueueManager->Enqueue( aEvent ); break; default: dist_post_response( aEPState, Command, aCommandOrdinal, aSeqNo, status, dist ); Command->Transit( SKV_SERVER_COMMAND_STATE_INIT ); } break; } default: { StrongAssertLogLine( 0 ) << "skv_server_retrieve_dist_command_sm:: Execute():: ERROR: Event not recognized" << " CommandState: " << Command->mState << " EventType: " << EventType << EndLogLine; break; } } break; } default: { StrongAssertLogLine( 0 ) << "skv_server_retrieve_dist_command_sm:: Execute():: ERROR: State not recognized" << " CommandState: " << Command->mState << EndLogLine; break; } } return SKV_SUCCESS; }
skv_status_t skv_local_kv_inmem::Insert( skv_cmd_RIU_req_t *aReq, skv_status_t aCmdStatus, skv_lmr_triplet_t *aStoredValueRep, skv_lmr_triplet_t *aValueRDMADest, skv_local_kv_cookie_t *aCookie ) { skv_status_t status = SKV_ERRNO_UNSPECIFIED_ERROR; int KeySize = aReq->mKeyValue.mKeySize; int ValueSize = aReq->mKeyValue.mValueSize; int TotalValueSize = ValueSize + aReq->mOffset; AssertLogLine( TotalValueSize >= 0 && TotalValueSize < SKV_VALUE_LIMIT ) << "skv_local_kv_inmem::Insert():: ERROR: " << "TotalValueSize: " << TotalValueSize << EndLogLine; // Check if there's enough space for Key/Value int KeyValueSize = KeySize + TotalValueSize; BegLogLine( SKV_LOCAL_KV_BACKEND_LOG) << "skv_local_kv_inmem::Insert():: Entering with: " << " KeySize: " << KeySize << " ValueSize: " << ValueSize << " TotalValueSize: " << TotalValueSize << " KeyValueSize: " << KeyValueSize << " Flags: " << (void*)aReq->mFlags << EndLogLine; int LocalValueSize = aStoredValueRep->GetLen(); /******************************************************** * Record Exists ********************************************************/ if( aCmdStatus == SKV_SUCCESS ) { switch( aReq->mFlags & (SKV_COMMAND_RIU_INSERT_EXPANDS_VALUE | SKV_COMMAND_RIU_INSERT_OVERWRITE_VALUE_ON_DUP | SKV_COMMAND_RIU_UPDATE | SKV_COMMAND_RIU_APPEND) ) { case SKV_COMMAND_RIU_INSERT_OVERWRITE_VALUE_ON_DUP: /******************************************************** * we overwrite WITHIN EXISTING RECORD BOUNDS ONLY ********************************************************/ BegLogLine( SKV_LOCAL_KV_BACKEND_LOG ) << "skv_local_kv_inmem::Insert():: OVERWRITE_ON_DUP" << " ValueSize: " << ValueSize << " offs: " << aReq->mOffset << EndLogLine; if( LocalValueSize < TotalValueSize ) { status = SKV_ERRNO_VALUE_TOO_LARGE; break; } aValueRDMADest->InitAbs( aStoredValueRep->GetLMRHandle(), (char *) aStoredValueRep->GetAddr() + aReq->mOffset, ValueSize ); status = SKV_SUCCESS; break; case SKV_COMMAND_RIU_INSERT_EXPANDS_VALUE: /******************************************************** * Record Exists, Expansion Allowed ********************************************************/ // Expandable insert option is set and the record is found // Do we need to expand? BegLogLine( SKV_LOCAL_KV_BACKEND_LOG ) << "skv_local_kv_inmem::Insert():: EXPAND_VALUE" << " LocalValueSize: " << LocalValueSize << " ValueSize: " << ValueSize << " TotalValueSize: " << TotalValueSize << EndLogLine; if( TotalValueSize > LocalValueSize ) { if( !(aReq->mFlags & SKV_COMMAND_RIU_INSERT_OVERLAPPING) ) { BegLogLine( SKV_LOCAL_KV_BACKEND_LOG ) << "skv_local_kv_inmem::Insert():: overlapping inserts not allowed " << " Req->mOffset: " << aReq->mOffset << " LocalValueSize: " << LocalValueSize << " requires: SKV_COMMAND_RIU_INSERT_OVERLAPPING to be set" << EndLogLine; status = SKV_ERRNO_INSERT_OVERLAP; break; } /*************************************************************** * Expand Value **************************************************************/ // Allocate new skv_lmr_triplet_t NewRecordAllocRep; status = AllocateAndMoveKey( aReq, KeyValueSize, &NewRecordAllocRep, &mPDSManager ); if( status != SKV_SUCCESS ) break; // copy existing value to new allocated record char* RecordPtr = (char *) NewRecordAllocRep.GetAddr() + KeySize; memcpy( RecordPtr, (void *) aStoredValueRep->GetAddr(), LocalValueSize ); RecordPtr += aReq->mOffset; // LocalValueSize; // Prepare LMR to cover the new to read fraction of the value only aValueRDMADest->InitAbs( NewRecordAllocRep.GetLMRHandle(), RecordPtr, ValueSize ); // Remove old record and deallocate space status = RemoveLocal( aReq, KeySize, (char *) aStoredValueRep->GetAddr(), &mPDSManager ); // insert new record status = InsertLocal( aReq, (char *) NewRecordAllocRep.GetAddr(), KeySize, TotalValueSize, &mPDSManager, mMyRank ); /*******************************************************************/ } else { // Record was found, but no expansion is needed // Just make sure that the rdma_read is done to the // appropriate offset aValueRDMADest->InitAbs( aStoredValueRep->GetLMRHandle(), (char *) aStoredValueRep->GetAddr() + aReq->mOffset, ValueSize ); status = SKV_SUCCESS; } break; /********************************************************/ case SKV_COMMAND_RIU_UPDATE: /******************************************************** * Record exists and we update with POTENTIAL REALLOCATION of the record ********************************************************/ // if the new size is exactly the previous size, there's nothing to adjust // just make sure the LMR is pointing to the right location if( (uint64_t)ValueSize == aStoredValueRep->GetLen() ) { BegLogLine( SKV_LOCAL_KV_BACKEND_LOG ) << "skv_local_kv_inmem::Insert():: UPDATE same length record, overwriting..." << " ValueSize: " << ValueSize << " offs: " << aReq->mOffset << EndLogLine; aValueRDMADest->InitAbs( aStoredValueRep->GetLMRHandle(), (char *) aStoredValueRep->GetAddr() + aReq->mOffset, ValueSize ); status = SKV_SUCCESS; } // reallocate, copy and insert new updated record, if the size is different else { BegLogLine( SKV_LOCAL_KV_BACKEND_LOG ) << "skv_local_kv_inmem::Insert():: UPDATE different length record, reallocating..." << " ValueSize: " << ValueSize << " offs: " << aReq->mOffset << EndLogLine; status = RemoveLocal( aReq, KeySize, (char *) aStoredValueRep->GetAddr(), &mPDSManager ); skv_lmr_triplet_t NewRecordAllocRep; status = AllocateAndMoveKey( aReq, KeyValueSize, &NewRecordAllocRep, &mPDSManager ); if( status != SKV_SUCCESS ) break; aValueRDMADest->InitAbs( NewRecordAllocRep.GetLMRHandle(), (char *) NewRecordAllocRep.GetAddr() + KeySize + aReq->mOffset, ValueSize ); status = InsertLocal( aReq, (char *) NewRecordAllocRep.GetAddr(), KeySize, TotalValueSize, &mPDSManager, mMyRank ); } break; /********************************************************/ case SKV_COMMAND_RIU_APPEND: /******************************************************** * Record Exists, Append new data ********************************************************/ TotalValueSize = LocalValueSize + ValueSize; KeyValueSize = KeySize + TotalValueSize; BegLogLine( SKV_LOCAL_KV_BACKEND_LOG ) << "skv_local_kv_inmem::Insert():: APPEND " << " LocalValueSize: " << LocalValueSize << " ValueSize: " << ValueSize << " TotalValueSize: " << TotalValueSize << EndLogLine; if( TotalValueSize > LocalValueSize ) { /*************************************************************** * Expand Value **************************************************************/ // Allocate new skv_lmr_triplet_t NewRecordAllocRep; status = AllocateAndMoveKey( aReq, KeyValueSize, &NewRecordAllocRep, &mPDSManager ); if( status != SKV_SUCCESS ) break; char* RecordPtr = (char *) NewRecordAllocRep.GetAddr() + KeySize; memcpy( RecordPtr, (void *) aStoredValueRep->GetAddr(), LocalValueSize ); // setup to add new record RecordPtr += LocalValueSize; // rdma read only the new record data aValueRDMADest->InitAbs( NewRecordAllocRep.GetLMRHandle(), RecordPtr, ValueSize ); status = RemoveLocal( aReq, KeySize, (char *) aStoredValueRep->GetAddr(), &mPDSManager ); status = InsertLocal( aReq, (char *) NewRecordAllocRep.GetAddr(), KeySize, TotalValueSize, &mPDSManager, mMyRank ); AssertLogLine( status == SKV_SUCCESS ) << "skv_local_kv_inmem::Insert():: ERROR: " << " status: " << skv_status_to_string( status ) << EndLogLine; /*******************************************************************/ } else { // Record was found, but no expansion is needed // Just make sure that the rdma_read is done to the // appropriate offset aValueRDMADest->InitAbs( aStoredValueRep->GetLMRHandle(), (char *) aStoredValueRep->GetAddr() + aReq->mOffset, ValueSize ); } break; /********************************************************/ default: // mFlags /******************************************************** * Record Exists and no special flags provided: error response ********************************************************/ BegLogLine( SKV_LOCAL_KV_BACKEND_LOG ) << " skv_local_kv_inmem::Insert(): record exists, returning ERRNO" << EndLogLine; status = SKV_ERRNO_RECORD_ALREADY_EXISTS; break; /********************************************************/ } } else { /******************************************************** * Record Does NOT Exist, do a general insert ********************************************************/ /**************************************** * Allocate space for the key and value ****************************************/ skv_lmr_triplet_t NewRecordAllocRep; BegLogLine( SKV_LOCAL_KV_BACKEND_LOG) << "skv_local_kv_inmem::Insert():: " << " Req->mKeyValue: " << aReq->mKeyValue << EndLogLine; status = AllocateAndMoveKey( aReq, KeyValueSize, &NewRecordAllocRep, &mPDSManager ); if( status == SKV_SUCCESS ) { // if no EXPAND requested the requested offset has to be 0 if( !(aReq->mFlags & SKV_COMMAND_RIU_INSERT_EXPANDS_VALUE) ) AssertLogLine( aReq->mOffset == 0 ) << "skv_local_kv_inmem::Insert():: ERROR: " << " Req->mOffset: " << aReq->mOffset << EndLogLine; aValueRDMADest->InitAbs( NewRecordAllocRep.GetLMRHandle(), (char *) NewRecordAllocRep.GetAddr() + KeySize + aReq->mOffset, ValueSize ); status = InsertLocal( aReq, (char *) NewRecordAllocRep.GetAddr(), KeySize, TotalValueSize, &mPDSManager, mMyRank ); } } /***********************************************************************/ if( status != SKV_SUCCESS ) return status; /******************************************************************* * Get the data copied or rdma'd into the new record ******************************************************************/ if( aReq->mFlags & SKV_COMMAND_RIU_INSERT_KEY_VALUE_FIT_IN_CTL_MSG ) { BegLogLine( SKV_LOCAL_KV_BACKEND_LOG ) << "skv_local_kv_inmem::Insert():: inserting value with FIT_IN_CTL_MSG" << " len: " << ValueSize << EndLogLine; memcpy( (void *) aValueRDMADest->GetAddr(), &aReq->mKeyValue.mData[KeySize], ValueSize ); BegLogLine(SKV_LOCAL_KV_BACKEND_LOG) << "Value placed in memory at " << (void *)(aValueRDMADest->GetAddr()) << EndLogLine ; } else // signal that this command is going to require async data transfer status = SKV_ERRNO_NEED_DATA_TRANSFER; return status; }
skv_status_t skv_local_kv_inmem::BulkInsert( skv_pds_id_t aPDSId, skv_lmr_triplet_t *aLocalBuffer, skv_local_kv_cookie_t *aCookie ) { int LocalBufferSize = aLocalBuffer->GetLen(); char* LocalBufferAddr = (char *)aLocalBuffer->GetAddr(); it_lmr_handle_t LocalBufferLMR = aLocalBuffer->GetLMRHandle(); BegLogLine( SKV_LOCAL_KV_BACKEND_LOG ) << "skv_local_kv_inmem:: " << " PDSId: " << aPDSId << " LocalBufferSize: " << LocalBufferSize << " LocalBuffer: " << (void *) LocalBufferAddr << " LocalBufferLMR: " << (void *) LocalBufferLMR << EndLogLine; // Layout of data in buffer { KeySize, ValueSize, Key, Value } int TotalProcessed = 0; skv_status_t LoopStatus = SKV_SUCCESS; static int RowsProcessed = 0; while( TotalProcessed < LocalBufferSize ) { char* KeyPtr = NULL; char* ValuePtr = NULL; int KeySize = -1; int ValueSize = -1; int RowLen = skv_bulk_insert_get_key_value_refs( LocalBufferAddr, &KeyPtr, KeySize, &ValuePtr, ValueSize ); AssertLogLine( ( KeySize > 0 ) && ( KeySize <= SKV_KEY_LIMIT ) ) << "skv_server_bulk_insert_command_sm::Execute(): ERROR: " << " KeySize: " << KeySize << " SKV_KEY_LIMIT: " << SKV_KEY_LIMIT << " TotalProcessed: " << TotalProcessed << " LocalBufferSize: " << LocalBufferSize << EndLogLine; // Check if the key exists skv_lmr_triplet_t ValueRepInStore; skv_status_t status = mPDSManager.Retrieve( aPDSId, KeyPtr, KeySize, 0, 0, (skv_cmd_RIU_flags_t)0, &ValueRepInStore ); int TotalSize = KeySize + ValueSize; #if 0 //SKV_LOCAL_KV_BACKEND_LOG int BytesInRow = skv_bulk_insert_get_total_len( LocalBufferAddr ); HexDump FxString( LocalBufferAddr, BytesInRow ); BegLogLine( SKV_LOCAL_KV_BACKEND_LOG ) << "skv_server_bulk_insert_command_sm::Execute(): " << " TotalSize: " << TotalSize << " KeySize: " << KeySize << " ValueSize: " << ValueSize << " RowsProcessed: " << RowsProcessed << " BytesInRow: " << BytesInRow << " FxString: " << FxString << EndLogLine; #endif LocalBufferAddr += RowLen; TotalProcessed += RowLen; RowsProcessed++; if( status == SKV_SUCCESS ) { static unsigned long long DupCount = 0; LoopStatus = SKV_ERRNO_RECORD_ALREADY_EXISTS; DupCount++; BegLogLine( 0 ) << "skv_server_bulk_insert_command_sm::Execute(): DUP_COUNT: " << DupCount << EndLogLine; continue; } skv_lmr_triplet_t NewRecordAllocRep; status = Allocate( TotalSize, & NewRecordAllocRep ); AssertLogLine( status == SKV_SUCCESS ) << "skv_server_bulk_insert_command_sm::Execute(): ERROR:: " << " status: " << skv_status_to_string( status ) << EndLogLine; char* LocalStoreAddr = (char *) NewRecordAllocRep.GetAddr(); memcpy( LocalStoreAddr, KeyPtr, KeySize ); memcpy( & LocalStoreAddr[ KeySize ], ValuePtr, ValueSize ); /**************************************************** * Insert the record into local store. ****************************************************/ status = Insert( aPDSId, LocalStoreAddr, KeySize, ValueSize, (skv_local_kv_cookie_t*)NULL ); AssertLogLine( status == SKV_SUCCESS ) << "skv_server_bulk_insert_command_sm::Execute(): ERROR:: " << " status: " << skv_status_to_string( status ) << EndLogLine; /****************************************************/ } return LoopStatus; }