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

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

    cout << "\nThis Unit test uses 4 Threads. Numbers (1-30) are inserted into the skip list parallelly." << endl;
    cout << "Then a few numbers at random are removed from the skip list parallelly. And next a few numbers are searched in the skip list." << endl;
    cout << "Finally, few Range operations are done in the skip list parallelly. The output is dislayed after each step for verification." << endl;
    cout << "This Unit test displays the output. Output may be interleaved since multiple threads tend to print together." << endl;
    

	generate_input(30);

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

    vector<thread> threads;

    cout << "\n---------- Numbers inserted parallelly ----------" << endl;

    for (auto i = numbers_insert.begin(); i != numbers_insert.end(); ++i)
    std::cout << *i << ' ';
    cout << endl;

    // insert
    int chunk_size = ceil(float(numbers_insert.size()) / num_threads);
    for(size_t i = 0; i < numbers_insert.size(); i = i + chunk_size){
        threads.push_back(thread(skiplist_add, i, i+chunk_size));
    }
    for (auto &th : threads) {
        th.join();
    }
    threads.clear();

    cout << "\n---------- Skip list after insert ----------" << endl;
    skiplist.display();


    cout << "\n---------- Numbers deleted parallelly ----------" << endl;

    for (auto i = numbers_delete.begin(); i != numbers_delete.end(); ++i)
    std::cout << *i << ' ';
    cout << endl;

    // delete
    chunk_size = ceil(float(numbers_delete.size()) / num_threads);
    for(size_t i = 0; i < numbers_delete.size(); i = i + chunk_size){
        threads.push_back(thread(skiplist_remove, i, i+chunk_size));
    }
    for (auto &th : threads) {
        th.join();
    }
    threads.clear();

    cout << "\n---------- Skip list after delete ----------" << endl;
    skiplist.display();

    cout << "\n---------- Numbers searched parallelly ----------" << endl;

    for (auto i = numbers_get.begin(); i != numbers_get.end(); ++i)
    std::cout << *i << ' ';
    cout << endl;

    // search
    chunk_size = ceil(float(numbers_get.size()) / num_threads);
    for(size_t i = 0; i < numbers_get.size(); i = i + chunk_size){
        threads.push_back(thread(skiplist_search, i, i+chunk_size));
    }
    for (auto &th : threads) {
        th.join();
    }
    threads.clear();

    cout << "\n---------- Range between random numbers in Skip list parallely ---------- " << endl;
    // range
    for(size_t i = 0; i < num_threads; i++){
        threads.push_back(thread(skiplist_range, numbers_range[i].first, numbers_range[i].second));
    }
    for (auto &th : threads) {
        th.join();
    }
	
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq 0x7603(%rip), %rbx      # 0x9fd0
leaq 0x3685(%rip), %rsi      # 0x6059
movq %rbx, %rdi
callq 0x21b0
movq %rax, %rdi
callq 0x20d0
leaq 0x3693(%rip), %rsi      # 0x607e
movq %rbx, %rdi
callq 0x21b0
movq %rax, %rdi
callq 0x20d0
leaq 0x36d7(%rip), %rsi      # 0x60d9
movq %rbx, %rdi
callq 0x21b0
movq %rax, %rdi
callq 0x20d0
leaq 0x373e(%rip), %rsi      # 0x6157
movq %rbx, %rdi
callq 0x21b0
movq %rax, %rdi
callq 0x20d0
leaq 0x37a4(%rip), %rsi      # 0x61d4
movq %rbx, %rdi
callq 0x21b0
movq %rax, %rdi
callq 0x20d0
pushq $0x1e
popq %rdi
callq 0x252c
movq 0x7789(%rip), %rsi      # 0xa1d8
subq 0x777a(%rip), %rsi      # 0xa1d0
shrq $0x2, %rsi
leaq 0x10(%rsp), %r14
movss 0x359d(%rip), %xmm0     # 0x6004
movq %r14, %rdi
callq 0x3e90
movups (%r14), %xmm0
movups %xmm0, 0x7746(%rip)     # 0xa1c0
movq %r14, %rdi
callq 0x4b9c
xorps %xmm0, %xmm0
movaps %xmm0, (%r14)
andq $0x0, 0x10(%r14)
leaq 0x37ac(%rip), %rsi      # 0x6241
movq %rbx, %rdi
callq 0x21b0
movq %rax, %rdi
callq 0x20d0
movq 0x7724(%rip), %r14      # 0xa1d0
movq 0x751d(%rip), %rbx      # 0x9fd0
pushq $0x20
popq %rbp
cmpq 0x771b(%rip), %r14      # 0xa1d8
je 0x2ada
movl (%r14), %esi
movq %rbx, %rdi
callq 0x22a0
movq %rax, %rdi
movl %ebp, %esi
callq 0x2200
addq $0x4, %r14
jmp 0x2ab6
movq 0x74ef(%rip), %rdi      # 0x9fd0
callq 0x20d0
movq 0x76eb(%rip), %rbp      # 0xa1d8
movq 0x76dc(%rip), %rbx      # 0xa1d0
movq %rbp, %rax
subq %rbx, %rax
sarq $0x2, %rax
js 0x2b07
cvtsi2ss %rax, %xmm0
jmp 0x2b1c
movq %rax, %rcx
shrq %rcx
andl $0x1, %eax
orq %rcx, %rax
cvtsi2ss %rax, %xmm0
addss %xmm0, %xmm0
movq 0x7675(%rip), %rax      # 0xa198
testq %rax, %rax
js 0x2b2f
cvtsi2ss %rax, %xmm1
jmp 0x2b44
movq %rax, %rcx
shrq %rcx
andl $0x1, %eax
orq %rcx, %rax
cvtsi2ss %rax, %xmm1
addss %xmm1, %xmm1
divss %xmm1, %xmm0
callq 0x2100
cvttss2si %xmm0, %eax
movslq %eax, %r15
xorl %eax, %eax
leaq 0x30(%rsp), %r14
leaq 0x28(%rsp), %r12
leaq 0x10(%rsp), %r13
subq %rbx, %rbp
movq %rax, 0x8(%rsp)
sarq $0x2, %rbp
cmpq %rbp, %rax
jae 0x2bc0
addq %r15, %rax
movq %rax, 0x28(%rsp)
movq %r14, %rdi
leaq -0x51d(%rip), %rsi      # 0x266b
leaq 0x8(%rsp), %rdx
movq %r12, %rcx
callq 0x30de
movq %r13, %rdi
movq %r14, %rsi
callq 0x375a
movq %r14, %rdi
callq 0x3160
movq 0x8(%rsp), %rax
addq %r15, %rax
movq 0x7621(%rip), %rbp      # 0xa1d8
movq 0x7612(%rip), %rbx      # 0xa1d0
jmp 0x2b65
movq 0x10(%rsp), %rbx
movq 0x18(%rsp), %r14
cmpq %r14, %rbx
je 0x2bdd
movq %rbx, %rdi
callq 0x2290
addq $0x8, %rbx
jmp 0x2bca
leaq 0x10(%rsp), %rdi
callq 0x316e
movq 0x73e2(%rip), %rdi      # 0x9fd0
leaq 0x367f(%rip), %rsi      # 0x6274
callq 0x21b0
movq %rax, %rdi
callq 0x20d0
leaq 0x75b7(%rip), %rdi      # 0xa1c0
callq 0x4ae4
movq 0x73bb(%rip), %rdi      # 0x9fd0
leaq 0x3686(%rip), %rsi      # 0x62a2
callq 0x21b0
movq %rax, %rdi
callq 0x20d0
movq 0x75b8(%rip), %r14      # 0xa1e8
movq 0x7399(%rip), %rbx      # 0x9fd0
pushq $0x20
popq %rbp
cmpq 0x75af(%rip), %r14      # 0xa1f0
je 0x2c5e
movl (%r14), %esi
movq %rbx, %rdi
callq 0x22a0
movq %rax, %rdi
movl %ebp, %esi
callq 0x2200
addq $0x4, %r14
jmp 0x2c3a
movq 0x736b(%rip), %rdi      # 0x9fd0
callq 0x20d0
movq 0x757f(%rip), %rbp      # 0xa1f0
movq 0x7570(%rip), %rbx      # 0xa1e8
movq %rbp, %rax
subq %rbx, %rax
sarq $0x2, %rax
js 0x2c8b
cvtsi2ss %rax, %xmm0
jmp 0x2ca0
movq %rax, %rcx
shrq %rcx
andl $0x1, %eax
orq %rcx, %rax
cvtsi2ss %rax, %xmm0
addss %xmm0, %xmm0
movq 0x74f1(%rip), %rax      # 0xa198
testq %rax, %rax
js 0x2cb3
cvtsi2ss %rax, %xmm1
jmp 0x2cc8
movq %rax, %rcx
shrq %rcx
andl $0x1, %eax
orq %rcx, %rax
cvtsi2ss %rax, %xmm1
addss %xmm1, %xmm1
divss %xmm1, %xmm0
callq 0x2100
cvttss2si %xmm0, %eax
movslq %eax, %r15
xorl %eax, %eax
leaq 0x30(%rsp), %r14
leaq 0x28(%rsp), %r12
leaq 0x10(%rsp), %r13
subq %rbx, %rbp
movq %rax, 0x8(%rsp)
sarq $0x2, %rbp
cmpq %rbp, %rax
jae 0x2d44
addq %r15, %rax
movq %rax, 0x28(%rsp)
movq %r14, %rdi
leaq -0x5e8(%rip), %rsi      # 0x2724
leaq 0x8(%rsp), %rdx
movq %r12, %rcx
callq 0x30de
movq %r13, %rdi
movq %r14, %rsi
callq 0x375a
movq %r14, %rdi
callq 0x3160
movq 0x8(%rsp), %rax
addq %r15, %rax
movq 0x74b5(%rip), %rbp      # 0xa1f0
movq 0x74a6(%rip), %rbx      # 0xa1e8
jmp 0x2ce9
movq 0x10(%rsp), %rbx
movq 0x18(%rsp), %r14
cmpq %r14, %rbx
je 0x2d61
movq %rbx, %rdi
callq 0x2290
addq $0x8, %rbx
jmp 0x2d4e
leaq 0x10(%rsp), %rdi
callq 0x316e
movq 0x725e(%rip), %rdi      # 0x9fd0
leaq 0x355b(%rip), %rsi      # 0x62d4
callq 0x21b0
movq %rax, %rdi
callq 0x20d0
leaq 0x7433(%rip), %rdi      # 0xa1c0
callq 0x4ae4
movq 0x7237(%rip), %rdi      # 0x9fd0
leaq 0x3562(%rip), %rsi      # 0x6302
callq 0x21b0
movq %rax, %rdi
callq 0x20d0
movq 0x744c(%rip), %r14      # 0xa200
movq 0x7215(%rip), %rbx      # 0x9fd0
pushq $0x20
popq %rbp
cmpq 0x7443(%rip), %r14      # 0xa208
je 0x2de2
movl (%r14), %esi
movq %rbx, %rdi
callq 0x22a0
movq %rax, %rdi
movl %ebp, %esi
callq 0x2200
addq $0x4, %r14
jmp 0x2dbe
movq 0x71e7(%rip), %rdi      # 0x9fd0
callq 0x20d0
movq 0x7413(%rip), %rbp      # 0xa208
movq 0x7404(%rip), %rbx      # 0xa200
movq %rbp, %rax
subq %rbx, %rax
sarq $0x2, %rax
js 0x2e0f
cvtsi2ss %rax, %xmm0
jmp 0x2e24
movq %rax, %rcx
shrq %rcx
andl $0x1, %eax
orq %rcx, %rax
cvtsi2ss %rax, %xmm0
addss %xmm0, %xmm0
movq 0x736d(%rip), %rax      # 0xa198
testq %rax, %rax
js 0x2e37
cvtsi2ss %rax, %xmm1
jmp 0x2e4c
movq %rax, %rcx
shrq %rcx
andl $0x1, %eax
orq %rcx, %rax
cvtsi2ss %rax, %xmm1
addss %xmm1, %xmm1
divss %xmm1, %xmm0
callq 0x2100
cvttss2si %xmm0, %eax
movslq %eax, %r15
xorl %eax, %eax
leaq 0x30(%rsp), %r14
leaq 0x28(%rsp), %r12
leaq 0x10(%rsp), %r13
subq %rbx, %rbp
movq %rax, 0x8(%rsp)
sarq $0x2, %rbp
cmpq %rbp, %rax
jae 0x2ec8
addq %r15, %rax
movq %rax, 0x28(%rsp)
movq %r14, %rdi
leaq -0x70b(%rip), %rsi      # 0x2785
leaq 0x8(%rsp), %rdx
movq %r12, %rcx
callq 0x30de
movq %r13, %rdi
movq %r14, %rsi
callq 0x375a
movq %r14, %rdi
callq 0x3160
movq 0x8(%rsp), %rax
addq %r15, %rax
movq 0x7349(%rip), %rbp      # 0xa208
movq 0x733a(%rip), %rbx      # 0xa200
jmp 0x2e6d
movq 0x10(%rsp), %rbx
movq 0x18(%rsp), %r14
cmpq %r14, %rbx
je 0x2ee5
movq %rbx, %rdi
callq 0x2290
addq $0x8, %rbx
jmp 0x2ed2
leaq 0x10(%rsp), %rdi
callq 0x316e
movq 0x70da(%rip), %rdi      # 0x9fd0
leaq 0x3438(%rip), %rsi      # 0x6335
callq 0x21b0
movq %rax, %rdi
callq 0x20d0
pushq $0x4
popq %r12
xorl %r13d, %r13d
leaq -0x6a1(%rip), %rbx      # 0x2877
leaq 0x8(%rsp), %r14
leaq 0x10(%rsp), %r15
cmpq 0x726f(%rip), %r13      # 0xa198
jae 0x2f64
movq 0x72e6(%rip), %rcx      # 0xa218
leaq (%rcx,%r12), %rdx
addq $-0x4, %rdx
addq %r12, %rcx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x3176
movq %r15, %rdi
movq %r14, %rsi
callq 0x375a
movq %r14, %rdi
callq 0x3160
incq %r13
addq $0x8, %r12
jmp 0x2f22
movq 0x10(%rsp), %rbx
movq 0x18(%rsp), %r14
cmpq %r14, %rbx
je 0x2f81
movq %rbx, %rdi
callq 0x2290
addq $0x8, %rbx
jmp 0x2f6e
leaq 0x10(%rsp), %rdi
callq 0x31f4
xorl %eax, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x2fd1
jmp 0x2fd1
jmp 0x2fd1
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
jmp 0x2fc4
jmp 0x2fd1
jmp 0x2fd1
jmp 0x2fbc
jmp 0x2fd1
jmp 0x2fd1
jmp 0x2fbc
jmp 0x2fd1
jmp 0x2fd1
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x3160
jmp 0x2fd4
jmp 0x2fd1
jmp 0x2fd1
jmp 0x2fd1
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x31f4
movq %rbx, %rdi
callq 0x22b0