// File: /workspace/github_cpp_makefile_star2_O2/shreyas-gopalakrishna[P]Concurrent-Skip-list/unit_test_3.cpp
// Function: main
int main(int argc, char *argv[]){

    cout << "\n---------- Unit Test - 3 ----------" << endl;

    cout << "\nThis Unit test uses 8 Threads. Numbers (1-5000) are used for this unit test." << endl;
    cout << "All threads call a function which performs insert, delete, search and range with random numbers (1-5000)." << endl;
    cout << "This simulates all operations parallelly on the skip list." << endl;

    cout << "\nThe final elements in the skip list will be based on if insert or delete got scheduled and executed first for any given element.\n" << endl;
    
    cout << "Few of the numbers from the 'delete vector' are deleted from the skip list and few may still exist since insert got scheduled after delete for these numbers." << endl;
    cout << "But the tests notice that none of the numbers not present in the 'delete vector' are deleted. And our traversal of the skip list is sorted. This verifies our skip list to be accurate. \n" << endl;

	generate_input(5000);

    skiplist = SkipList(numbers_insert.size(), 0.5);

    concurrent_skiplist_combined();

    // checking if insert is done
    if(skiplist.search(numbers_insert[0]) == to_string(numbers_insert[0]) || skiplist.search(numbers_insert[0]) == ""){
        cout << "Unit Test 1: Insert: PASS" << endl;
    }else{
        cout << "Unit Test 1: Insert: FAIL" << endl;
    }

    // checking if insert is done
    if(skiplist.search(numbers_insert[1]) == to_string(numbers_insert[1]) || skiplist.search(numbers_insert[1]) == "" ){
        cout << "Unit Test 2: Insert: PASS" << endl;
    }else{
        cout << "Unit Test 2: Insert: FAIL" << endl;
    }


    // checking if delete is done
    if(skiplist.search(numbers_delete[0]) == ""){
        cout << "Unit Test 3: Delete: PASS" << endl;
    }else{
        cout << "Unit Test 3: Delete: FAIL" << endl;
    }

    // checking if delete is done
    if(skiplist.search(numbers_delete[1]) == ""){
        cout << "Unit Test 4: Delete: PASS" << endl;
    }else{
        cout << "Unit Test 4: Delete: FAIL" << endl;
    }


    if(skiplist.search(numbers_get[0]) == to_string(numbers_get[0]) || skiplist.search(numbers_get[0]) == ""){
        cout << "Unit Test 5: Search: PASS" << endl;
    }else{
        cout << "Unit Test 5: Insert: FAIL" << endl;
    }

    // checking if Search is done
    if(skiplist.search(numbers_get[1]) == to_string(numbers_get[1]) || skiplist.search(numbers_get[1]) == ""){
        cout << "Unit Test 6: Search: PASS" << endl;
    }else{
        cout << "Unit Test 6: Search: FAIL" << endl;
    }

    // checking by search if deleted element is present
    if(skiplist.search(numbers_delete[0]) == ""){
        cout << "Unit Test 7: Search: PASS" << endl;
    }else{
        cout << "Unit Test 7: Search: FAIL" << endl;
    }

    map<int, string> range_output = skiplist.range(1, 5000);

    // checking range
    if(range_output.count(numbers_delete[0]) == 0){
        cout << "Unit Test 8: Range: PASS" << endl;
    }else{
        cout << "Unit Test 8: Range: FAIL" << endl;
    }

    // checking range
    if(range_output.count(numbers_delete[1]) == 0){
        cout << "Unit Test 9: Range: PASS" << endl;
    }else{
        cout << "Unit Test 9: Range: FAIL" << endl;
    }

	
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x70, %rsp
movq 0x660a(%rip), %rbx      # 0x8fd0
leaq 0x2653(%rip), %rsi      # 0x5020
movq %rbx, %rdi
callq 0x21b0
movq %rax, %rdi
callq 0x20f0
leaq 0x2661(%rip), %rsi      # 0x5045
movq %rbx, %rdi
callq 0x21b0
movq %rax, %rdi
callq 0x20f0
leaq 0x2698(%rip), %rsi      # 0x5093
movq %rbx, %rdi
callq 0x21b0
movq %rax, %rdi
callq 0x20f0
leaq 0x26eb(%rip), %rsi      # 0x50fd
movq %rbx, %rdi
callq 0x21b0
movq %rax, %rdi
callq 0x20f0
leaq 0x270f(%rip), %rsi      # 0x5138
movq %rbx, %rdi
callq 0x21b0
movq %rax, %rdi
callq 0x20f0
leaq 0x277b(%rip), %rsi      # 0x51bb
movq %rbx, %rdi
callq 0x21b0
movq %rax, %rdi
callq 0x20f0
leaq 0x2802(%rip), %rsi      # 0x5259
movq %rbx, %rdi
callq 0x21b0
movq %rax, %rdi
callq 0x20f0
movl $0x1388, %edi           # imm = 0x1388
callq 0x24ec
movq 0x6740(%rip), %rsi      # 0x91b8
subq 0x6731(%rip), %rsi      # 0x91b0
shrq $0x2, %rsi
leaq 0x20(%rsp), %rbx
movss 0x2574(%rip), %xmm0     # 0x5004
movq %rbx, %rdi
callq 0x3dfc
movups (%rbx), %xmm0
movups %xmm0, 0x66fe(%rip)     # 0x91a0
leaq 0x66f7(%rip), %r14      # 0x91a0
movq %rbx, %rdi
callq 0x4b08
callq 0x2904
movq 0x66f3(%rip), %rax      # 0x91b0
movl (%rax), %edx
leaq 0x20(%rsp), %rdi
movq %r14, %rsi
callq 0x4348
movq 0x66dd(%rip), %rax      # 0x91b0
movl (%rax), %esi
movq %rsp, %rdi
callq 0x3004
leaq 0x20(%rsp), %rdi
movq %rsp, %rsi
callq 0x30f3
testb %al, %al
je 0x2b09
movq %rsp, %rdi
callq 0x20d0
leaq 0x20(%rsp), %rdi
callq 0x20d0
leaq 0x280c(%rip), %rsi      # 0x5313
jmp 0x2b68
movq 0x66a0(%rip), %rax      # 0x91b0
movl (%rax), %edx
leaq 0x6687(%rip), %rsi      # 0x91a0
leaq 0x50(%rsp), %rdi
callq 0x4348
leaq 0x27e8(%rip), %rsi      # 0x5312
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
callq 0x311c
movl %eax, %ebp
movq %rbx, %rdi
callq 0x20d0
movq %rsp, %rdi
callq 0x20d0
leaq 0x20(%rsp), %rdi
callq 0x20d0
leaq 0x27b9(%rip), %rax      # 0x5313
leaq 0x27cc(%rip), %rsi      # 0x532d
testb %bpl, %bpl
cmovneq %rax, %rsi
movq 0x6461(%rip), %rdi      # 0x8fd0
callq 0x21b0
movq %rax, %rdi
callq 0x20f0
movq 0x662d(%rip), %rax      # 0x91b0
movl 0x4(%rax), %edx
leaq 0x6613(%rip), %rsi      # 0x91a0
leaq 0x20(%rsp), %rdi
callq 0x4348
movq 0x6612(%rip), %rax      # 0x91b0
movl 0x4(%rax), %esi
movq %rsp, %rdi
callq 0x3004
leaq 0x20(%rsp), %rdi
movq %rsp, %rsi
callq 0x30f3
testb %al, %al
je 0x2bd5
movq %rsp, %rdi
callq 0x20d0
leaq 0x20(%rsp), %rdi
callq 0x20d0
leaq 0x2774(%rip), %rsi      # 0x5347
jmp 0x2c35
movq 0x65d4(%rip), %rax      # 0x91b0
movl 0x4(%rax), %edx
leaq 0x65ba(%rip), %rsi      # 0x91a0
leaq 0x50(%rsp), %rdi
callq 0x4348
leaq 0x271b(%rip), %rsi      # 0x5312
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
callq 0x311c
movl %eax, %ebp
movq %rbx, %rdi
callq 0x20d0
movq %rsp, %rdi
callq 0x20d0
leaq 0x20(%rsp), %rdi
callq 0x20d0
leaq 0x2720(%rip), %rax      # 0x5347
leaq 0x2733(%rip), %rsi      # 0x5361
testb %bpl, %bpl
cmovneq %rax, %rsi
movq 0x6394(%rip), %r14      # 0x8fd0
movq %r14, %rdi
callq 0x21b0
movq %rax, %rdi
callq 0x20f0
movq 0x6575(%rip), %rax      # 0x91c8
movl (%rax), %edx
leaq 0x6544(%rip), %rbx      # 0x91a0
leaq 0x20(%rsp), %r12
movq %r12, %rdi
movq %rbx, %rsi
callq 0x4348
leaq 0x269f(%rip), %r15      # 0x5312
movq %r12, %rdi
movq %r15, %rsi
callq 0x311c
movl %eax, %ebp
movq %r12, %rdi
callq 0x20d0
leaq 0x26ec(%rip), %rax      # 0x537b
leaq 0x26ff(%rip), %rsi      # 0x5395
testb %bpl, %bpl
cmovneq %rax, %rsi
movq %r14, %rdi
callq 0x21b0
movq %rax, %rdi
callq 0x20f0
movq 0x6514(%rip), %rax      # 0x91c8
movl 0x4(%rax), %edx
leaq 0x20(%rsp), %r12
movq %r12, %rdi
movq %rbx, %rsi
callq 0x4348
movq %r12, %rdi
movq %r15, %rsi
callq 0x311c
movl %eax, %ebp
movq %r12, %rdi
callq 0x20d0
leaq 0x26cc(%rip), %rax      # 0x53af
leaq 0x26df(%rip), %rsi      # 0x53c9
testb %bpl, %bpl
cmovneq %rax, %rsi
movq %r14, %rdi
callq 0x21b0
movq %rax, %rdi
callq 0x20f0
movq 0x64d8(%rip), %rax      # 0x91e0
movl (%rax), %edx
leaq 0x20(%rsp), %rdi
movq %rbx, %rsi
callq 0x4348
movq 0x64c2(%rip), %rax      # 0x91e0
movl (%rax), %esi
movq %rsp, %rdi
callq 0x3004
leaq 0x20(%rsp), %rdi
movq %rsp, %rsi
callq 0x30f3
testb %al, %al
je 0x2d54
movq %rsp, %rdi
callq 0x20d0
leaq 0x20(%rsp), %rdi
callq 0x20d0
leaq 0x2691(%rip), %rsi      # 0x53e3
jmp 0x2db3
movq 0x6485(%rip), %rax      # 0x91e0
movl (%rax), %edx
leaq 0x643c(%rip), %rsi      # 0x91a0
leaq 0x50(%rsp), %rdi
callq 0x4348
leaq 0x259d(%rip), %rsi      # 0x5312
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
callq 0x311c
movl %eax, %ebp
movq %rbx, %rdi
callq 0x20d0
movq %rsp, %rdi
callq 0x20d0
leaq 0x20(%rsp), %rdi
callq 0x20d0
leaq 0x263e(%rip), %rax      # 0x53e3
leaq 0x2651(%rip), %rsi      # 0x53fd
testb %bpl, %bpl
cmovneq %rax, %rsi
movq 0x6216(%rip), %rdi      # 0x8fd0
callq 0x21b0
movq %rax, %rdi
callq 0x20f0
movq 0x6412(%rip), %rax      # 0x91e0
movl 0x4(%rax), %edx
leaq 0x63c8(%rip), %rsi      # 0x91a0
leaq 0x20(%rsp), %rdi
callq 0x4348
movq 0x63f7(%rip), %rax      # 0x91e0
movl 0x4(%rax), %esi
movq %rsp, %rdi
callq 0x3004
leaq 0x20(%rsp), %rdi
movq %rsp, %rsi
callq 0x30f3
testb %al, %al
je 0x2e20
movq %rsp, %rdi
callq 0x20d0
leaq 0x20(%rsp), %rdi
callq 0x20d0
leaq 0x25f9(%rip), %rsi      # 0x5417
jmp 0x2e80
movq 0x63b9(%rip), %rax      # 0x91e0
movl 0x4(%rax), %edx
leaq 0x636f(%rip), %rsi      # 0x91a0
leaq 0x50(%rsp), %rdi
callq 0x4348
leaq 0x24d0(%rip), %rsi      # 0x5312
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
callq 0x311c
movl %eax, %ebp
movq %rbx, %rdi
callq 0x20d0
movq %rsp, %rdi
callq 0x20d0
leaq 0x20(%rsp), %rdi
callq 0x20d0
leaq 0x25a5(%rip), %rax      # 0x5417
leaq 0x25b8(%rip), %rsi      # 0x5431
testb %bpl, %bpl
cmovneq %rax, %rsi
movq 0x6149(%rip), %rbx      # 0x8fd0
movq %rbx, %rdi
callq 0x21b0
movq %rax, %rdi
callq 0x20f0
movq 0x632a(%rip), %rax      # 0x91c8
movl (%rax), %edx
leaq 0x62f9(%rip), %r14      # 0x91a0
leaq 0x20(%rsp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0x4348
leaq 0x2454(%rip), %rsi      # 0x5312
movq %r15, %rdi
callq 0x311c
movl %eax, %ebp
movq %r15, %rdi
callq 0x20d0
leaq 0x2574(%rip), %rax      # 0x544b
leaq 0x2587(%rip), %rsi      # 0x5465
testb %bpl, %bpl
cmovneq %rax, %rsi
movq %rbx, %rdi
callq 0x21b0
movq %rax, %rdi
callq 0x20f0
leaq 0x20(%rsp), %rbx
pushq $0x1
popq %rdx
movq %rbx, %rdi
movq %r14, %rsi
movl $0x1388, %ecx           # imm = 0x1388
callq 0x4808
movq 0x62b4(%rip), %rsi      # 0x91c8
movq %rbx, %rdi
callq 0x312a
testq %rax, %rax
leaq 0x2559(%rip), %rax      # 0x547f
leaq 0x256b(%rip), %rsi      # 0x5498
cmoveq %rax, %rsi
movq 0x6098(%rip), %rdi      # 0x8fd0
callq 0x21b0
movq %rax, %rdi
callq 0x20f0
movq 0x627c(%rip), %rsi      # 0x91c8
addq $0x4, %rsi
leaq 0x20(%rsp), %rdi
callq 0x312a
testq %rax, %rax
leaq 0x254d(%rip), %rax      # 0x54b1
leaq 0x255f(%rip), %rsi      # 0x54ca
cmoveq %rax, %rsi
movq 0x605a(%rip), %rdi      # 0x8fd0
callq 0x21b0
movq %rax, %rdi
callq 0x20f0
leaq 0x20(%rsp), %rdi
callq 0x31de
xorl %eax, %eax
addq $0x70, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
jmp 0x2fa2
jmp 0x2fa2
jmp 0x2fa2
movq %rax, %rbx
movq %rsp, %rdi
callq 0x20d0
jmp 0x2fb8
jmp 0x2fb5
jmp 0x2fb5
jmp 0x2fb5
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x20d0
jmp 0x2fd1
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x31de
movq %rbx, %rdi
callq 0x22a0
nop