text: #include "gtest/gtest.h"
  #include "servant/Application.h"
  #include "TarsTest/TestcaseServer/RPCTest.h"
  #include "servant/AdminF.h"
  #include "TarsServantName.h"
  
  
  #include "util/tc_multi_hashmap.h"
  #include "util/tc_shm.h"
  #include "util/tc_option.h"
  #include <stdlib.h>
  #include <iostream>
  #include "util/tc_common.h"
  // #include <sys/time.h>
  
  
  using namespace tars;
  
  
  ////////////////////////////////////////////////////////////////////
  //
  
  namespace {
      
  TC_Shm				g_shm;
  TC_Multi_HashMap	g_hmap;
  bool				g_bSilent = false;		// �Ƿ�Ϊ����ģʽ���������־������ȡ�ø��ߵ��ٶ�
  
  // ��ͨ�Ĺ��ܲ���
  struct FunctionTest
  {
  	static void initMem()
  	{
  #if __WORDSIZE == 64
  		size_t iMemSize    = 1024*20;
  #else
  		size_t iMemSize    = 1024*10;
  #endif
  		g_shm.init(iMemSize, 0x12345);
  		cout << "init mem, shm key=0x" << hex << 0x12345 << dec << endl;
  	}
  	
  	static void initMap()
  	{
  		if (g_shm.iscreate())
  		{
  			size_t iMinSize = 2, iMaxSize = 8;
  			g_hmap.initDataBlockSize(iMinSize, iMaxSize, 2.0);
  			g_hmap.create(g_shm.getPointer(), g_shm.size());
  			g_hmap.setEraseCount(3);
  		}
  		else
  		{
  			g_hmap.connect(g_shm.getPointer(), g_shm.size());
  		}
  	}
  };
  
  // �����������ܲ���
  struct PerformanceTest
  {
  	static void initMem()
  	{
  		size_t iMemSize    = 1073741824;		// 1G
  		g_shm.init(iMemSize, 0x23456);
  		cout << "init mem, shm key=0x" << hex << 0x23456 << dec << endl;
  	}
  	
  	static void initMap()
  	{
  		if (g_shm.iscreate())
  		{
  			size_t iMinSize = 5, iMaxSize = 20;
  			g_hmap.initDataBlockSize(iMinSize, iMaxSize, 2.0);
  			g_hmap.create(g_shm.getPointer(), g_shm.size());
  			g_hmap.setEraseCount(10);
  		}
  		else
  		{
  			g_hmap.connect(g_shm.getPointer(), g_shm.size());
  		}
  	}
  };
  
  void set(const string &mk, const string &uk, const string &v, uint8_t version, bool dirty, bool full, bool head)
  {
  	vector<TC_Multi_HashMap::Value> vRecords;
  
  	TC_Multi_HashMap::DATATYPE eType = (full ? TC_Multi_HashMap::FULL_DATA : TC_Multi_HashMap::PART_DATA);
  
  	timeval tv_1, tv_2;
  	TC_Common::gettimeofday(tv_1);
  	
  	int ret = TC_Multi_HashMap::RT_OK;
  	if(uk.empty())
  	{
  		// ������key��only key
  		ret = g_hmap.set(mk, vRecords);
  	}
  	else
  	{
  		if(v.empty())
  		{
  			// ����������only key
  			ret = g_hmap.set(mk, uk, eType, head, vRecords);
  		}
  		else
  		{
  			ret = g_hmap.set(mk, uk, v, version, dirty, eType, head, vRecords);
  		}
  	}
  	
  	TC_Common::gettimeofday(tv_2);
  	
  	long lTime = 0;
  	if(tv_2.tv_usec < tv_1.tv_usec)
  	{
  		lTime = (tv_2.tv_sec -1 - tv_1.tv_sec) * 1000000;
  	}
  	else
  	{
  		lTime = (tv_2.tv_sec - tv_1.tv_sec) * 1000000 + (tv_2.tv_usec - tv_1.tv_usec);
  	}
  	
  	//assert(ret == 0);
  	cout << "set:" << mk << "|" << uk << "|" << v << "|" << ret << "|" << lTime << endl;
  	for(size_t i = 0; i < vRecords.size(); i++)
  	{
  		cout << "set erase:" << vRecords[i]._mkey << "|" << vRecords[i]._data._key 
  			<< "|" << vRecords[i]._data._value << endl;
  	}
  }
  
  void get(const string &mk, const string &uk)
  {
  	TC_Multi_HashMap::Value v;
  	if(!uk.empty())
  	{
  		// ����������ѯ����
  		int ret = g_hmap.get(mk, uk, v);
  		cout << "get:" << mk << "|" << uk << "|" << v._data._value << "|" 
  			<< (int)v._data._iVersion << "|" << v._data._dirty << "|" << ret << endl;
  	}
  	else
  	{
  		// ����key�µ���������
  		size_t count = g_hmap.count(mk);
  		cout << "count of " << mk << ": " << count << endl;
  		TC_Multi_HashMap::lock_iterator it = g_hmap.find(mk);
  		while(it != g_hmap.end())
  		{
  			TC_Multi_HashMap::Value v;
  			int ret = it->get(v);
  			cout << v._mkey << "|" << v._data._key << "|" << v._data._value 
  				<< "|" << (int)v._data._iVersion << "|" << v._data._dirty << "|" << ret << endl;
  			it ++;
  		}
  	}
  }
  
  void del(const string &mk, const string &uk)
  {
  	vector<TC_Multi_HashMap::Value> vtDel;
  	int ret = TC_Multi_HashMap::RT_OK;
  	if(uk.empty())
  	{
  		ret = g_hmap.del(mk, vtDel);
  	}
  	else
  	{
  		TC_Multi_HashMap::Value v;
  		ret = g_hmap.del(mk, uk, v);
  		vtDel.push_back(v);
  	}
  	cout << "del:" << mk << "|" << uk << "|" << ret << endl;
  	for(size_t i = 0; i < vtDel.size(); i ++)
  	{
  		cout << "del:" << vtDel[i]._mkey << "|" << vtDel[i]._data._key << "|" << vtDel[i]._data._value << endl;
  	}
  }
  
  void sync()
  {
  	TC_Multi_HashMap::Value data;
  	size_t n = 0;
  	g_hmap.setSyncTime(30);
  	g_hmap.sync();
  	while(true)
  	{
  		int ret = g_hmap.sync(time(NULL), data);
  		if (ret == TC_Multi_HashMap::RT_OK)
  		{
  			break;
  		}
  		else if(ret == TC_Multi_HashMap::RT_NEED_SYNC)
  		{
  			++n;
  			cout << "sync:" << data._mkey << "|" << data._data._key << "|" 
  				<< data._data._value << "|" << data._data._synct << endl;
  		}
  	}
  	cout << n << " records synced" << endl;
  }
  
  void erase(int ratio)
  {
  	vector<TC_Multi_HashMap::Value> vtErased;
  	int ret = g_hmap.erase(ratio, vtErased, true);
  	cout << "erase:" << ratio << "|" << vtErased.size() << "|" << ret << endl;
  	for(size_t i = 0; i < vtErased.size(); i++)
  	{
  		cout << "erase:" << vtErased[i]._mkey << "|" << vtErased[i]._data._key 
  			<< "|" << vtErased[i]._data._value << endl;
  	}
  }
  
  void listh()
  {
  	const TC_Multi_HashMap::tagMapHead &head = g_hmap.getMapHead();
  	cout << "list hash count: " << head._iElementCount << endl;
  	TC_Multi_HashMap::hash_iterator it = g_hmap.hashBegin();
  	while(it != g_hmap.hashEnd())
  	{
  		vector<TC_Multi_HashMap::Value> vv;
  		it->get(vv);
  		++it;
  		
  		for(size_t i = 0; i < vv.size(); i ++)
  		{
  			cout << vv[i]._mkey << "|" << vv[i]._data._key << "|" << vv[i]._data._value 
  				<< "|" << (int)vv[i]._data._iVersion << "|" << vv[i]._data._dirty << "|" << vv[i]._data._synct << endl;
  		}
  	}
  }
  
  void list(int type, bool asc = true)
  {
  	TC_Multi_HashMap::lock_iterator it;
  	switch(type)
  	{
  	case 0:
  		// ��block������
  		if(asc)
  		{
  			// ����
  			it = g_hmap.begin();
  		}
  		else
  		{
  			// ����
  			it = g_hmap.rbegin();
  		}
  		break;
  	case 1:
  		// ��getʱ��������
  		if(asc)
  		{
  			// ����
  			it = g_hmap.beginGetTime();
  		}
  		else
  		{
  			// ����
  			it = g_hmap.rbeginGetTime();
  		}
  		break;
  	case 2:
  		// ��setʱ��������
  		if(asc)
  		{
  			// ����
  			it = g_hmap.beginSetTime();
  		}
  		else
  		{
  			// ����
  			it = g_hmap.rbeginSetTime();
  		}
  		break;
  	case 3:
  		// ��������������
  		it = g_hmap.beginDirty();
  		break;
  	default:
  		return;
  	}
  
  	while(it != g_hmap.end())
  	{
  		TC_Multi_HashMap::Value v;
  		it->get(v);
  		++it;
  		
  		cout << v._mkey << "|" << v._data._key << "|" << v._data._value 
  			<< "|" << (int)v._data._iVersion << "|" << v._data._dirty << "|" << v._data._synct << endl;
  	}
  }
  
  void batchset(size_t iCount, size_t iAvgRec)
  {
  	srand(time(NULL));
  	string mk, uk, v;
  	vector<TC_Multi_HashMap::Value> vRecords;
  
  	timeval tv_1, tv_2;
  	TC_Common::gettimeofday(tv_1);
  
  	for(size_t i = 1; i <= iCount / iAvgRec; i ++)
  	{
  		mk = TC_Common::tostr(i);
  		size_t iRec = rand() % iAvgRec + 1;
  		for(size_t j = 1; j <= iRec; j ++)
  		{
  			uk = TC_Common::tostr(j);
  			v = mk + uk;
  
  			timeval tv_1, tv_2;
  			if(!g_bSilent)
  			{
  				TC_Common::gettimeofday(tv_1);
  			}
  
  			vRecords.clear();
  			int ret = g_hmap.set(mk, uk, v, 0, true, TC_Multi_HashMap::FULL_DATA, true, vRecords);
  
  			if(!g_bSilent)
  			{
  				TC_Common::gettimeofday(tv_2);
  				long lTime = 0;
  				if(tv_2.tv_usec < tv_1.tv_usec)
  				{
  					lTime = (tv_2.tv_sec -1 - tv_1.tv_sec) * 1000000;
  				}
  				else
  				{
  					lTime = (tv_2.tv_sec - tv_1.tv_sec) * 1000000 + (tv_2.tv_usec - tv_1.tv_usec);
  				}
  				
  				//assert(ret == 0);
  				cout << "set:" << mk << "|" << uk << "|" << v << "|" << ret << "|" << lTime << endl;
  				for(size_t i = 0; i < vRecords.size(); i++)
  				{
  					cout << "set erase:" << vRecords[i]._mkey << "|" << vRecords[i]._data._key 
  						<< "|" << vRecords[i]._data._value << endl;
  				}
  			}
  		}
  	}
  
  	TC_Common::gettimeofday(tv_2);
  	long lTime = 0;
  	if(tv_2.tv_usec < tv_1.tv_usec)
  	{
  		lTime = (tv_2.tv_sec -1 - tv_1.tv_sec) * 1000000;
  	}
  	else
  	{
  		lTime = (tv_2.tv_sec - tv_1.tv_sec) * 1000000 + (tv_2.tv_usec - tv_1.tv_usec);
  	}
  	cout << "batchset:" << iCount << "|" << iAvgRec << "|" << lTime << endl;
  }
  
  void batchset()
  {
  	vector<TC_Multi_HashMap::Value> vtSet, vtErased;
  
  	TC_Multi_HashMap::Value v;
  
  	v._mkey = "1", v._data._key = "1", v._data._value = "11";
  	vtSet.push_back(v);
  
  	v._mkey = "1", v._data._key = "2", v._data._value = "12";
  	vtSet.push_back(v);
  
  	v._mkey = "2", v._data._key = "1", v._data._value = "21";
  	vtSet.push_back(v);
  
  	v._mkey = "3", v._data._key = "1", v._data._value = "31";
  	vtSet.push_back(v);
  
  	v._mkey = "4", v._data._key = "1", v._data._value = "41";
  	vtSet.push_back(v);
  
  	int ret = g_hmap.set(vtSet, TC_Multi_HashMap::FULL_DATA, true, true, vtErased);
  
  	for(size_t i = 0; i < vtSet.size(); i ++)
  	{
  		cout << "set:" << vtSet[i]._mkey << "|" << vtSet[i]._data._key << "|" << vtSet[i]._data._value << "|" << ret << endl;
  	}
  	for(size_t i = 0; i < vtErased.size(); i++)
  	{
  		cout << "set erase:" << vtErased[i]._mkey << "|" << vtErased[i]._data._key 
  			<< "|" << vtErased[i]._data._value << endl;
  	}
  }
  
  void batchget(size_t iCount, size_t iAvgRec)
  {
  	srand(time(NULL));
  	string mk, uk;
  	TC_Multi_HashMap::Value v;
  
  	timeval tv_1, tv_2;
  	TC_Common::gettimeofday(tv_1);
  	
  	for(size_t i = 1; i <= iCount / iAvgRec; i ++)
  	{
  		mk = TC_Common::tostr(i);
  		size_t iRec = rand() % iAvgRec + 1;
  		for(size_t j = 1; j <= iRec; j ++)
  		{
  			uk = TC_Common::tostr(j);
  			
  			timeval tv_1, tv_2;
  			if(!g_bSilent)
  			{
  				TC_Common::gettimeofday(tv_1);
  			}
  			
  			int ret = g_hmap.get(mk, uk, v);
  			
  			if(!g_bSilent)
  			{
  				TC_Common::gettimeofday(tv_2);
  				long lTime = 0;
  				if(tv_2.tv_usec < tv_1.tv_usec)
  				{
  					lTime = (tv_2.tv_sec -1 - tv_1.tv_sec) * 1000000;
  				}
  				else
  				{
  					lTime = (tv_2.tv_sec - tv_1.tv_sec) * 1000000 + (tv_2.tv_usec - tv_1.tv_usec);
  				}
  				
  				//assert(ret == 0);
  				cout << "get:" << mk << "|" << uk << "|" << v._data._value << "|" 
  					<< (int)v._data._iVersion << "|" << v._data._dirty << "|" << ret << endl;
  			}
  		}
  	}
  	
  	TC_Common::gettimeofday(tv_2);
  	long lTime = 0;
  	if(tv_2.tv_usec < tv_1.tv_usec)
  	{
  		lTime = (tv_2.tv_sec -1 - tv_1.tv_sec) * 1000000;
  	}
  	else
  	{
  		lTime = (tv_2.tv_sec - tv_1.tv_sec) * 1000000 + (tv_2.tv_usec - tv_1.tv_usec);
  	}
  	cout << "batchset:" << iCount << "|" << iAvgRec << "|" << lTime << endl;
  }
  
  
  // �ڴ��С���ԣ�����һЩ�ṹ�ڲ�ͬ�Ļ�������ռ���ֽ���
  void testMemSize()
  {
  	cout << "sizeof(int)=" << sizeof(int) << endl;
  	cout << "sizeof(long)=" << sizeof(long) << endl;
  	cout << "sizeof(size_t)=" << sizeof(size_t) << endl;
  	cout << "sizeof(time_t)=" << sizeof(time_t) << endl;
  	cout << "sizeof(tagBlockHead)=" << sizeof(TC_Multi_HashMap::Block::tagBlockHead) << endl;
  	cout << "sizeof(tagMainKeyHead)=" << sizeof(TC_Multi_HashMap::MainKey::tagMainKeyHead) << endl;
  	cout << "sizeof(tagChunkHead)=" << sizeof(TC_Multi_HashMap::Block::tagChunkHead) << endl;
  	cout << "sizeof(tagHashItem)=" << sizeof(TC_Multi_HashMap::tagHashItem) << endl;
  	cout << "sizeof(tagMainKeyHashItem)=" << sizeof(TC_Multi_HashMap::tagMainKeyHashItem) << endl;
  }
  
  void usage(char *argv)
  {
      cout << argv << " --help\tshow this help message" << endl;
  	cout << "\t --mem\tview memory size of some structs" << endl;
  	cout << "\t --f\tdo the functionality test(default option)" << endl;
  	cout << "\t --p\tdo the performance test" << endl;
  	cout << "\t --s\tsilent mode in performance test, no output" << endl;
      cout << "\t --release\trelease the allocated share memory" << endl;
      cout << "\t --view\tview statistic information of this map" << endl;
      cout << "\t --set [--mkey=] [--ukey=] [--value=] [--version] [--clean] [--full] [--tail]" << endl;
      cout << "\t --get [--mkey=] [--ukey=]" << endl;
      cout << "\t --del [--mkey=] [--ukey=]" << endl;
      cout << "\t --sync" << endl;
      cout << "\t --erase [--ratio]" << endl;
      cout << "\t --isdirty [--mkey=] [--ukey=]" << endl;
      cout << "\t --listh\tlist data by hash index" << endl;
  	cout << "\t --listb [--desc]\tlist data by block chain" << endl;
  	cout << "\t --listg [--desc]\tlist data by get time chain" << endl;
  	cout << "\t --lists [--desc]\tlist data by set time chain" << endl;
      cout << "\t --listd\tlist data by dirty data chain" << endl;
      cout << "\t --set-batch [--count] [--avgrec]\tdo batch set operation, will set total count records with avgrec records per main key" << endl;
      cout << "\t --get-batch [--count] [--avgrec]\tdo batch get operation" << endl;
  	cout << "\t --chkmk [--mkey]\tcheck if main key exists" << endl;
  	cout << "\t --setstate [--mkey] [--ukey] [--dirty] [--clean] [--part] [--full]\tcheck if main key exists" << endl;
  	cout << "\t --chkbad [--hash] [--repair]" << endl;
  }
  
  
  int main_test(int argc, char* argv[])
  {
  	try
      {
          TC_Option option;
          option.decode(argc, argv);
  
          map<string, string> m = option.getMulti();
  
          if(option.hasParam("help") || option.getMulti().empty())
          {
              usage(argv[0]);
              return 0;
          }
  
  		if(option.hasParam("mem"))
  		{
  			testMemSize();
  			return 0;
  		}
  
  		g_bSilent = option.hasParam("s");
  
  		// ������úͻ�ȡʱҲ�������ܲ���
  		bool bPerfTest = option.hasParam("p");
  		if(bPerfTest)
  		{
  			PerformanceTest::initMem();
  		}
  		else
  		{
  			FunctionTest::initMem();
  		}
  
          if(option.hasParam("release"))
          {
              g_shm.del();
              return 0;
          }
  
  		if(bPerfTest)
  		{
  			PerformanceTest::initMap();
  		}
  		else
  		{
  			FunctionTest::initMap();
  		}
  
          if(option.hasParam("view"))
          {
              cout << g_hmap.desc() << endl;
          }
          else if(option.hasParam("set"))
          {
              string mk = option.getValue("mkey");
  			string uk = option.getValue("ukey");
              string v = option.getValue("value");
  			uint8_t version = option.getValue("version").empty() ? 0 : atoi(option.getValue("version").c_str());
  			bool dirty = option.getValue("clean").empty() ? true : false;
  			bool full = option.getValue("full").empty() ? false : true;
  			bool head = option.getValue("tail").empty() ? true : false;
  
  			if(mk.empty())
  			{
  				usage(argv[0]);
  				return 0;
  			}
  			
  			set(mk, uk, v, version, dirty, full, head);
          }
          else if(option.hasParam("get"))
          {
              string mk;
  			string uk;
              mk = option.getValue("mkey");
  			uk = option.getValue("ukey");
  
  			if(mk.empty())
  			{
  				usage(argv[0]);
  				return 0;
  			}
  			
  			get(mk, uk);
          }
          else if(option.hasParam("del"))
          {
              string mk;
  			string uk;
              mk = option.getValue("mkey");
  			uk = option.getValue("ukey");
  			
  			if(mk.empty())
  			{
  				usage(argv[0]);
  				return 0;
  			}
  
  			del(mk, uk);
          }
          else if(option.hasParam("sync"))
          {
  			sync();
          }
          else if(option.hasParam("erase"))
          {
              string ratio = option.getValue("ratio");
  			if(ratio.empty())
  			{
  				usage(argv[0]);
  				return 0;
  			}
  
  			erase(TC_Common::strto<int>(ratio));
          }
          else if(option.hasParam("isdirty"))
          {
              string mk;
  			string uk;
              mk = option.getValue("mkey");
  			uk = option.getValue("ukey");
  			if(mk.empty())
  			{
  				usage(argv[0]);
  				return 0;
  			}
              int ret = TC_Multi_HashMap::RT_OK;
  			if(uk.empty())
  			{
  				ret = g_hmap.checkDirty(mk);
  			}
  			else
  			{
  				ret = g_hmap.checkDirty(mk, uk);
  			}
              cout << "isdirty:" << mk << "|" << uk << "|" << (ret == TC_Multi_HashMap::RT_DIRTY_DATA) << endl;
          }
          else if(option.hasParam("listh"))
          {
  			listh();
          }
          else if(option.hasParam("listb"))
          {
  			if(option.hasParam("desc"))
  			{
  				list(0, false);
  			}
  			else
  			{
  				list(0, true);
  			}
          }
          else if(option.hasParam("listg"))
          {
  			if(option.hasParam("desc"))
  			{
  				list(1, false);
  			}
  			else
  			{
  				list(1, true);
  			}
          }
          else if(option.hasParam("lists"))
          {
  			if(option.hasParam("desc"))
  			{
  				list(2, false);
  			}
  			else
  			{
  				list(2, true);
  			}
          }
          else if(option.hasParam("listd"))
          {
  			list(3);
          }
  		else if(option.hasParam("set-batch"))
  		{
  			string sCount = option.getValue("count");
  			string sAvgRec = option.getValue("avgrec");
  			if(!sCount.empty())
  			{
  				batchset(TC_Common::strto<size_t>(sCount), sAvgRec.empty() ? 2 : TC_Common::strto<size_t>(sAvgRec));
  			}
  			else
  			{
  				// ������������������
  				batchset();
  			}
  		}
  		else if(option.hasParam("get-batch"))
  		{
  			string sCount = option.getValue("count");
  			string sAvgRec = option.getValue("avgrec");
  			if(sCount.empty())
  			{
  				usage(argv[0]);
  				return 0;
  			}
  
  			batchget(TC_Common::strto<size_t>(sCount), sAvgRec.empty() ? 2 : TC_Common::strto<size_t>(sAvgRec));
  		}
  		else if(option.hasParam("chkmk"))
  		{
  			string mk = option.getValue("mkey");
  			if(mk.empty())
  			{
  				usage(argv[0]);
  				return 0;
  			}
  
  			int ret = g_hmap.checkMainKey(mk);
  			if(ret == TC_Multi_HashMap::RT_OK)
  			{
  				cout << "main key " << mk << " exists" << endl;
  			}
  			else if(ret == TC_Multi_HashMap::RT_ONLY_KEY)
  			{
  				cout << "main key " << mk << " exists, but only key" << endl;
  			}
  			else if(ret == TC_Multi_HashMap::RT_PART_DATA)
  			{
  				cout << "main key " << mk << " exists, and possible part data" << endl;
  			}
  			else if(ret == TC_Multi_HashMap::RT_NO_DATA)
  			{
  				cout << "main key " << mk << " not exists" << endl;
  			}
  			else
  			{
  				cout << "chkmk " << mk << " failed: " << ret << endl;
  			}
  		}
  		else if(option.hasParam("setstate"))
  		{
  			string mk = option.getValue("mkey");
  			string uk = option.getValue("ukey");
  			bool bDirty = option.hasParam("dirty");
  			bool bClean = option.hasParam("clean");
  			bool bFull = option.hasParam("full");
  			bool bPart = option.hasParam("part");
  			if(mk.empty())
  			{
  				usage(argv[0]);
  				return 0;
  			}
  			if(!uk.empty())
  			{
  				if(bDirty)
  				{
  					int ret = g_hmap.setDirty(mk, uk);
  					cout << "setdirty:" << mk << "|" << uk << "|" << ret << endl;
  				}
  				else if(bClean)
  				{
  					int ret = g_hmap.setClean(mk, uk);
  					cout << "setclean:" << mk << "|" << uk << "|" << ret << endl;
  				}
  				else
  				{
  					usage(argv[0]);
  					return 0;
  				}
  			}
  			else
  			{
  				if(bFull)
  				{
  					int ret = g_hmap.setFullData(mk, true);
  					cout << "set full data:" << mk << "|" << ret << endl;
  				}
  				else if(bPart)
  				{
  					int ret = g_hmap.setFullData(mk, false);
  					cout << "set part data:" << mk << "|" << ret << endl;
  				}
  				else
  				{
  					usage(argv[0]);
  					return 0;
  				}
  			}
  		}
  		else if(option.hasParam("chkbad"))
  		{
  			string sHash = option.getValue("hash");
  			if(sHash.empty())
  			{
  				usage(argv[0]);
  				return 0;
  			}
  			uint32_t iHash = TC_Common::strto<uint32_t>(sHash);
  			size_t iCount = g_hmap.checkBadBlock(iHash, option.hasParam("repair"));
  			cout << iCount << " bad block under hash " << iHash << endl;
  		}
  		else
  		{
  			usage(argv[0]);
  		}
  	}
  	catch(exception &e)
  	{
  		cout << "error! " << e.what() << endl;
  	}
  
  	return 0;
  }
  
  
  
  TEST(TarsUtilTestcase, UT_TC_Multi_HashMap)
  {
      char * g_array_argv[6][3] = { 
  
      };
      
      for(unsigned int i=0; i<(sizeof(g_array_argv)/sizeof(char*[3])); i++)
      {
          char **argv = g_array_argv[i];
          int argc = (sizeof(g_array_argv[i]) / sizeof(char *));
          main_test(argc, argv);
      }        
  }
  
  
  }