// File: /workspace/github_c_makefile_star2_O3/giannisdravilas[P]Disease-Monitor/tests/../modules/DiseaseMonitor.c
// Function: dm_insert_record
bool dm_insert_record(Record record){

    MapNode found_node = map_find_node(map_ids_records, &(record->id));

    // Αν υπάρχει ήδη record με το ίδιο id
    if(found_node){

        // Βρίσκουμε το προηγούμενο record με το ίδιο id
        Record value = map_node_value(map_ids_records, found_node);

        // Αφαιρούμε από τα map_disease_country_date και map_NULL_disease ένα στοιχείο με τα
        // στοιχεία του προηγούμενου record. H map_find() δεν υπάρχει περίπτωση να επιστρέψει
        // NULL αφού σίγουρα θα έχει εισαχθεί τέτοιο στοιχείο και στα δύο Maps
        MapCount mapcount = malloc(sizeof(*mapcount));
        mapcount->disease = value->disease;
        mapcount->country = value->country;
        mapcount->date = value->date;
        (*(int*)map_find(map_disease_country_date, mapcount))--;
        (*(int*)map_find(map_NULL_diseases, value->disease))--;
        free(mapcount);

        // Αφαιρούμε και επανεισάγουμε το αντίστοιχο record και από τα υπόλοιπα maps, εκείνα
        // δηλαδή που χρησιμοποιεί η map_get_records()
        map_remove(map_ids_records, &(record->id));
        map_insert(map_ids_records, &(record->id), record);

        MapNode found = map_find_node(map_diseases_dates, record->disease);
        if(found){
            set_remove(map_node_value(map_diseases_dates, found), record);
            set_insert(map_node_value(map_diseases_dates, found), record);
        }

        found = map_find_node(map_countries_dates, record->country);
        if(found){
            set_remove(map_node_value(map_countries_dates, found), record);
            set_insert(map_node_value(map_countries_dates, found), record);
        }

        // Ενημερώνουμε και τα map_disease_country_date, map_NULL_diseases
        update_map_count(map_disease_country_date, record);

        Pointer value1 = map_find(map_NULL_diseases, record->disease);
        if(value){
            (*(int*)value1)++;
        }else{
            map_insert(map_NULL_diseases, record->disease, create_int(1));
        }

        return true;

    // Αν δεν υπάρχει record με το ίδιο id    
    }else{

        // Εισάγουμε το record στο map_ids_records
        map_insert(map_ids_records, &(record->id), record);

        // Κάθε στοιχείο του map_diseases_dates είναι ένα Set. Αν υπάρχει Set εισάγουμε
        // το record σε αυτό, αλλιώς δημιουργούμε ένα Set και έπειτα εισάγουμε το record.
        MapNode found = map_find_node(map_diseases_dates, record->disease);
        if(found){
            set_insert(map_node_value(map_diseases_dates, found), record);
        }else{
            Set set = set_create(compare_record_dates, NULL);
            map_insert(map_diseases_dates, record->disease, set);
            set_insert(set, record);
        }

        // Κάθε στοιχείο του map_countries_dates είναι ένα Set. Αν υπάρχει Set εισάγουμε
        // το record σε αυτό, αλλιώς δημιουργούμε ένα Set και έπειτα εισάγουμε το record.
        found = map_find_node(map_countries_dates, record->country);
        if(found){
            set_insert(map_node_value(map_countries_dates, found), record);
        }else{
            Set set = set_create(compare_record_dates, NULL);
            map_insert(map_countries_dates, record->country, set);
            set_insert(set, record);
        }

        // Ενημερώνουμε και τα map_disease_country_date, map_NULL_diseases
        update_map_count(map_disease_country_date, record);
        Pointer value = map_find(map_NULL_diseases, record->disease);
        if(value){
            (*(int*)value)++;
        }else{
            map_insert(map_NULL_diseases, record->disease, create_int(1));
        }

        return false;
    }
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %r14
movq 0x98e8(%rip), %rdi      # 0xe730
movq %r14, %rsi
callq 0x6dd5
movq %rax, %rbx
movq 0x98d6(%rip), %rdi      # 0xe730
testq %rax, %rax
je 0x4f94
movq %rbx, %rsi
callq 0x6dbb
movq %rax, %r15
movl $0x18, %edi
callq 0x21c0
movq %rax, %r12
movups 0x10(%r15), %xmm0
movups %xmm0, (%rax)
movq 0x20(%r15), %rax
movq %rax, 0x10(%r12)
movq 0x98b5(%rip), %rdi      # 0xe748
movq %r12, %rsi
callq 0x696d
decl (%rax)
movq 0x9884(%rip), %rdi      # 0xe728
movq 0x10(%r15), %rsi
callq 0x696d
decl (%rax)
movq %r12, %rdi
callq 0x22d0
movq 0x9872(%rip), %rdi      # 0xe730
movq %r14, %rsi
callq 0x67e6
movq 0x9863(%rip), %rdi      # 0xe730
movq %r14, %rsi
movq %r14, %rdx
callq 0x65e6
movq 0x9859(%rip), %rdi      # 0xe738
movq 0x10(%r14), %rsi
callq 0x6dd5
testq %rax, %rax
je 0x4f24
movq %rax, %r15
movq 0x9841(%rip), %rdi      # 0xe738
movq %rax, %rsi
callq 0x6dbb
movq %rax, %rdi
movq %r14, %rsi
callq 0x8088
movq 0x9827(%rip), %rdi      # 0xe738
movq %r15, %rsi
callq 0x6dbb
movq %rax, %rdi
movq %r14, %rsi
callq 0x7fe8
movq 0x9815(%rip), %rdi      # 0xe740
movq 0x18(%r14), %rsi
callq 0x6dd5
testq %rax, %rax
je 0x4f70
movq %rax, %r15
movq 0x97fd(%rip), %rdi      # 0xe740
movq %rax, %rsi
callq 0x6dbb
movq %rax, %rdi
movq %r14, %rsi
callq 0x8088
movq 0x97e3(%rip), %rdi      # 0xe740
movq %r15, %rsi
callq 0x6dbb
movq %rax, %rdi
movq %r14, %rsi
callq 0x7fe8
movq 0x97d1(%rip), %rdi      # 0xe748
movq %r14, %rsi
callq 0x4d91
movq 0x97a2(%rip), %rdi      # 0xe728
movq 0x10(%r14), %rsi
callq 0x696d
jmp 0x5073
movq %r14, %rsi
movq %r14, %rdx
callq 0x65e6
movq 0x9792(%rip), %rdi      # 0xe738
movq 0x10(%r14), %rsi
callq 0x6dd5
testq %rax, %rax
je 0x4fc8
movq 0x977d(%rip), %rdi      # 0xe738
movq %rax, %rsi
callq 0x6dbb
movq %rax, %r15
jmp 0x4fec
leaq -0x588(%rip), %rdi      # 0x4a47
xorl %esi, %esi
callq 0x7f57
movq %rax, %r15
movq 0x9758(%rip), %rdi      # 0xe738
movq 0x10(%r14), %rsi
movq %rax, %rdx
callq 0x65e6
movq %r15, %rdi
movq %r14, %rsi
callq 0x7fe8
movq 0x9742(%rip), %rdi      # 0xe740
movq 0x18(%r14), %rsi
callq 0x6dd5
testq %rax, %rax
je 0x5020
movq 0x972d(%rip), %rdi      # 0xe740
movq %rax, %rsi
callq 0x6dbb
movq %rax, %r15
jmp 0x5044
leaq -0x5e0(%rip), %rdi      # 0x4a47
xorl %esi, %esi
callq 0x7f57
movq %rax, %r15
movq 0x9708(%rip), %rdi      # 0xe740
movq 0x18(%r14), %rsi
movq %rax, %rdx
callq 0x65e6
movq %r15, %rdi
movq %r14, %rsi
callq 0x7fe8
movq 0x96f2(%rip), %rdi      # 0xe748
movq %r14, %rsi
callq 0x4d91
movq 0x96c3(%rip), %rdi      # 0xe728
movq 0x10(%r14), %rsi
callq 0x696d
testq %rax, %rax
je 0x5087
incl (%rax)
testq %rbx, %rbx
setne %al
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
movq 0x969a(%rip), %r15      # 0xe728
movq 0x10(%r14), %r14
movl $0x4, %edi
callq 0x21c0
movl $0x1, (%rax)
movq %r15, %rdi
movq %r14, %rsi
movq %rax, %rdx
callq 0x65e6
jmp 0x5075