// File: /workspace/github_c_makefile_star2_O0/chatziko-k08[P]lecture-code/tests/ADTMap_test.c
// Function: test_insert
void test_insert(void) {

	Map map = map_create(compare_ints, free, free);
	map_set_hash_function(map, hash_int);

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

	for (int i = 0; i < N; i++) {
		key_array[i] = create_int(i);
	}

	// Ανακατεύουμε το key_array ώστε να υπάρχει ομοιόμορφη εισαγωγή τιμών
	shuffle(key_array, N);

	// Δοκιμάζουμε την insert εισάγοντας κάθε φορά νέους κόμβους
	for (int i = 0; i < N; i++) {
		value_array[i] = create_int(i);

		// Εισαγωγή, δοκιμή και έλεγχος ότι ενημερώθηκε το size
		insert_and_test(map, key_array[i], value_array[i]);

		TEST_ASSERT(map_size(map) == (i + 1)); 
	}

	// Προσθέτουμε ένα κλειδί που είναι __ισοδύναμο__ (όχι ίσο) με το κλειδί του πρώτου κόμβο
	// Και ελέγχουμε αν και το key και το value έχουν ενημερωθεί
	int* new_key = create_int(*key_array[0]);
	int* new_value = create_int(99);

	insert_and_test(map, new_key, new_value);

	map_destroy(map);

	// Δοκιμάζουμε ότι insert/replace δουλεύει σωστά και χωρίς αυτόματο free
	Map map2 = map_create(compare_ints, NULL, NULL);
	map_set_hash_function(map2, hash_int);

	int key1 = 0, key2 = 0;
	int value1 = 0, value2 = 0;

	insert_and_test(map2, &key1, &value1);
	insert_and_test(map2, &key1, &value2);
	insert_and_test(map2, &key2, &value2);

	map_destroy(map2);
	free(key_array);
	free(value_array);

	// Δοκιμάζουμε ότι η συμπεριφορά είναι σωστή όταν 2 keys κάνουν hash στην ίδια τιμή,
	// ακόμα και μετά από διαγραφή του ενός.
	Map map3 = map_create(compare_ints, NULL, NULL);
	map_set_hash_function(map3, hash_int);

	key1 = 1;
	key2 = 54;

	map_insert(map3, &key1, &value1);			// Τα key1,key2 κάνουν hash στην ίδια τιμή (σε hash table μεγέθους 53)
	map_insert(map3, &key2, &value1);
	TEST_ASSERT(map_remove(map3, &key1));
	map_insert(map3, &key2, &value2);			// πρέπει να αντικαταστήσει το key2
	TEST_ASSERT(map_size(map3) == 1);
	TEST_ASSERT(map_remove(map3, &key2));
	TEST_ASSERT(map_find(map3, &key2) == NULL);

	map_destroy(map3);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
leaq -0x25f(%rip), %rdi      # 0x43a0
movq 0x79ba(%rip), %rdx      # 0xbfc0
movq %rdx, %rsi
callq 0x5e20
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rdi
leaq 0x1d33(%rip), %rsi      # 0x6350
callq 0x6370
movl $0x3e8, -0xc(%rbp)      # imm = 0x3E8
movslq -0xc(%rbp), %rdi
shlq $0x3, %rdi
callq 0x2180
movq %rax, -0x18(%rbp)
movslq -0xc(%rbp), %rdi
shlq $0x3, %rdi
callq 0x2180
movq %rax, -0x20(%rbp)
movl $0x0, -0x24(%rbp)
movl -0x24(%rbp), %eax
cmpl -0xc(%rbp), %eax
jge 0x467c
movl -0x24(%rbp), %edi
callq 0x44a0
movq %rax, %rdx
movq -0x18(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x4652
movq -0x18(%rbp), %rdi
movl -0xc(%rbp), %esi
callq 0x4550
movl $0x0, -0x28(%rbp)
movl -0x28(%rbp), %eax
cmpl -0xc(%rbp), %eax
jge 0x4729
movl -0x28(%rbp), %edi
callq 0x44a0
movq %rax, %rdx
movq -0x20(%rbp), %rax
movslq -0x28(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rax
movslq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
movq -0x20(%rbp), %rax
movslq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rdx
callq 0x44d0
movq -0x8(%rbp), %rdi
callq 0x5f70
movl -0x28(%rbp), %ecx
addl $0x1, %ecx
cmpl %ecx, %eax
sete %al
andb $0x1, %al
movzbl %al, %edi
leaq 0x3bee(%rip), %rsi      # 0x82e1
movl $0x51, %edx
leaq 0x3ed8(%rip), %rcx      # 0x85d7
leaq 0x3c24(%rip), %r8       # 0x832a
movb $0x0, %al
callq 0x2370
cmpl $0x0, %eax
jne 0x4717
callq 0x2e50
jmp 0x4719
jmp 0x471b
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x468f
movq -0x18(%rbp), %rax
movq (%rax), %rax
movl (%rax), %edi
callq 0x44a0
movq %rax, -0x30(%rbp)
movl $0x63, %edi
callq 0x44a0
movq %rax, -0x38(%rbp)
movq -0x8(%rbp), %rdi
movq -0x30(%rbp), %rsi
movq -0x38(%rbp), %rdx
callq 0x44d0
movq -0x8(%rbp), %rdi
callq 0x61d0
leaq -0x3ca(%rip), %rdi      # 0x43a0
xorl %eax, %eax
movl %eax, %edx
movq %rdx, %rsi
callq 0x5e20
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rdi
leaq 0x1bcb(%rip), %rsi      # 0x6350
callq 0x6370
movl $0x0, -0x44(%rbp)
movl $0x0, -0x48(%rbp)
movl $0x0, -0x4c(%rbp)
movl $0x0, -0x50(%rbp)
movq -0x40(%rbp), %rdi
leaq -0x44(%rbp), %rsi
leaq -0x4c(%rbp), %rdx
callq 0x44d0
movq -0x40(%rbp), %rdi
leaq -0x44(%rbp), %rsi
leaq -0x50(%rbp), %rdx
callq 0x44d0
movq -0x40(%rbp), %rdi
leaq -0x48(%rbp), %rsi
leaq -0x50(%rbp), %rdx
callq 0x44d0
movq -0x40(%rbp), %rdi
callq 0x61d0
movq -0x18(%rbp), %rdi
callq 0x2270
movq -0x20(%rbp), %rdi
callq 0x2270
leaq -0x45b(%rip), %rdi      # 0x43a0
xorl %eax, %eax
movl %eax, %edx
movq %rdx, %rsi
callq 0x5e20
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rdi
leaq 0x1b3a(%rip), %rsi      # 0x6350
callq 0x6370
movl $0x1, -0x44(%rbp)
movl $0x36, -0x48(%rbp)
movq -0x58(%rbp), %rdi
leaq -0x44(%rbp), %rsi
leaq -0x4c(%rbp), %rdx
callq 0x6000
movq -0x58(%rbp), %rdi
leaq -0x48(%rbp), %rsi
leaq -0x4c(%rbp), %rdx
callq 0x6000
movq -0x58(%rbp), %rdi
leaq -0x44(%rbp), %rsi
callq 0x6100
andb $0x1, %al
movzbl %al, %edi
leaq 0x3a7d(%rip), %rsi      # 0x82e1
movl $0x76, %edx
leaq 0x3d67(%rip), %rcx      # 0x85d7
leaq 0x3acc(%rip), %r8       # 0x8343
movb $0x0, %al
callq 0x2370
cmpl $0x0, %eax
jne 0x4888
callq 0x2e50
jmp 0x488a
movq -0x58(%rbp), %rdi
leaq -0x48(%rbp), %rsi
leaq -0x50(%rbp), %rdx
callq 0x6000
movq -0x58(%rbp), %rdi
callq 0x5f70
cmpl $0x1, %eax
sete %al
andb $0x1, %al
movzbl %al, %edi
leaq 0x3a2b(%rip), %rsi      # 0x82e1
movl $0x78, %edx
leaq 0x3d15(%rip), %rcx      # 0x85d7
leaq 0x3a92(%rip), %r8       # 0x835b
movb $0x0, %al
callq 0x2370
cmpl $0x0, %eax
jne 0x48da
callq 0x2e50
jmp 0x48dc
jmp 0x48de
movq -0x58(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x6100
andb $0x1, %al
movzbl %al, %edi
leaq 0x39ea(%rip), %rsi      # 0x82e1
movl $0x79, %edx
leaq 0x3cd4(%rip), %rcx      # 0x85d7
leaq 0x3a65(%rip), %r8       # 0x836f
movb $0x0, %al
callq 0x2370
cmpl $0x0, %eax
jne 0x491b
callq 0x2e50
jmp 0x491d
jmp 0x491f
movq -0x58(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x5f90
cmpq $0x0, %rax
sete %al
andb $0x1, %al
movzbl %al, %edi
leaq 0x39a2(%rip), %rsi      # 0x82e1
movl $0x7a, %edx
leaq 0x3c8c(%rip), %rcx      # 0x85d7
leaq 0x3a35(%rip), %r8       # 0x8387
movb $0x0, %al
callq 0x2370
cmpl $0x0, %eax
jne 0x4963
callq 0x2e50
jmp 0x4965
movq -0x58(%rbp), %rdi
callq 0x61d0
addq $0x60, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)