// File: /workspace/github_cpp_makefile_star2_O3/narula[P]skiplists/skiplist-extra.cc
// Function: main
int main(int argc, char** argv) {
  srand(time(NULL));
  int LIST_SIZE = 16;
  if (argc > 1) {
	LIST_SIZE = atoi(argv[1]);
  }
  int POOL = 3*LIST_SIZE;
  int ITERATIONS = 10000;
  int maxl = floor(log(LIST_SIZE)/log(4))+1;
  if (LIST_SIZE < 99) {	
	perfect_test(LIST_SIZE);
	insert_test(LIST_SIZE);
	exit(1);
  }
  SkipList* stest2 = SkipList::init_list(LIST_SIZE, POOL, maxl);
  assert(stest2);
  stest2->enable_counts();
  timespec ts;

  clock_gettime(CLOCK_MONOTONIC, &ts);
  time_t start = ts.tv_sec*1000000000 + ts.tv_nsec;
  for (int i = 0; i < ITERATIONS; i++) {
	int key = (rand() % LIST_SIZE);
	if (ITERATIONS < 50) printf("key: %d\n", key);
	stest2->fastFindTest(key);
  }
  clock_gettime(CLOCK_MONOTONIC, &ts);
  time_t test_lookup_time = ts.tv_sec*1000000000 + ts.tv_nsec;
  int test_lookup_ptr_follows = stest2->get_ptr_count();
  stest2->reset();
  assert(stest2->get_ptr_count() == 0);

  for (int i = 0; i < ITERATIONS; i++) {
	int key = (rand() % LIST_SIZE);
	if (ITERATIONS < 50) printf("key: %d\n", key);
	stest2->lookup(key);
  }
  clock_gettime(CLOCK_MONOTONIC, &ts);
  time_t lookup_time = ts.tv_sec*1000000000 + ts.tv_nsec;
  int lookup_ptr_follows = stest2->get_ptr_count();
  stest2->reset();
  assert(stest2->get_ptr_count() == 0);

  for (int i = 0; i < ITERATIONS; i++) {
	stest2->insert(rand() % POOL);
  }
  clock_gettime(CLOCK_MONOTONIC, &ts);
  time_t insert_time = ts.tv_sec*1000000000 + ts.tv_nsec;
  int insert_ptr_follows = stest2->get_ptr_count();

  printf("insertns: %ld; lookupns: %ld; testns: %ld, itr: %d; size: %d; levels: %d; probability: %d; ptr_lookups: %d, ptr_inserts: %d, ptr_test:%d, dd0:%d, dd1:%d, dd2:%d, dd3:%d, ddx:%d\n", 
		 (insert_time-lookup_time)/(ITERATIONS), (lookup_time-test_lookup_time)/(ITERATIONS), (test_lookup_time-start)/ITERATIONS, ITERATIONS, LIST_SIZE, maxl, FANOUT, lookup_ptr_follows, insert_ptr_follows, test_lookup_ptr_follows, stest2->drop_down_pred[0], stest2->drop_down_pred[1], stest2->drop_down_pred[2], stest2->drop_down_pred[3], stest2->drop_down_pred[4]);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rsi, %r14
movl %edi, %ebp
xorl %edi, %edi
callq 0x10b0
movl %eax, %edi
callq 0x10c0
movl $0x10, %ebx
cmpl $0x2, %ebp
jl 0x2bd2
movq 0x8(%r14), %rdi
callq 0x1110
movl %eax, %ebx
cvtsi2sd %ebx, %xmm0
callq 0x1080
divsd 0x425(%rip), %xmm0      # 0x3008
callq 0x1120
cmpl $0x62, %ebx
jle 0x2de8
leal (%rbx,%rbx,2), %ebp
addsd 0x414(%rip), %xmm0      # 0x3010
cvttsd2si %xmm0, %edx
movl %ebx, %edi
movl %ebp, %esi
movq %rdx, 0x30(%rsp)
callq 0x1b40
movq %rax, %r15
movl $0x1, 0x2c(%rax)
leaq 0x38(%rsp), %r12
movl $0x1, %edi
movq %r12, %rsi
callq 0x10a0
movq (%r12), %rax
movq %rax, 0x18(%rsp)
movq 0x8(%r12), %rax
movq %rax, 0x20(%rsp)
movl $0x2710, %r14d          # imm = 0x2710
callq 0x1050
cltd
idivl %ebx
movq %r15, %rdi
movl %edx, %esi
callq 0x147c
decl %r14d
jne 0x2c43
leaq 0x38(%rsp), %r12
movl $0x1, %edi
movq %r12, %rsi
callq 0x10a0
movq (%r12), %rax
movq %rax, (%rsp)
movq 0x8(%r12), %rax
movq %rax, 0x8(%rsp)
movl 0x28(%r15), %eax
movq %rax, 0x28(%rsp)
movl $0x0, 0x28(%r15)
movl $0x2710, %r14d          # imm = 0x2710
callq 0x1050
cltd
idivl %ebx
movq %r15, %rdi
movl %edx, %esi
callq 0x137e
decl %r14d
jne 0x2c95
leaq 0x38(%rsp), %r12
movl $0x1, %edi
movq %r12, %rsi
callq 0x10a0
movq (%r12), %r14
movq 0x8(%r12), %r13
movl 0x28(%r15), %eax
movq %rax, 0x10(%rsp)
movl $0x0, 0x28(%r15)
movl $0x2710, %r12d          # imm = 0x2710
callq 0x1050
cltd
idivl %ebp
movq %r15, %rdi
movl %edx, %esi
callq 0x1992
decl %r12d
jne 0x2cde
imulq $0x3b9aca00, %r14, %r12 # imm = 0x3B9ACA00
addq %r13, %r12
imulq $0x3b9aca00, (%rsp), %r14 # imm = 0x3B9ACA00
addq 0x8(%rsp), %r14
leaq 0x38(%rsp), %r13
movl $0x1, %edi
movq %r13, %rsi
callq 0x10a0
imulq $0x3b9aca00, (%r13), %rcx # imm = 0x3B9ACA00
movq 0x8(%r13), %rax
movl 0x28(%r15), %r10d
subq %r12, %rax
addq %rcx, %rax
movabsq $0x346dc5d63886594b, %rcx # imm = 0x346DC5D63886594B
imulq %rcx
movq %rdx, %rsi
shrq $0x3f, %rsi
sarq $0xb, %rdx
addq %rdx, %rsi
subq %r14, %r12
movq %r12, %rax
imulq %rcx
movq %rdx, %r8
movq %rdx, %rax
shrq $0x3f, %rax
sarq $0xb, %r8
addq %rax, %r8
imulq $-0x3b9aca00, 0x18(%rsp), %rax # imm = 0xC4653600
subq 0x20(%rsp), %rax
addq %r14, %rax
imulq %rcx
movq %rdx, %rcx
shrq $0x3f, %rcx
sarq $0xb, %rdx
addq %rdx, %rcx
movl 0x14(%r15), %r11d
movl 0x18(%r15), %r14d
movl 0x1c(%r15), %r12d
movl 0x20(%r15), %r13d
movl 0x24(%r15), %r15d
leaq 0x659(%rip), %rdi       # 0x33ff
movq %r8, %rdx
movl $0x2710, %r8d           # imm = 0x2710
movl %ebx, %r9d
xorl %eax, %eax
pushq %r15
pushq %r13
pushq %r12
pushq %r14
pushq %r11
pushq 0x50(%rsp)
pushq %r10
pushq 0x48(%rsp)
pushq $0x4
pushq 0x78(%rsp)
callq 0x1040
addq $0x50, %rsp
xorl %eax, %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl %ebx, %edi
callq 0x2ad1