// File: gpertea[P]gclib/htest.cpp
// Function: main
int main(int argc, char* argv[]) {
 GPVec<HStrData> strs;
 GPVec<HStrData> sufstrs;
 //GArgs args(argc, argv, "hg:c:s:t:o:p:help;genomic-fasta=COV=PID=seq=out=disable-flag;test=");
 GArgs args(argc, argv, "hQCn:");
 //fprintf(stderr, "Command line was:\n");
 //args.printCmdLine(stderr);
 args.printError(USAGE, true);
 if (args.getOpt('h') || args.getOpt("help")) GMessage(USAGE);
 GStr s=args.getOpt('n');
 if (!s.is_empty()) {
	 numClusters=s.asInt();
	 if (numClusters<=0)
		 GError("%s\nError: invalid value for -n !\n", USAGE);
 }
 qryMode=(args.getOpt('Q'));
 checkRM=(args.getOpt('C'));
 int numargs=args.startNonOpt();
 const char* a=NULL;
 FILE* f=NULL;
 int total=0;
//==== quick test area
 /*
 std::unordered_map<SObj*, int > umap;
 GHash<int> gh;
 GPVec<SObj> ptrs(false);
 GQHash<int, SObj*> ihash(false);
 GQHash<SObj*, int> phash;
 GQStrHash<SObj*> shash;
 const char* tstrs[6] = {"twelve", "five", "nine", "eleven", "three", "nope"};
 int  vals[6]     = { 12,  5, 9, 11, 3, 777 };
 char buf[20];
 for (int i=0;i<5;i++) {
   SObj* o=new SObj(tstrs[i], vals[i]*10);
   ptrs.Add(o);
   sprintf(buf, "%lx", o);
   GMessage("SObj (%s, %d) pointer added: %s\n",tstrs[i], o->val, buf);
   gh.Add(buf, new int(vals[i]));
   shash.Add(tstrs[i], o);
   ihash.Add(vals[i], o);
   phash.Add(o, vals[i]);
   umap[o]=vals[i];
 }
 ptrs.Sort();
 GMessage("shash has now %d entries.\n", shash.Count());
 //enumerate shash entries:
 {
   shash.startIterate();
   SObj* iv=NULL;
   while (const char* k=shash.Next(iv)) {
	   GMessage("Enumerating shash entry: (%s => %lx)\n",
			    k, iv);
   }
 }
 //qry:
 for (int i=0;i<ptrs.Count();i++) {
   SObj* o=ptrs[i];
   //test tset
   SObj* v=shash.Find(o->atr.chars());
   if (v==NULL)
	   GMessage("key <%s> not found in shash!\n", o->atr.chars());
   int* iv=phash.Find(o);
   if (iv==NULL)
	   GMessage("key <%lx> not found in phash!\n", o);
   //if (!oset[*o])
//   GMessage("struct {%s, %d} not found in oset!\n", o->atr.chars(), o->val);

   //sprintf(buf, "%lx", o);
   //int* hv=gh[buf];
   //GMessage("Item {%s, %d} : GHash retrieved flag = %d, umap retrieved flag = %d\n",
   //  o->atr.chars(), o->val, *hv, umap[o]);
 }
//SObj* n=new SObj("test", 10);
//if (!pset[n])
//	   GMessage("key <%lx> not found in pset!\n", n);

 for (int i=0;i<6;i++) {
	SObj* o=shash[tstrs[i]];
	if (o==NULL) GMessage("key <%s> not found in shash!\n", tstrs[i]);
	if (o && i<5) {
		if (o->atr!=tstrs[i])
			GMessage("shash value does not match key <%s!\n", tstrs[i]);
	}
 }

 //delete n;
 //int v=umap[n];
 //GMessage("Non-existing test entry returned value %d\n", v);
  */
 /*
 auto found=umap.find(n);
 if (found!=umap.end()) {
   GMessage("Found flags %d for entry {\"%s\", %d}\n", found->second,
         n->atr.chars(), found->first->val );
 } else  GMessage("New test obj not found !\n");

 return(0);
*/
//==== quick test area end
 if (numargs==0) {
	 //a="htest_data.lst";
	 a="htest_over500.lst";
	 f=fopen(a, "r");
	 if (f==NULL) GError("Error: could not open file %s !\n", a);
	 GMessage("loading %d clusters from file..\n", numClusters);
	 int num=loadStrings(f, sufstrs, strs, numClusters);
	 total+=num;
	 fclose(f);
 }
 else {
	   while ((a=args.nextNonOpt())) {
		   f=fopen(a, "r");
		   if (f==NULL) GError("Error: could not open file %s !\n", a);
		   int num=loadStrings(f, sufstrs, strs, numClusters);
		   total+=num;
		   fclose(f);
	   }
  }
   GResUsage swatch;


   run_GHash(swatch, sufstrs, "GHash w/ suffix");
   showTimings(swatch);
   //run_GHash(swatch, strs, "GHash no suffix");
   //showTimings(swatch);

/*
   run_Hopscotch(swatch, sufstrs, "hopscotch w/ suffix");
   showTimings(swatch);
   run_Hopscotch(swatch, strs, "hopscotch no suffix");
   showTimings(swatch);
*/
/*
   run_Robin(swatch, sufstrs, "robin w/ suffix");
   showTimings(swatch);
   run_Robin(swatch, strs, "robin no suffix");
   showTimings(swatch);
*/

   run_Khashl(swatch, sufstrs, "khashl w/ suffix");
   showTimings(swatch);
/*
   run_Khashl(swatch, strs, "khashl no suffix");
   showTimings(swatch);
*/
   run_GHashMap(swatch, sufstrs, "GHashMap default w/ suffix");
   showTimings(swatch);

   run_GxxHashMap(swatch, sufstrs, "GHashMap xxHash32 w/ suffix");
   showTimings(swatch);

   //run_GHashMap(swatch, strs, "GHashMap no suffix");
   //showTimings(swatch);

   //run_GHashMapShk(swatch, sufstrs, "GHashSetShk w/ suffix");
   //showTimings(swatch);
   //run_GHashMapShk(swatch, strs, "GHashSetShk no suffix");
   //showTimings(swatch);

/*
   run_Bytell(swatch, sufstrs, "bytell w/ suffix");
   showTimings(swatch);
   run_Bytell(swatch, strs, "bytell no suffix");
   showTimings(swatch);
*/

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x990, %rsp            # imm = 0x990
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq -0x30(%rbp), %rdi
movl $0x2, %esi
movl %esi, -0x7b0(%rbp)
movl $0x1, %edx
movl %edx, -0x7ac(%rbp)
callq 0x110d0
movl -0x7b0(%rbp), %esi
movl -0x7ac(%rbp), %edx
leaq -0x50(%rbp), %rdi
callq 0x110d0
jmp 0xee4f
movl -0x8(%rbp), %esi
movq -0x10(%rbp), %rdx
leaq 0x5751(%rip), %rcx      # 0x145ae
leaq -0xa0(%rbp), %rdi
xorl %r8d, %r8d
callq 0xb6a0
jmp 0xee6e
leaq 0x573f(%rip), %rsi      # 0x145b4
leaq -0xa0(%rbp), %rdi
movl $0x1, %edx
callq 0xc4c0
jmp 0xee88
leaq -0xa0(%rbp), %rdi
movl $0x68, %esi
callq 0xc990
movq %rax, -0x7b8(%rbp)
jmp 0xeea2
movq -0x7b8(%rbp), %rax
cmpq $0x0, %rax
jne 0xeed8
leaq 0x576c(%rip), %rsi      # 0x14622
leaq -0xa0(%rbp), %rdi
callq 0xc8e0
movq %rax, -0x7c0(%rbp)
jmp 0xeecb
movq -0x7c0(%rbp), %rax
cmpq $0x0, %rax
je 0xef1d
leaq 0x56d5(%rip), %rdi      # 0x145b4
xorl %eax, %eax
callq 0x26f0
jmp 0xeee8
jmp 0xef1d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0xf3b2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0xf3a9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0xf39d
leaq -0xa0(%rbp), %rdi
movl $0x6e, %esi
callq 0xc990
movq %rax, -0x7c8(%rbp)
jmp 0xef37
movq -0x7c8(%rbp), %rsi
leaq -0xc8(%rbp), %rdi
movl $0x8, %edx
callq 0x6770
jmp 0xef51
leaq -0xc8(%rbp), %rdi
callq 0x6530
movb %al, -0x7c9(%rbp)
jmp 0xef65
movb -0x7c9(%rbp), %al
testb $0x1, %al
jne 0xefd7
jmp 0xef71
leaq -0xc8(%rbp), %rdi
movl $0xa, %esi
callq 0xb0d0
movl %eax, -0x7d0(%rbp)
jmp 0xef8a
movl -0x7d0(%rbp), %eax
movl %eax, 0xb2ba(%rip)      # 0x1a250
cmpl $0x0, 0xb2b3(%rip)      # 0x1a250
jg 0xefd5
leaq 0x5681(%rip), %rdi      # 0x14627
leaq 0x5607(%rip), %rsi      # 0x145b4
xorl %eax, %eax
callq 0x2640
jmp 0xefb6
jmp 0xefd5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0xc8(%rbp), %rdi
callq 0x6990
jmp 0xf39d
jmp 0xefd7
leaq -0xa0(%rbp), %rdi
movl $0x51, %esi
callq 0xc990
movq %rax, -0x7d8(%rbp)
jmp 0xeff1
movq -0x7d8(%rbp), %rax
testq %rax, %rax
setne 0xb267(%rip)            # 0x1a269
leaq -0xa0(%rbp), %rdi
movl $0x43, %esi
callq 0xc990
movq %rax, -0x7e0(%rbp)
jmp 0xf01c
movq -0x7e0(%rbp), %rax
testq %rax, %rax
setne 0xb23d(%rip)            # 0x1a26a
leaq -0xa0(%rbp), %rdi
callq 0xcbb0
movl %eax, -0x7e4(%rbp)
jmp 0xf041
movl -0x7e4(%rbp), %eax
movl %eax, -0xcc(%rbp)
movq $0x0, -0xd8(%rbp)
movq $0x0, -0xe0(%rbp)
movl $0x0, -0xe4(%rbp)
cmpl $0x0, -0xcc(%rbp)
jne 0xf140
leaq 0x55c8(%rip), %rax      # 0x14649
movq %rax, -0xd8(%rbp)
movq -0xd8(%rbp), %rdi
leaq 0x5065(%rip), %rsi      # 0x140fb
callq 0x22d0
movq %rax, -0x7f0(%rbp)
jmp 0xf0a4
movq -0x7f0(%rbp), %rax
movq %rax, -0xe0(%rbp)
cmpq $0x0, -0xe0(%rbp)
jne 0xf0d5
movq -0xd8(%rbp), %rsi
leaq 0x5591(%rip), %rdi      # 0x1465b
xorl %eax, %eax
callq 0x2640
jmp 0xf0d3
jmp 0xf0d5
movl 0xb175(%rip), %esi      # 0x1a250
leaq 0x559a(%rip), %rdi      # 0x1467c
xorl %eax, %eax
callq 0x26f0
jmp 0xf0eb
movq -0xe0(%rbp), %rdi
movl 0xb158(%rip), %ecx      # 0x1a250
leaq -0x50(%rbp), %rsi
leaq -0x30(%rbp), %rdx
callq 0xd3c0
movl %eax, -0x7f4(%rbp)
jmp 0xf10d
movl -0x7f4(%rbp), %eax
movl %eax, -0xe8(%rbp)
movl -0xe8(%rbp), %ecx
movl -0xe4(%rbp), %eax
addl %ecx, %eax
movl %eax, -0xe4(%rbp)
movq -0xe0(%rbp), %rdi
callq 0x2250
jmp 0xf13b
jmp 0xf213
jmp 0xf142
leaq -0xa0(%rbp), %rdi
callq 0xcbd0
movq %rax, -0x800(%rbp)
jmp 0xf157
movq -0x800(%rbp), %rax
movq %rax, -0xd8(%rbp)
cmpq $0x0, %rax
je 0xf211
movq -0xd8(%rbp), %rdi
leaq 0x4f7e(%rip), %rsi      # 0x140fb
callq 0x22d0
movq %rax, -0x808(%rbp)
jmp 0xf18b
movq -0x808(%rbp), %rax
movq %rax, -0xe0(%rbp)
cmpq $0x0, -0xe0(%rbp)
jne 0xf1bc
movq -0xd8(%rbp), %rsi
leaq 0x54aa(%rip), %rdi      # 0x1465b
xorl %eax, %eax
callq 0x2640
jmp 0xf1ba
jmp 0xf1bc
movq -0xe0(%rbp), %rdi
movl 0xb087(%rip), %ecx      # 0x1a250
leaq -0x50(%rbp), %rsi
leaq -0x30(%rbp), %rdx
callq 0xd3c0
movl %eax, -0x80c(%rbp)
jmp 0xf1de
movl -0x80c(%rbp), %eax
movl %eax, -0xec(%rbp)
movl -0xec(%rbp), %ecx
movl -0xe4(%rbp), %eax
addl %ecx, %eax
movl %eax, -0xe4(%rbp)
movq -0xe0(%rbp), %rdi
callq 0x2250
jmp 0xf20c
jmp 0xf142
jmp 0xf213
leaq -0x248(%rbp), %rdi
xorl %esi, %esi
callq 0x11150
jmp 0xf223
leaq 0x5473(%rip), %rdx      # 0x1469d
leaq -0x248(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0xd980
jmp 0xf23c
leaq -0x3a0(%rbp), %rdi
movq %rdi, -0x818(%rbp)
leaq -0x248(%rbp), %rsi
movl $0x158, %edx            # imm = 0x158
callq 0x21f0
movq -0x818(%rbp), %rsi
movq %rsp, %rdi
movl $0x2b, %ecx
rep  movsq (%rsi), %es:(%rdi)
callq 0xd7d0
jmp 0xf274
leaq 0x5432(%rip), %rdx      # 0x146ad
leaq -0x248(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0xdde0
jmp 0xf28d
leaq -0x4f8(%rbp), %rdi
movq %rdi, -0x820(%rbp)
leaq -0x248(%rbp), %rsi
movl $0x158, %edx            # imm = 0x158
callq 0x21f0
movq -0x820(%rbp), %rsi
movq %rsp, %rdi
movl $0x2b, %ecx
rep  movsq (%rsi), %es:(%rdi)
callq 0xd7d0
jmp 0xf2c5
leaq 0x53f2(%rip), %rdx      # 0x146be
leaq -0x248(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0xe1c0
jmp 0xf2de
leaq -0x650(%rbp), %rdi
movq %rdi, -0x828(%rbp)
leaq -0x248(%rbp), %rsi
movl $0x158, %edx            # imm = 0x158
callq 0x21f0
movq -0x828(%rbp), %rsi
movq %rsp, %rdi
movl $0x2b, %ecx
rep  movsq (%rsi), %es:(%rdi)
callq 0xd7d0
jmp 0xf316
leaq 0x53bc(%rip), %rdx      # 0x146d9
leaq -0x248(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0xe5e0
jmp 0xf32f
leaq -0x7a8(%rbp), %rdi
movq %rdi, -0x830(%rbp)
leaq -0x248(%rbp), %rsi
movl $0x158, %edx            # imm = 0x158
callq 0x21f0
movq -0x830(%rbp), %rsi
movq %rsp, %rdi
movl $0x2b, %ecx
rep  movsq (%rsi), %es:(%rdi)
callq 0xd7d0
jmp 0xf367
leaq -0xc8(%rbp), %rdi
callq 0x6990
leaq -0xa0(%rbp), %rdi
callq 0xc780
leaq -0x50(%rbp), %rdi
callq 0x111a0
leaq -0x30(%rbp), %rdi
callq 0x111a0
movl -0x4(%rbp), %eax
addq $0x990, %rsp            # imm = 0x990
popq %rbp
retq
leaq -0xa0(%rbp), %rdi
callq 0xc780
leaq -0x50(%rbp), %rdi
callq 0x111a0
leaq -0x30(%rbp), %rdi
callq 0x111a0
movq -0x58(%rbp), %rdi
callq 0x2400
nopw %cs:(%rax,%rax)