int CPacket_wait_manager::addWaitNode(int area, const data_entry*, const data_entry* value, int bucket_number, const vector<uint64_t>& des_server_ids, base_packet* request, uint32_t max_packet_id, int &version) { //check map_size first int index = get_map_index(max_packet_id); { //CRwLock m_lock(m_mutex,RLOCK); CScopedRwLock __scoped_lock(m_slots_locks->getlock(index), false); if(m_PkgWaitMap[index].size() > TAIR_MAX_DUP_MAP_SIZE) return TAIR_RETURN_DUPLICATE_BUSY; } //CRwLock m_lock(m_mutex,WLOCK); CScopedRwLock __scoped_lock(m_slots_locks->getlock(index), true); CDuplicatPkgMapIter itr = m_PkgWaitMap[index].find(max_packet_id); if (itr == m_PkgWaitMap[index].end()) { //not found in map .inert it and inster to a queue. CPacket_wait_Nodes *pdelaysign = new CPacket_wait_Nodes(bucket_number, request, des_server_ids, version, value); changeBucketCount(bucket_number, 1); m_PkgWaitMap[index][max_packet_id] = pdelaysign; return TAIR_RETURN_SUCCESS; } else { //should never happen,but if crash and restared, nay mixed. log_error("packet sequnce id is dup"); return TAIR_RETURN_DUPLICATE_IDMIXED; } }
int CPacket_wait_manager::doResponse(int bucket_number, uint64_t des_server_id, uint32_t max_packet_id, struct CPacket_wait_Nodes **ppNode) { //CRwLock m_lock(m_mutex,WLOCK); int index = get_map_index(max_packet_id); CScopedRwLock __scoped_lock(m_slots_locks->getlock(index), true); CDuplicatPkgMapIter itr = m_PkgWaitMap[index].find(max_packet_id); if (itr != m_PkgWaitMap[index].end()) { int ret=itr->second->do_response(bucket_number,des_server_id); if (0 == ret) { changeBucketCount(bucket_number, -1); *ppNode= itr->second; m_PkgWaitMap[index].erase(itr); } else { *ppNode= NULL; } return ret; } else { //already timeout. log_warn("resonse packet %u, but not found", max_packet_id); *ppNode= NULL; return TAIR_RETURN_DUPLICATE_DELAY; } }
int CPacket_wait_manager::doTimeout( uint32_t max_packet_id) { //CRwLock m_lock(m_mutex,WLOCK); int index = get_map_index(max_packet_id); { CScopedRwLock __scoped_lock(m_slots_locks->getlock(index), false); CDuplicatPkgMapIter itr = m_PkgWaitMap[index].find(max_packet_id); if (itr == m_PkgWaitMap[index].end()) return 0; } //now we should clear it. clear_waitnode(max_packet_id); return TAIR_RETURN_DUPLICATE_ACK_TIMEOUT; }
int CPacket_wait_manager::clear_waitnode( uint32_t max_packet_id) { int index=get_map_index(max_packet_id); CScopedRwLock __scoped_lock(m_slots_locks->getlock(index), true); CDuplicatPkgMapIter itr = m_PkgWaitMap[index].find(max_packet_id); if (itr != m_PkgWaitMap[index].end()) { CPacket_wait_Nodes* pNode = itr->second; changeBucketCount(pNode->bucket_number, -1); m_PkgWaitMap[index].erase(itr); delete pNode; pNode = NULL; return 0; } else { log_error("clear_waitnode node but not found,packet=%d",max_packet_id); } return 0; }
int CPacket_wait_manager::doResponse(int bucket_number, uint64_t des_server_id, uint32_t max_packet_id, struct CPacket_wait_Nodes **ppNode) { //CRwLock m_lock(m_mutex,WLOCK); int index = get_map_index(max_packet_id); CScopedRwLock __scoped_lock(m_slots_locks->getlock(index), true); CDuplicatPkgMapIter itr = m_PkgWaitMap[index].find(max_packet_id); if (itr != m_PkgWaitMap[index].end()) { int ret=itr->second->do_response(bucket_number,des_server_id); if (0 == ret) { changeBucketCount(bucket_number, -1); *ppNode= itr->second; m_PkgWaitMap[index].erase(itr); } else { *ppNode= NULL; } // at this point, we duplicate successfully and need record this key/value (rsync_manager->add_record(xx)) // for remote sync, unfortunately, current duplicate_manager doest't maintain neccessary // context of request, so we can do noting but ignoring now. // Howerver, storage manager who just uses its own binlog can rest easy now, because rsyc_manager->add_record(xx) // is meaningless for it actually. // TODO: reconstruct duplicate_manager thoroughly. return ret; } else { //already timeout. log_warn("resonse packet %u, but not found", max_packet_id); *ppNode= NULL; return TAIR_RETURN_DUPLICATE_DELAY; } }
bool CPacket_wait_manager::isBucketFree(int bucket_number) { assert(bucket_number >= 0 && bucket_number < TAIR_MAX_BUCKET_NUMBER); CScopedRwLock __scoped_lock(m_slots_locks->getlock(0), false); return m_bucket_count[bucket_number] < MAX_BUCKET_FREE_COUNT; }