TEST_F(TestTabletLocationItem, test_valid) { ObMergerTabletLocationList list; ObTabletLocation temp_server; ObServer chunkserver; for (int32_t i = 0; i < ObMergerTabletLocationList::MAX_REPLICA_COUNT; ++i) { chunkserver.set_ipv4_addr(i + 300000, i + 1024); temp_server.tablet_version_ = i; temp_server.chunkserver_ = chunkserver; EXPECT_TRUE(OB_SUCCESS == list.add(temp_server)); } // all invalid ObMergerTabletLocation server; for (int32_t i = 0; i < ObMergerTabletLocationList::MAX_REPLICA_COUNT; ++i) { chunkserver.set_ipv4_addr(i + 300000, i + 1024); server.server_.chunkserver_ = chunkserver; server.server_.tablet_version_ = i; EXPECT_TRUE(OB_SUCCESS == list.set_item_invalid(server)); EXPECT_TRUE(list[i].err_times_ == ObMergerTabletLocation::MAX_ERR_TIMES); } list.set_item_valid(1100); EXPECT_TRUE(list.get_timestamp() == 1100); for (int64_t i = 0; i < ObMergerTabletLocationList::MAX_REPLICA_COUNT; ++i) { EXPECT_TRUE(list[i].err_times_ == 0); } }
TEST_F(TestTabletLocationItem, test_serialize) { ObMergerTabletLocation server; ObMergerTabletLocationList list; list.set_timestamp(1000); ObTabletLocation temp_server; ObServer chunkserver; for (int32_t i = 0; i < ObMergerTabletLocationList::MAX_REPLICA_COUNT; ++i) { chunkserver.set_ipv4_addr(i + 300000, i + 1024); temp_server.tablet_version_ = i; temp_server.chunkserver_ = chunkserver; EXPECT_TRUE(OB_SUCCESS == list.add(temp_server)); EXPECT_TRUE(i + 1 == list.size()); } list.print_info(); int64_t size = list.get_serialize_size(); EXPECT_TRUE(size != 0); char * temp = new char[size]; EXPECT_TRUE(NULL != temp); int64_t pos = 0; EXPECT_TRUE(OB_SUCCESS != list.serialize(temp, size - 1 , pos)); pos = 0; EXPECT_TRUE(OB_SUCCESS == list.serialize(temp, size, pos)); EXPECT_TRUE(pos == size); ObMergerTabletLocationList list2; pos = 0; EXPECT_TRUE(OB_SUCCESS == list2.deserialize(temp, size, pos)); list2.print_info(); list.print_info(); }
TEST_F(TestTabletLocationItem, test_sort) { ObMergerTabletLocationList list; ObServer root_server; const char * addr = "localhost"; root_server.set_ipv4_addr(addr, 8888); int32_t server_ip = root_server.get_ipv4(); // one server ObTabletLocation location; srand(100); ObServer temp; temp.set_ipv4_addr(rand() % 10245, 1023); //location.tablet_id_ = 1; location.chunkserver_ = temp; list.add(location); EXPECT_TRUE(OB_SUCCESS == list.sort(root_server)); int64_t count = list.size(); for (int64_t i = 0; i < count - 1; ++i) { EXPECT_TRUE(abs(list[i].server_.chunkserver_.get_ipv4() - server_ip) <= abs(list[i+1].server_.chunkserver_.get_ipv4() - server_ip)); } // two server temp.set_ipv4_addr(rand() % 10245, 1024); location.chunkserver_ = temp; list.add(location); EXPECT_TRUE(OB_SUCCESS == list.sort(root_server)); count = list.size(); for (int64_t i = 0; i < count - 1; ++i) { EXPECT_TRUE(abs(list[i].server_.chunkserver_.get_ipv4() - server_ip) <= abs(list[i+1].server_.chunkserver_.get_ipv4() - server_ip)); } // three server location.chunkserver_ = root_server; list.add(location); EXPECT_TRUE(OB_SUCCESS == list.sort(root_server)); count = list.size(); for (int64_t i = 0; i < count - 1; ++i) { EXPECT_TRUE(abs(list[i].server_.chunkserver_.get_ipv4() - server_ip) <= abs(list[i+1].server_.chunkserver_.get_ipv4() - server_ip)); } }
int ObMergerTabletLocationCache::get(const uint64_t table_id, const ObString & rowkey, ObMergerTabletLocationList & location) { int ret = OB_SUCCESS; if (!init_) { TBSYS_LOG(ERROR, "%s", "check init failed"); ret = OB_INNER_STAT_ERROR; } else if ((0 == rowkey.length()) || (NULL == rowkey.ptr())) { TBSYS_LOG(ERROR, "%s", "check rowkey length failed"); ret = OB_INPUT_PARAM_ERROR; } else { char * temp = (char *)ob_malloc(sizeof(table_id) + rowkey.length(), ObModIds::OB_MS_LOCATION_CACHE); if (NULL == temp) { TBSYS_LOG(ERROR, "check ob malloc failed:size[%lu], pointer[%p]", sizeof(table_id) + rowkey.length(), temp); ret = OB_ALLOCATE_MEMORY_FAILED; } else { ObString CacheKey; // encode table_id + rowkey as CacheKey *((uint64_t *) temp) = table_id; memcpy(temp + sizeof(uint64_t), rowkey.ptr(), rowkey.length()); CacheKey.assign(temp, static_cast<int32_t>(sizeof(table_id) + rowkey.length())); // get the pair according to the key ObCachePair pair; ret = tablet_cache_.get(CacheKey, pair); if (OB_SUCCESS != ret) { TBSYS_LOG(DEBUG, "find tablet from cache failed:table_id[%lu], length[%d]", table_id, rowkey.length()); } else { int64_t pos = 0; // TODO double check pair.key whether as equal with CacheKey ret = location.deserialize(pair.get_value().ptr(), pair.get_value().length(), pos); if (OB_SUCCESS != ret) { TBSYS_LOG(ERROR, "deserialize location failed:table_id[%lu], length[%d], " "ret[%d]", table_id, rowkey.length(), ret); } } // destory the temp buffer ob_free(temp); } } return ret; }
TEST_F(TestTabletLocationItem, test_timestamp) { ObMergerTabletLocationList list; EXPECT_TRUE(list.get_timestamp() == 0); list.set_timestamp(1025); EXPECT_TRUE(list.get_timestamp() == 1025); list.set_timestamp(1026); EXPECT_TRUE(list.get_timestamp() == 1026); }
TEST_F(TestTabletLocationItem, test_add) { ObTabletLocation server; ObMergerTabletLocationList list; EXPECT_TRUE(0 == list.size()); for (int64_t i = 0; i < ObMergerTabletLocationList::MAX_REPLICA_COUNT; ++i) { server.tablet_version_ = i; EXPECT_TRUE(OB_SUCCESS == list.add(server)); EXPECT_TRUE(i + 1 == list.size()); } EXPECT_TRUE(OB_SUCCESS != list.add(server)); EXPECT_TRUE(OB_SUCCESS != list.add(server)); EXPECT_TRUE(OB_SUCCESS != list.add(server)); EXPECT_TRUE(ObMergerTabletLocationList::MAX_REPLICA_COUNT == list.size()); }
int32_t ObChunkServerTaskDispatcher::select_cs(ObMergerTabletLocationList & list) { int64_t list_size = list.size(); int32_t ret = static_cast<int32_t>(random() % list_size); if (get_factor_ > 0) { ObMergerServerCounter * counter = GET_TSI_MULT(ObMergerServerCounter, SERVER_COUNTER_ID); if (NULL == counter) { TBSYS_LOG(WARN, "get tsi server counter failed:counter[%p]", counter); } else { int64_t min_count = (((uint64_t)1) << 63) - 1; int64_t cur_count = 0; for (int32_t i = 0; i < list_size; ++i) { if (list[i].err_times_ >= ObMergerTabletLocation::MAX_ERR_TIMES) { continue; } cur_count = counter->get(list[i].server_.chunkserver_); if (0 == cur_count) { ret = i; break; } if (cur_count < min_count) { min_count = cur_count; ret = i; } } } if ((ret >= 0) && (ret < list_size) && (counter != NULL)) { int err = counter->inc(list[ret].server_.chunkserver_, get_factor_); if (err != OB_SUCCESS) { TBSYS_LOG(WARN, "inc selected cs failed:ret[%d], err[%d]", ret, err); } } } return ret; }
TEST_F(TestTabletLocationItem, test_invalid) { ObMergerTabletLocationList list; ObTabletLocation temp_server; ObServer chunkserver; for (int32_t i = 0; i < ObMergerTabletLocationList::MAX_REPLICA_COUNT; ++i) { chunkserver.set_ipv4_addr(i + 300000, i + 1024); temp_server.tablet_version_ = i; temp_server.chunkserver_ = chunkserver; EXPECT_TRUE(OB_SUCCESS == list.add(temp_server)); } ObMergerTabletLocation server; // not exist for (int32_t i = 0; i < ObMergerTabletLocationList::MAX_REPLICA_COUNT; ++i) { chunkserver.set_ipv4_addr(i + 200000, i + 1024); server.server_.chunkserver_ = chunkserver; server.server_.tablet_version_ = i; EXPECT_TRUE(OB_SUCCESS != list.set_item_invalid(server)); EXPECT_TRUE(list[i].err_times_ != ObMergerTabletLocation::MAX_ERR_TIMES); } // set second invalid chunkserver.set_ipv4_addr(1 + 300000, 1 + 1024); server.server_.chunkserver_ = chunkserver; server.server_.tablet_version_ = 1; EXPECT_TRUE(OB_SUCCESS == list.set_item_invalid(server)); EXPECT_TRUE(list[1].err_times_ == ObMergerTabletLocation::MAX_ERR_TIMES); EXPECT_TRUE(list[0].err_times_ != ObMergerTabletLocation::MAX_ERR_TIMES); EXPECT_TRUE(list[2].err_times_ != ObMergerTabletLocation::MAX_ERR_TIMES); // all invalid for (int32_t i = 0; i < ObMergerTabletLocationList::MAX_REPLICA_COUNT; ++i) { chunkserver.set_ipv4_addr(i + 300000, i + 1024); server.server_.chunkserver_ = chunkserver; server.server_.tablet_version_ = i; EXPECT_TRUE(OB_SUCCESS == list.set_item_invalid(server)); EXPECT_TRUE(list[i].err_times_ == ObMergerTabletLocation::MAX_ERR_TIMES); } for (int64_t i = 0; i < ObMergerTabletLocationList::MAX_REPLICA_COUNT; ++i) { server.server_.tablet_version_ = i + 100; EXPECT_TRUE(OB_SUCCESS == list.set_item_invalid(server)); } }
TEST_F(TestTabletLocationItem, test_deserialize) { ObMergerTabletLocation server; ObMergerTabletLocationList list; list.set_timestamp(1000); ObTabletLocation temp_server; ObServer chunkserver; for (int32_t i = 0; i < ObMergerTabletLocationList::MAX_REPLICA_COUNT; ++i) { chunkserver.set_ipv4_addr(i + 300000, i + 1024); temp_server.tablet_version_ = i; temp_server.chunkserver_ = chunkserver; EXPECT_TRUE(OB_SUCCESS == list.add(temp_server)); EXPECT_TRUE(i + 1 == list.size()); } ObStringBuf buffer; list.set_buffer(buffer); list.print_info(); char start[1024] = "0x00000000"; char end[1024] = "0xFFFFFFFF"; ObRange range; range.start_key_.assign(start, (int32_t)strlen(start)); range.end_key_.assign(end, (int32_t)strlen(end)); int ret = list.set_tablet_range(range); EXPECT_TRUE(OB_SUCCESS == ret); int64_t size = list.get_serialize_size(); EXPECT_TRUE(size != 0); char * temp = new char[size]; EXPECT_TRUE(NULL != temp); int64_t pos = 0; EXPECT_TRUE(OB_SUCCESS != list.serialize(temp, size - 1 , pos)); pos = 0; EXPECT_TRUE(OB_SUCCESS == list.serialize(temp, size, pos)); EXPECT_TRUE(pos == size); ObMergerTabletLocationList list2; list2.set_buffer(buffer); pos = 0; EXPECT_TRUE(OB_SUCCESS == list2.deserialize(temp, size, pos)); list2.print_info(); list.print_info(); char start1[1024] = "0x0000000000"; char end1[1024] = "0xFFFFFFFFFF"; range.start_key_.assign(start1, (int32_t)strlen(start1)); range.end_key_.assign(end1, (int32_t)strlen(end1)); EXPECT_TRUE(OB_SUCCESS == list.set_tablet_range(range)); size = list.get_serialize_size(); EXPECT_TRUE(size != 0); delete []temp; temp = new char[size]; EXPECT_TRUE(NULL != temp); pos = 0; EXPECT_TRUE(OB_SUCCESS == list.serialize(temp, size, pos)); pos = 0; EXPECT_TRUE(OB_SUCCESS != list2.deserialize(temp, size, pos)); // pos = 0; list2.reset(); EXPECT_TRUE(OB_SUCCESS == list2.deserialize(temp, size, pos)); }
TEST_F(TestTabletLocationItem, test_del) { ObMergerTabletLocation server; ObMergerTabletLocationList list; EXPECT_TRUE(OB_SUCCESS != list.del(0, server)); EXPECT_TRUE(OB_SUCCESS != list.del(1, server)); EXPECT_TRUE(OB_SUCCESS != list.del(2, server)); EXPECT_TRUE(OB_SUCCESS != list.del(3, server)); ObTabletLocation temp_server; for (int64_t i = 0; i < ObMergerTabletLocationList::MAX_REPLICA_COUNT; ++i) { temp_server.tablet_version_ = i; EXPECT_TRUE(OB_SUCCESS == list.add(temp_server)); EXPECT_TRUE(i + 1 == list.size()); } for (int64_t i = 0; i < ObMergerTabletLocationList::MAX_REPLICA_COUNT; ++i) { EXPECT_TRUE(OB_SUCCESS == list.del(0, server)); EXPECT_TRUE(0 == server.err_times_); EXPECT_TRUE(i == server.server_.tablet_version_); EXPECT_TRUE(ObMergerTabletLocationList::MAX_REPLICA_COUNT - i - 1 == list.size()); } for (int64_t i = 0; i < ObMergerTabletLocationList::MAX_REPLICA_COUNT; ++i) { temp_server.tablet_version_ = i; EXPECT_TRUE(OB_SUCCESS == list.add(temp_server)); EXPECT_TRUE(i + 1 == list.size()); } for (int64_t i = ObMergerTabletLocationList::MAX_REPLICA_COUNT - 1; i >= 0; --i) { EXPECT_TRUE(OB_SUCCESS == list.del(0, server)); EXPECT_TRUE(ObMergerTabletLocationList::MAX_REPLICA_COUNT - i - 1 == server.server_.tablet_version_); EXPECT_TRUE(i == list.size()); } EXPECT_TRUE(0 == list.size()); for (int64_t i = ObMergerTabletLocationList::MAX_REPLICA_COUNT - 1; i >= 0; --i) { EXPECT_TRUE(OB_SUCCESS != list.del(0, server)); } for (int64_t i = 0; i < ObMergerTabletLocationList::MAX_REPLICA_COUNT; ++i) { temp_server.tablet_version_ = i; EXPECT_TRUE(OB_SUCCESS == list.add(temp_server)); EXPECT_TRUE(i + 1 == list.size()); } EXPECT_TRUE(OB_SUCCESS == list.del(1, server)); EXPECT_TRUE(1 == server.server_.tablet_version_); EXPECT_TRUE(ObMergerTabletLocationList::MAX_REPLICA_COUNT - 1 == list.size()); }
// waring:all return cell in a row must be same as root table's columns, // and the second row is this row allocated chunkserver list int ObMergerRootRpcProxy::scan_root_table(ObMergerTabletLocationCache * cache, const uint64_t table_id, const ObString & row_key, const ObServer & addr, ObMergerTabletLocationList & location) { assert(location.get_buffer() != NULL); int ret = OB_SUCCESS; bool find_right_tablet = false; ObScanner scanner; // root table id = 0 ret = rpc_stub_->fetch_tablet_location(rpc_timeout_, root_server_, 0, table_id, row_key, scanner); if (ret != OB_SUCCESS) { TBSYS_LOG(WARN, "fetch tablet location failed:table_id[%lu], length[%d], ret[%d]", table_id, row_key.length(), ret); hex_dump(row_key.ptr(), row_key.length(), true); } else { ObRange range; range.border_flag_.unset_inclusive_start(); range.border_flag_.set_inclusive_end(); ObString start_key; ObString end_key; ObServer server; ObCellInfo * cell = NULL; bool row_change = false; ObScannerIterator iter = scanner.begin(); TBSYS_LOG(DEBUG, "%s", "parse scanner result for get some tablet locations"); // all return cell in a row must be same as root table's columns ++iter; while ((iter != scanner.end()) && (OB_SUCCESS == (ret = iter.get_cell(&cell, &row_change))) && !row_change) { if (NULL == cell) { ret = OB_INNER_STAT_ERROR; break; } start_key.assign(cell->row_key_.ptr(), cell->row_key_.length()); ++iter; } if (ret == OB_SUCCESS) { int64_t ip = 0; int64_t port = 0; bool second_row = true; // next cell ObMergerTabletLocationList list; for (++iter; iter != scanner.end(); ++iter) { ret = iter.get_cell(&cell, &row_change); if (ret != OB_SUCCESS) { TBSYS_LOG(ERROR, "get cell from scanner iterator failed:ret[%d]", ret); break; } else if (row_change) // && (iter != last_iter)) { range.table_id_ = table_id; if (NULL == start_key.ptr()) { range.border_flag_.set_min_value(); } else { range.border_flag_.unset_min_value(); range.start_key_ = start_key; } range.border_flag_.unset_max_value(); range.end_key_ = end_key; start_key = end_key; end_key.assign(cell->row_key_.ptr(), cell->row_key_.length()); list.set_timestamp(tbsys::CTimeUtil::getTime()); list.sort(addr); // not deep copy the range list.set_tablet_range(range); // the second row is this row allocated chunkserver list if (second_row) { second_row = false; if ((row_key <= range.end_key_) && (row_key > range.start_key_)) { find_right_tablet = true; location = list; assert(location.get_buffer() != NULL); location.set_tablet_range(range); } else { ret = OB_DATA_NOT_SERVE; TBSYS_LOG(ERROR, "check range not include this key:ret[%d]", ret); hex_dump(row_key.ptr(), row_key.length()); range.hex_dump(); break; } } // add to cache if (OB_SUCCESS != cache->set(range, list)) { TBSYS_LOG(WARN, "%s", "add the range to cache failed"); } list.clear(); } else { end_key.assign(cell->row_key_.ptr(), cell->row_key_.length()); if ((cell->column_name_.compare("1_port") == 0) || (cell->column_name_.compare("2_port") == 0) || (cell->column_name_.compare("3_port") == 0)) { ret = cell->value_.get_int(port); } else if ((cell->column_name_.compare("1_ipv4") == 0) || (cell->column_name_.compare("2_ipv4") == 0) || (cell->column_name_.compare("3_ipv4") == 0)) { ret = cell->value_.get_int(ip); if (OB_SUCCESS == ret) { if (port == 0) { TBSYS_LOG(WARN, "check port failed:ip[%ld], port[%ld]", ip, port); } server.set_ipv4_addr(static_cast<int32_t>(ip), static_cast<int32_t>(port)); ObTabletLocation addr(0, server); if (OB_SUCCESS != (ret = list.add(addr))) { TBSYS_LOG(ERROR, "add addr failed:ip[%ld], port[%ld], ret[%d]", ip, port, ret); break; } else { TBSYS_LOG(DEBUG, "add addr succ:ip[%ld], port[%ld]", ip, port); } ip = port = 0; } } if (ret != OB_SUCCESS) { TBSYS_LOG(ERROR, "check get value failed:ret[%d]", ret); break; } } } // for the last row if ((OB_SUCCESS == ret) && (start_key != end_key)) { range.table_id_ = table_id; if (NULL == start_key.ptr()) { range.border_flag_.set_min_value(); } else { range.border_flag_.unset_min_value(); range.start_key_ = start_key; } range.border_flag_.unset_max_value(); range.end_key_ = end_key; list.set_timestamp(tbsys::CTimeUtil::getTime()); // not deep copy the range list.set_tablet_range(range); list.sort(addr); // double check add all range->locationlist to cache if ((row_key <= range.end_key_) && (row_key > range.start_key_)) { find_right_tablet = true; location = list; // deep copy range assert(location.get_buffer() != NULL); location.set_tablet_range(range); } else if (second_row) { range.hex_dump(); ret = OB_DATA_NOT_SERVE; TBSYS_LOG(ERROR, "check range not include this key:ret[%d]", ret); } // add to list to cache if (OB_SUCCESS != cache->set(range, list)) { range.hex_dump(); TBSYS_LOG(WARN, "%s", "add the range to cache failed"); } } } else { TBSYS_LOG(ERROR, "check get first row cell failed:ret[%d]", ret); } } if ((OB_SUCCESS == ret) && (0 == location.size())) { TBSYS_LOG(ERROR, "check get location size failed:table_id[%ld], find[%d], count[%ld]", table_id, find_right_tablet, location.size()); hex_dump(row_key.ptr(), row_key.length()); ret = OB_INNER_STAT_ERROR; } ms_get_counter_set().inc(ObMergerCounterIds::C_SCAN_ROOT_TABLE); return ret; }
int ObMergerTabletLocationCache::set(const ObRange & range, const ObMergerTabletLocationList & location) { int ret = OB_SUCCESS; if (!init_) { TBSYS_LOG(ERROR, "%s", "check init failed"); ret = OB_INNER_STAT_ERROR; } else { ObCachePair pair; // malloc the pair mem buffer int64_t size = range.get_serialize_size(); ret = tablet_cache_.malloc(pair, static_cast<int32_t>(size), static_cast<int32_t>(location.get_serialize_size())); if (OB_SUCCESS != ret) { TBSYS_LOG(ERROR, "check malloc failed:key_size[%lu], ret[%d]", size, ret); } int64_t pos = 0; // key serialize to the pair if (OB_SUCCESS == ret) { ret = range.serialize(pair.get_key().ptr(), size, pos); if (ret != OB_SUCCESS) { TBSYS_LOG(ERROR, "serialize range failed:ret[%d]", ret); } } // value serialize to the pair if (OB_SUCCESS == ret) { pos = 0; ret = location.serialize(pair.get_value().ptr(), location.get_serialize_size(), pos); if (ret != OB_SUCCESS) { TBSYS_LOG(ERROR, "serialize locationlist failed:ret[%d]", ret); } } // delete the old cache item if (OB_SUCCESS == ret) { ret = del(range.table_id_, range.end_key_); if ((ret != OB_SUCCESS) && (ret != OB_ENTRY_NOT_EXIST)) { TBSYS_LOG(WARN, "del the old item:table[%lu], ret[%d]", range.table_id_, ret); } else { ret = OB_SUCCESS; } } // add new pair and return the old pair for deletion if (OB_SUCCESS == ret) { ObCachePair oldpair; ret = tablet_cache_.add(pair, oldpair); if (ret != OB_SUCCESS) { TBSYS_LOG(ERROR, "add the pair failed:ret[%d]", ret); } else { TBSYS_LOG(DEBUG, "%s", "set tablet location cache succ"); } } } return ret; }
TEST_F(TestRpcStub, test_scan_servers) { ObMergerRpcStub stub; ThreadSpecificBuffer buffer; ObPacketFactory factory; tbnet::Transport transport; tbnet::DefaultPacketStreamer streamer; streamer.setPacketFactory(&factory); transport.start(); ObClientManager client_manager; EXPECT_TRUE(OB_SUCCESS == client_manager.initialize(&transport, &streamer)); EXPECT_TRUE(OB_SUCCESS == stub.init(&buffer, &client_manager)); ObMergerTabletLocationList list; ObServer chunk_server; chunk_server.set_ipv4_addr(addr, MockChunkServer::CHUNK_SERVER_PORT); ObTabletLocation addr; //addr.tablet_id_ = 100; addr.chunkserver_ = chunk_server; list.add(addr); list.add(addr); list.add(addr); // start root server MockChunkServer server; MockServerRunner test_chunk_server(server); tbsys::CThread chunk_server_thread; chunk_server_thread.start(&test_chunk_server, NULL); sleep(2); ObScanParam param; ObCellInfo cell; ObRange range; ObString name; ObScanner scanner; param.set(1, name, range); EXPECT_TRUE(OB_SUCCESS == stub.scan(timeout, chunk_server, param, scanner)); EXPECT_TRUE(!scanner.is_empty()); uint64_t count = 0; ObScannerIterator iter; for (iter = scanner.begin(); iter != scanner.end(); ++iter) { EXPECT_TRUE(OB_SUCCESS == iter.get_cell(cell)); //EXPECT_TRUE(cell.column_id_ == count); printf("client:%.*s\n", cell.row_key_.length(), cell.row_key_.ptr()); ++count; } // return 10 cells EXPECT_TRUE(count == 10); ObMergerTabletLocation succ_addr; bool update = false; EXPECT_TRUE(OB_SUCCESS == stub.scan(timeout, list, param, succ_addr, scanner, update)); EXPECT_TRUE(!scanner.is_empty()); EXPECT_TRUE(update == false); for (iter = scanner.begin(); iter != scanner.end(); ++iter) { EXPECT_TRUE(OB_SUCCESS == iter.get_cell(cell)); printf("client:%.*s\n", cell.row_key_.length(), cell.row_key_.ptr()); } transport.stop(); server.stop(); sleep(10); }