bool ExpandableBlockStreamExchangeEpoll::close() { logging_->log("[%ld] Close: nexhausted lowers=%d, nlower=%d", state.exchange_id_, nexhausted_lowers, nlowers); CancelReceiverThread(); CloseTheSocket(); /* free the temporary resource/ */ for (unsigned i = 0; i < nlowers; i++) { delete block_for_socket_[i]; ; } delete received_block_stream_; delete buffer; delete[] block_for_socket_; /* rest the status of this iterator instance, such that the following calling of open() and next() can * act correctly. */ resetStatus(); Environment::getInstance()->getExchangeTracker()->LogoutExchange(ExchangeID(state.exchange_id_, partition_offset)); logging_->log("[%ld] ExchangeUpper is closed!", state.exchange_id_); return true; }
bool ExpandableBlockStreamExchangeEpoll::RegisterExchange() { ExchangeTracker* et = Environment::getInstance()->getExchangeTracker(); std::ostringstream port_str; port_str << socket_port; return et->RegisterExchange(ExchangeID(state.exchange_id_, partition_offset), port_str.str()); }
bool ExchangeMerger::RegisterExchange() { ExchangeTracker* et = Environment::getInstance()->getExchangeTracker(); std::ostringstream port_str; port_str << socket_port_; return et->RegisterExchange( ExchangeID(state_.exchange_id_, partition_offset_), port_str.str()); }
bool ExchangeMerger::Close() { LOG(INFO) << " exchange_merger_id = " << state_.exchange_id_ << " closed!" << " exhausted lower senders num = " << exhausted_lowers << " lower sender num = " << lower_num_ << std::endl; CancelReceiverThread(); CloseSocket(); for (unsigned i = 0; i < lower_num_; i++) { if (NULL != block_for_socket_[i]) { delete block_for_socket_[i]; block_for_socket_[i] = NULL; } } if (NULL != block_for_deserialization) { delete block_for_deserialization; block_for_deserialization = NULL; } if (NULL != all_merged_block_buffer_) { delete all_merged_block_buffer_; all_merged_block_buffer_ = NULL; } /* rest the status of this iterator instance, such that the following calling * of open() and next() can act correctly. */ ResetStatus(); Environment::getInstance()->getExchangeTracker()->LogoutExchange( ExchangeID(state_.exchange_id_, partition_offset_)); LOG(INFO) << "exchange merger id = " << state_.exchange_id_ << " is closed!" << std::endl; return true; }
bool ExpandableBlockStreamExchangeEpoll::checkOtherUpperRegistered(){ ExchangeTracker* et=Environment::getInstance()->getExchangeTracker(); for(unsigned i=0;i<state.upper_id_list_.size();i++){ NodeID id=state.upper_id_list_[i]; /* Repeatedly ask node with ip for port information until the received port is other than 0, which means * that the exchangeId on noede ip is registered to the exchangeTracker*/ int wait_time_in_millisecond=1; NodeAddress node_addr; while(!et->AskForSocketConnectionInfo(ExchangeID(state.exchange_id_,i),id,node_addr)){ usleep(wait_time_in_millisecond); wait_time_in_millisecond = wait_time_in_millisecond < 200 ? wait_time_in_millisecond + 20 : 200; } } }
bool ExpandableBlockStreamExchangeMaterialized::close(){ FILE* file; void* addr; sem_open_.set_value(1); block_for_socket_->~BlockReadable(); received_block_stream_->~BlockStreamBase(); buffer->~BlockStreamBuffer(); CloseTheSocket(); Environment::getInstance()->getExchangeTracker()->LogoutExchange(ExchangeID(state_.exchange_id_,0)); return true; }
bool ExpandableBlockStreamExchangeMaterialized::open(const PartitionOffset& part_off){ if(sem_open_.try_wait()){ nexhausted_lowers_=0; received_block_stream_=BlockStreamBase::createBlock(state_.schema_,state_.block_size_); block_for_socket_=new BlockReadableFix(received_block_stream_->getSerializedBlockSize(),state_.schema_); buffer=new BlockStreamBuffer(state_.block_size_,nlowers_*10,state_.schema_); if(PrepareTheSocket()==false) return false; if(RegisterExchange(ExchangeID(state_.exchange_id_,0))==false){ Logging_ExpandableBlockStreamExchangeMaterialized("Register Exchange with ID=%l fails!",state_.exchange_id_); } if(isMaster()){ Logging_ExpandableBlockStreamExchangeMaterialized("This exchange is the master one, serialize the iterator subtree to the children..."); if(SerializeAndSendToMulti()==false) return false; } if(WaitForConnectionFromLowerExchanges()==false){ return false; } if(pthread_create(&receiver_tid,NULL,receiver,this)!=0){ Logging_ExpandableBlockStreamExchangeMaterialized("Failed to create receiver thread."); return false; } open_finished_=true; return true; } else{ while(!open_finished_){ usleep(1); } return true; } }
/** * pay attention to the work of different block buffer according to the * comments near it */ bool ExchangeSenderPipeline::Open(SegmentExecStatus* const exec_status, const PartitionOffset&) { RETURN_IF_CANCELLED(exec_status); state_.child_->Open(exec_status, state_.partition_offset_); RETURN_IF_CANCELLED(exec_status); upper_num_ = state_.upper_id_list_.size(); partition_function_ = PartitionFunctionFactory::createBoostHashFunction(upper_num_); socket_fd_upper_list_ = new int[upper_num_]; /** * initialize the block that is used to accumulate the block obtained * by calling child iterator's next() */ block_for_asking_ = BlockStreamBase::createBlock(state_.schema_, state_.block_size_); /** * partitioned_data_buffer_ stores the tuples received from child iterator. * Note the tuples are partitioned and stored. */ partitioned_data_buffer_ = new PartitionedBlockBuffer( upper_num_, block_for_asking_->getSerializedBlockSize()); /** * the temporary block that is used to transfer a block from partitioned data * buffer into sending_buffer. */ block_for_sending_buffer_ = new BlockContainer(block_for_asking_->getSerializedBlockSize()); /** * Initialize the buffer that is used to hold the blocks being sent. There are * upper_num blocks, each corresponding to a merger. */ sending_buffer_ = new PartitionedBlockContainer( upper_num_, block_for_asking_->getSerializedBlockSize()); // Initialized the temporary block to hold the serialized block. block_for_serialization_ = new Block(block_for_asking_->getSerializedBlockSize()); /** * Initialize the blocks that are used to accumulate the tuples from child so * that the insertion to the buffer * can be conducted at the granularity of blocks rather than tuples. */ partitioned_block_stream_ = new BlockStreamBase* [upper_num_]; for (unsigned i = 0; i < upper_num_; ++i) { partitioned_block_stream_[i] = BlockStreamBase::createBlock(state_.schema_, state_.block_size_); } RETURN_IF_CANCELLED(exec_status); /** connect to all the mergers **/ for (unsigned upper_offset = 0; upper_offset < state_.upper_id_list_.size(); ++upper_offset) { RETURN_IF_CANCELLED(exec_status); LOG(INFO) << "(exchane_id= " << state_.exchange_id_ << " partition_offset= " << state_.partition_offset_ << " ) try to connect to upper( " << upper_offset << " , " << state_.upper_id_list_[upper_offset] << " ) "; if (ConnectToUpper(ExchangeID(state_.exchange_id_, upper_offset), state_.upper_id_list_[upper_offset], socket_fd_upper_list_[upper_offset]) != true) { LOG(INFO) << "unsuccessfully !" << std::endl; return false; } } LOG(INFO) << "connect to all mereger successfully !" << std::endl; RETURN_IF_CANCELLED(exec_status); /** create the Sender thread **/ int error = pthread_create(&sender_thread_id_, NULL, Sender, this); if (error != 0) { LOG(ERROR) << "(exchane_id= " << state_.exchange_id_ << " partition_offset= " << state_.partition_offset_ << " ) Failed to create the sender thread>>>>>>>>>>" << std::endl; return false; } return true; }
bool ExchangeIteratorLowerWithWideDependency::open(){ state.child->open(); upper_count=state.upper_ip_port_array.size(); bwfb=new BlockWritableFixBuffer(state.schema,state.block_size,state.upper_ip_port_array.size(),0); bwfb->init(); over=1; sendcount=0; empty_sem=new semaphore(upper_count); full_sem=new semaphore(); lo=new Lock(); eventQueue=new int[upper_count]; sock_fd=new int[upper_count]; tuple=memalign(cacheline_size,state.schema->getTupleMaxSize()); //set upper_ip_port block and send the blocks out for(int upper_ip_port_num=0;upper_ip_port_num<state.upper_ip_port_array.size();upper_ip_port_num++){ struct hostent* host; if((host=gethostbyname(state.upper_ip_port_array[upper_ip_port_num].c_str()))==0){ perror("gethostbyname errors!\n"); return false; } // struct sockaddr_in temp; // temp.sin_family=AF_INET; // temp.sin_port=htons(100); // temp.sin_addr=*((struct in_addr*)host->h_addr); if((sock_fd[upper_ip_port_num]=socket(AF_INET, SOCK_STREAM,0))==-1){ perror("socket creation errors!\n"); return false; } ExchangeTracker* et=Environment::getInstance()->getExchangeTracker(); int upper_port; if((upper_port=et->AskForSocketConnectionInfo(ExchangeID(state.exchange_id,0),state.upper_ip_port_array[upper_ip_port_num]),upper_port)==0){ Logging_ExchangeIteratorLowerWithWideDependency("Fails to ask %s for socket connection info, the exchange id=%d",state.upper_ip_port_array[upper_ip_port_num].c_str(),state.exchange_id); } if(ConnectToUpperExchangeWithMulti(sock_fd[upper_ip_port_num],host,upper_port)==false) return false; } //Currently, the producer and prochase function are created in the open func //TODO: when create them, abstract a thread from the threads pool to do the two func pthread_t prochaseId; int error; error=pthread_create(&prochaseId,NULL,prochaseLower,this); if(error!=0){ cout<<"create threads error!"<<endl; } cout<<"==================: "<<over<<endl; //when there is no tuple in the file, give a value 0 to the variable "over" while(over==1){ Logging_ExchangeIteratorLowerWithWideDependency("in the while loop to listen the fd set"); //getchar(); fd_set socketfds; FD_ZERO(&socketfds); //Currently, here must adopt the "select" syscall to monitor the socket_fd, for example, there are //2 upper hash partitions on the upper, the buffer size can be 2*n. the fd_set can be use to monitor //the 2 socket_fd, when one of the fd occurred a event, will invoke the PrepareForTheNewBlock int sock_fd_max=0; for(int i=0;i<upper_count;i++){ FD_SET(sock_fd[i],&socketfds); if(sock_fd[i]>sock_fd_max) sock_fd_max=sock_fd[i]; } //Currently, we come up with a algorithm, the main meaning is as follows: //--------------------------------------------- //if(nth block in blockwritablebuffer full) // if(n belongs to socket fd_set) // send the n block out; // else // int returnvalue=0; // wai(returnvalue=t for the socket fd come into fd_set) //--------------------------------------------- //TODO: now, the time which waiting for socket fd is maybe long, the longest //time is one block handling long, and multi block in the buffer can be used //to decrease the time consuming here if(select(sock_fd_max+1,&socketfds,(fd_set*)NULL,(fd_set*)NULL,(struct timeval*)NULL)>0){ for(int j=0;j<upper_count;j++){ if(FD_ISSET(sock_fd[j],&socketfds)){ empty_sem->wait(); lo->acquire(); eventQueue[j]=1; // cout<<"in the select"<<endl; lo->release(); full_sem->post(); } } } } return true; }
bool ExpandableBlockStreamExchangeLowerEfficient::open(const PartitionOffset&) { logging_->log("[%lld] Exchange lower is created!", state_.exchange_id_); debug_connected_uppers = 0; debug_connected_uppers_in = 0; state_.child_->open(state_.partition_offset_); nuppers_ = state_.upper_id_list_.size(); partition_function_ = PartitionFunctionFactory::createBoostHashFunction( nuppers_); socket_fd_upper_list = new int[nuppers_]; /** initialize the block stream that is used to accumulate the block obtained by calling child iterator's next() **/ block_stream_for_asking_ = BlockStreamBase::createBlock(state_.schema_, state_.block_size_); /** buffer stores the tuples received from child iterator. Note the tuples are partitioned and stored. **/ partitioned_data_buffer_ = new PartitionedBlockBuffer( nuppers_, block_stream_for_asking_->getSerializedBlockSize()); /** the temporary block that is used to transfer a block from partitioned data buffer into sending buffer.**/ block_for_buffer_ = new BlockContainer( block_stream_for_asking_->getSerializedBlockSize()); /** Initialize the buffer that is used to hold the blocks being sent. There are nuppers block, each corresponding * to a merger. **/ sending_buffer_ = new PartitionedBlockContainer( nuppers_, block_stream_for_asking_->getSerializedBlockSize()); /** Initialized the temporary block to hold the serialized block stream. **/ block_for_serialization_ = new Block( block_stream_for_asking_->getSerializedBlockSize()); /** Initialize the blocks that are used to accumulate the tuples from child so that the insertion to the buffer * can be conducted at the granularity of blocks rather than tuples. */ partitioned_block_stream_ = new BlockStreamBase*[nuppers_]; for (unsigned i = 0; i < nuppers_; i++) { partitioned_block_stream_[i] = BlockStreamBase::createBlock( state_.schema_, state_.block_size_); } /** connect to all the mergers **/ for (unsigned upper_offset = 0; upper_offset < state_.upper_id_list_.size(); upper_offset++) { logging_->log("[%ld,%d] try to connect to upper (%d) %s\n", state_.exchange_id_, state_.partition_offset_, upper_offset, state_.upper_id_list_[upper_offset]); if (ConnectToUpper(ExchangeID(state_.exchange_id_, upper_offset), state_.upper_id_list_[upper_offset], socket_fd_upper_list[upper_offset], logging_) != true) return false; printf("[%ld,%d] connected to upper [%d,%d] on Node %d\n", state_.exchange_id_, state_.partition_offset_, state_.exchange_id_, upper_offset, state_.upper_id_list_[upper_offset]); } /** create the sender thread **/ // if (true == g_thread_pool_used) { // Environment::getInstance()->getThreadPool()->add_task(sender, this); // } // else { int error; error = pthread_create(&sender_tid, NULL, sender, this); if (error != 0) { logging_->elog( "Failed to create the sender thread>>>>>>>>>>>>>>>>>>>>>>>>>>>>@@#@#\n\n."); return false; } // } // pthread_create(&debug_tid,NULL,debug,this); /*debug*/ return true; }