// File: /workspace/github_c_makefile_star2_O0/chatziko-k08[P]lecture-code/tests/ADTSet_test.c
// Function: test_find
void test_find(void) {
	
	Set set = set_create(compare_ints, free);

	int N = 1000;

	int** value_array = malloc(N * sizeof(*value_array));

	for (int i = 0; i < N; i++)
		value_array[i] = create_int(i);

	// Παρόμοια με την set_remove, εάν το δέντρο δεν είναι σωστά ισορροπημένο, οι συναρτήσεις εύρεσης
	// στοιχείων δεν θα ελέγχονται πλήρως
	shuffle(value_array, N);

	for (int i = 0; i < N; i++) {
		set_insert(set, value_array[i]);

		SetNode found_node 	= set_find_node(set, value_array[i]);
		Pointer found_value = set_node_value(set, found_node);

		TEST_ASSERT(found_node != SET_EOF);
		TEST_ASSERT(found_value == value_array[i]);
	}

	// Αναζήτηση στοιχείου που δεν υπάρχει στο set
	int not_exists = 2000;
	TEST_ASSERT(set_find_node(set, &not_exists) == SET_EOF);
	TEST_ASSERT(set_find(set, &not_exists) == NULL);

	// Αναζήτηση μέγιστων/ελάχιστων στοιχείων
	// Συγκρίνουμε τις τιμές των δεικτών και όχι τους ίδιους τους δείκτες, καθώς
	// δεν γνωρίζουμε την θέση τους μετά απο το ανακάτεμα του πίνακα, αλλά γνωρίζουμε
	// ποιές τιμές υπάρχουν στο Set. Στη συγκεκριμένη περίπτωση, γνωρίζουμε ότι Set = {0, 1, ..., N-1}
	SetNode first_node = set_first(set);
	Pointer first_value = set_node_value(set, first_node);
	TEST_ASSERT((*(int *)first_value) == 0);

	SetNode next = set_next(set, first_node);
	Pointer next_value = set_node_value(set, next);
	TEST_ASSERT((*(int *)next_value) == 1);

	SetNode last_node = set_last(set);
	Pointer last_node_value = set_node_value(set, last_node);
	TEST_ASSERT((*(int *)last_node_value) == N-1);

	SetNode prev = set_previous(set, last_node);
	Pointer prev_value = set_node_value(set, prev);
	TEST_ASSERT((*(int *)prev_value) == N-2);

	// Ελέγχουμε και ότι βρίσκουμε σωστά τις τιμές από ενδιάμεσους κόμβους
	SetNode middle_node = set_find_node(set, value_array[N/2]);
	SetNode middle_node_prev = set_previous(set, middle_node);

	Pointer middle_node_value = set_node_value(set, middle_node);
	Pointer middle_node_value_prev = set_node_value(set, middle_node_prev);
	
	TEST_ASSERT(*(int *)middle_node_value == *(int *)middle_node_value_prev + 1);


	set_destroy(set);
	free(value_array);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
leaq -0x682(%rip), %rdi      # 0x43d0
movq 0x7567(%rip), %rsi      # 0xbfc0
callq 0x5d80
movq %rax, -0x8(%rbp)
movl $0x3e8, -0xc(%rbp)      # imm = 0x3E8
movslq -0xc(%rbp), %rdi
shlq $0x3, %rdi
callq 0x2180
movq %rax, -0x18(%rbp)
movl $0x0, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
cmpl -0xc(%rbp), %eax
jge 0x4aab
movl -0x1c(%rbp), %edi
callq 0x43a0
movq %rax, %rdx
movq -0x18(%rbp), %rax
movslq -0x1c(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x4a81
movq -0x18(%rbp), %rdi
movl -0xc(%rbp), %esi
callq 0x44a0
movl $0x0, -0x20(%rbp)
movl -0x20(%rbp), %eax
cmpl -0xc(%rbp), %eax
jge 0x4b9a
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rax
movslq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
callq 0x63f0
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rax
movslq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
callq 0x5e70
movq %rax, -0x28(%rbp)
movq -0x8(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x69b0
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x28(%rbp)
setne %al
andb $0x1, %al
movzbl %al, %edi
leaq 0x37c4(%rip), %rsi      # 0x82e1
movl $0xb4, %edx
leaq 0x3b2d(%rip), %rcx      # 0x8656
leaq 0x38c3(%rip), %r8       # 0x83f3
movb $0x0, %al
callq 0x2370
cmpl $0x0, %eax
jne 0x4b41
callq 0x2e50
jmp 0x4b43
jmp 0x4b45
movq -0x30(%rbp), %rax
movq -0x18(%rbp), %rcx
movslq -0x20(%rbp), %rdx
cmpq (%rcx,%rdx,8), %rax
sete %al
andb $0x1, %al
movzbl %al, %edi
leaq 0x377d(%rip), %rsi      # 0x82e1
movl $0xb5, %edx
leaq 0x3ae6(%rip), %rcx      # 0x8656
leaq 0x3892(%rip), %r8       # 0x8409
movb $0x0, %al
callq 0x2370
cmpl $0x0, %eax
jne 0x4b88
callq 0x2e50
jmp 0x4b8a
jmp 0x4b8c
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20(%rbp)
jmp 0x4abe
movl $0x7d0, -0x34(%rbp)     # imm = 0x7D0
movq -0x8(%rbp), %rdi
leaq -0x34(%rbp), %rsi
callq 0x5e70
cmpq $0x0, %rax
sete %al
andb $0x1, %al
movzbl %al, %edi
leaq 0x3720(%rip), %rsi      # 0x82e1
movl $0xba, %edx
leaq 0x3a89(%rip), %rcx      # 0x8656
leaq 0x3853(%rip), %r8       # 0x8427
movb $0x0, %al
callq 0x2370
cmpl $0x0, %eax
jne 0x4be5
callq 0x2e50
jmp 0x4be7
jmp 0x4be9
movq -0x8(%rbp), %rdi
leaq -0x34(%rbp), %rsi
callq 0x5e20
cmpq $0x0, %rax
sete %al
andb $0x1, %al
movzbl %al, %edi
leaq 0x36d8(%rip), %rsi      # 0x82e1
movl $0xbb, %edx
leaq 0x3a41(%rip), %rcx      # 0x8656
leaq 0x3836(%rip), %r8       # 0x8452
movb $0x0, %al
callq 0x2370
cmpl $0x0, %eax
jne 0x4c2d
callq 0x2e50
jmp 0x4c2f
movq -0x8(%rbp), %rdi
callq 0x6110
movq %rax, -0x40(%rbp)
movq -0x8(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x69b0
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
cmpl $0x0, (%rax)
sete %al
andb $0x1, %al
movzbl %al, %edi
leaq 0x367e(%rip), %rsi      # 0x82e1
movl $0xc3, %edx
leaq 0x39e7(%rip), %rcx      # 0x8656
leaq 0x37ff(%rip), %r8       # 0x8475
movb $0x0, %al
callq 0x2370
cmpl $0x0, %eax
jne 0x4c87
callq 0x2e50
jmp 0x4c89
movq -0x8(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x67c0
movq %rax, -0x50(%rbp)
movq -0x8(%rbp), %rdi
movq -0x50(%rbp), %rsi
callq 0x69b0
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
cmpl $0x1, (%rax)
sete %al
andb $0x1, %al
movzbl %al, %edi
leaq 0x3620(%rip), %rsi      # 0x82e1
movl $0xc7, %edx
leaq 0x3989(%rip), %rcx      # 0x8656
leaq 0x37bc(%rip), %r8       # 0x8490
movb $0x0, %al
callq 0x2370
cmpl $0x0, %eax
jne 0x4ce5
callq 0x2e50
jmp 0x4ce7
movq -0x8(%rbp), %rdi
callq 0x6190
movq %rax, -0x60(%rbp)
movq -0x8(%rbp), %rdi
movq -0x60(%rbp), %rsi
callq 0x69b0
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
movl (%rax), %eax
movl -0xc(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
sete %al
andb $0x1, %al
movzbl %al, %edi
leaq 0x35bf(%rip), %rsi      # 0x82e1
movl $0xcb, %edx
leaq 0x3928(%rip), %rcx      # 0x8656
leaq 0x3775(%rip), %r8       # 0x84aa
movb $0x0, %al
callq 0x2370
cmpl $0x0, %eax
jne 0x4d46
callq 0x2e50
jmp 0x4d48
movq -0x8(%rbp), %rdi
movq -0x60(%rbp), %rsi
callq 0x65f0
movq %rax, -0x70(%rbp)
movq -0x8(%rbp), %rdi
movq -0x70(%rbp), %rsi
callq 0x69b0
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rax
movl (%rax), %eax
movl -0xc(%rbp), %ecx
subl $0x2, %ecx
cmpl %ecx, %eax
sete %al
andb $0x1, %al
movzbl %al, %edi
leaq 0x355a(%rip), %rsi      # 0x82e1
movl $0xcf, %edx
leaq 0x38c3(%rip), %rcx      # 0x8656
leaq 0x3731(%rip), %r8       # 0x84cb
movb $0x0, %al
callq 0x2370
cmpl $0x0, %eax
jne 0x4dab
callq 0x2e50
jmp 0x4dad
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rax
movq %rax, -0xa0(%rbp)
movl -0xc(%rbp), %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movq -0xa0(%rbp), %rax
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rsi
callq 0x5e70
movq %rax, -0x80(%rbp)
movq -0x8(%rbp), %rdi
movq -0x80(%rbp), %rsi
callq 0x65f0
movq %rax, -0x88(%rbp)
movq -0x8(%rbp), %rdi
movq -0x80(%rbp), %rsi
callq 0x69b0
movq %rax, -0x90(%rbp)
movq -0x8(%rbp), %rdi
movq -0x88(%rbp), %rsi
callq 0x69b0
movq %rax, -0x98(%rbp)
movq -0x90(%rbp), %rax
movl (%rax), %eax
movq -0x98(%rbp), %rcx
movl (%rcx), %ecx
addl $0x1, %ecx
cmpl %ecx, %eax
sete %al
andb $0x1, %al
movzbl %al, %edi
leaq 0x349c(%rip), %rsi      # 0x82e1
movl $0xd8, %edx
leaq 0x3805(%rip), %rcx      # 0x8656
leaq 0x368f(%rip), %r8       # 0x84e7
movb $0x0, %al
callq 0x2370
cmpl $0x0, %eax
jne 0x4e69
callq 0x2e50
jmp 0x4e6b
movq -0x8(%rbp), %rdi
callq 0x6230
movq -0x18(%rbp), %rdi
callq 0x2270
addq $0xa0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)