TEST_F(ServerCollectTest, get_range_blocks_) { srand(time(NULL)); DataServerStatInfo info; memset(&info, 0, sizeof(info)); info.status_ = DATASERVER_STATUS_ALIVE; info.id_ = 0xfffffff0; time_t now = Func::get_monotonic_time(); bool master = true; bool writable = true; ServerCollect server(info, now); const int32_t BLOCK_COUNT = random() % 10000 + 40960; BlockCollect* blocks[BLOCK_COUNT]; for (int32_t i = 0; i < BLOCK_COUNT; ++i) blocks[i] = new BlockCollect(100 + i); for (int32_t k = 0; k < BLOCK_COUNT; ++k) { EXPECT_TRUE(server.add(blocks[k], writable, master)); } for (int32_t j = 0; j < BLOCK_COUNT; ++j) tbsys::gDelete(blocks[j]); EXPECT_EQ(BLOCK_COUNT, server.hold_->size()); const int32_t MAX_QUERY_NUMS = random() % 512 + 1024; BlockCollect* pblock = NULL; BlockCollect* tmp[MAX_QUERY_NUMS]; ArrayHelper<BlockCollect*> helper(MAX_QUERY_NUMS, tmp); int32_t actual = 0; uint32_t begin = 0; bool complete = true; do { helper.clear(); complete = server.get_range_blocks_(helper, begin, MAX_QUERY_NUMS); if (!helper.empty()) { actual += helper.get_array_index(); pblock = *helper.at(helper.get_array_index() - 1); begin = pblock->id(); } } while (!complete); EXPECT_EQ(BLOCK_COUNT, actual); }
TEST_F(ServerCollectTest, touch) { srand(time(NULL)); DataServerStatInfo info; memset(&info, 0, sizeof(info)); info.status_ = DATASERVER_STATUS_ALIVE; info.id_ = 0xfffffff0; info.use_capacity_ = 0xffffff; info.total_capacity_ = 0xffffffff; time_t now = Func::get_monotonic_time(); bool master = true; bool writable = true; ServerCollect server(layout_manager_, info, now); info.id_++; ServerCollect server2(layout_manager_, info,now); const int32_t BLOCK_COUNT = random() % 10000 + 40960; for (int32_t i = 0; i < BLOCK_COUNT; ++i) { BlockCollect* block = layout_manager_.get_block_manager().insert(100 + i, now); EXPECT_TRUE(NULL != block); block->add(writable, master, server.id(), now); EXPECT_EQ(TFS_SUCCESS, server.add(block->id(), writable, master)); } EXPECT_TRUE(server.writable_->size() > 0); EXPECT_EQ(0, server.hold_master_->size()); EXPECT_EQ(BLOCK_COUNT, server.hold_->size()); bool promote = false; int32_t count = 0; int64_t average_used_capacity = 0xfff; EXPECT_FALSE(server.touch(promote, count, average_used_capacity)); count = 3; EXPECT_FALSE(server.touch(promote, count, average_used_capacity)); count = 3; promote = true; EXPECT_TRUE(server.touch(promote, count, average_used_capacity)); EXPECT_EQ(3, count); average_used_capacity = 0xffffff; EXPECT_TRUE(server.touch(promote, count, average_used_capacity)); EXPECT_EQ(3, count); for (int32_t i = 0; i < BLOCK_COUNT; ++i) { BlockCollect* block = layout_manager_.get_block_manager().get(100 + i); EXPECT_TRUE(NULL != block); block->add(writable, master, server2.id(), now); server2.add(block->id(), writable, master); } EXPECT_TRUE(server2.touch(promote, count, average_used_capacity)); EXPECT_EQ(0, count); EXPECT_TRUE(server2.hold_master_->size() == 3); EXPECT_EQ(BLOCK_COUNT, server.hold_->size()); }
bool ServerCollect::remove_writable_(const common::ArrayHelper<BlockCollect*>& blocks) { RWLock::Lock lock(mutex_, WRITE_LOCKER); BlockCollect* block = NULL; for (int32_t i = 0; i < blocks.get_array_index(); ++i) { block = *blocks.at(i); TBSYS_LOG(DEBUG, "%s remove_writable: is_full: %d, servers size: %d", tbsys::CNetUtil::addrToString(id()).c_str(), block->is_full(), block->get_servers_size()); if (!block->is_writable() || !is_equal_group(block->id())) hold_master_->erase(block); if (block->is_full() || !is_equal_group(block->id())) writable_->erase(block); } return true; }
bool ServerCollect::touch(bool& promote, int32_t& count, const double average_used_capacity) { bool ret = ((is_report_block_complete() || promote) /*&& !is_full()*/ && count > 0); if (!ret) { count = 0; } else { BlockCollect* invalid_blocks[1024]; ArrayHelper<BlockCollect*> helper(1024, invalid_blocks); RWLock::Lock lock(mutex_, WRITE_LOCKER); int32_t current = hold_master_->size(); TBSYS_LOG(DEBUG, "%s touch current %d, writable size: %d", CNetUtil::addrToString(id()).c_str(),current, writable_->size()); if (current >= SYSPARAM_NAMESERVER.max_write_file_count_) { count = 0; } else { count = std::min(count, (SYSPARAM_NAMESERVER.max_write_file_count_ - current)); if (count <= 0) { TBSYS_LOG(DEBUG, "%s", "there is any block need add into hold_master_"); } else { int32_t actual = 0; double use_capacity_ratio = use_capacity_ / total_capacity_; double max_average_use_capacity_ratio = average_used_capacity * AVERAGE_USED_CAPACITY_MULTIPLE; BlockCollect* block = NULL; TfsVector<BlockCollect*>::iterator where; while ((!writable_->empty()) && (writable_index_ < writable_->size()) && (actual < count)) { block = writable_->at(writable_index_); ++writable_index_; if (!block->is_writable()) { if (block->is_full()) helper.push_back(block); continue; } if (!is_equal_group(block->id())) { helper.push_back(block); continue; } if (!block->is_master(this)) continue; where = hold_master_->find(block); if (hold_master_->end() == where) { ++actual; hold_master_->push_back(block); } } if (writable_index_ >= writable_->size()) writable_index_ = 0; for (int32_t i = 0; i < helper.get_array_index(); ++i) { block = *helper.at(i); writable_->erase(block); } if (!is_full() && ((use_capacity_ratio < max_average_use_capacity_ratio) || max_average_use_capacity_ratio <= PERCENTAGE_MIN)) { count -= actual; } else { count = 0; } } } } return ret; }