#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include “csim.h”

#define NUM_CLIENTS 5
#define DB_SIZE 500
#define DATA_ITEM_SIZE 1024
#define BANDWIDTH 10000
#define CACHE_SIZE 100
#define NUM_HOT_ITEMS 50

double t_query_arr[] = {5, 10, 25, 50, 100};
double t_update_arr[] = {5, 10, 20, 100, 200};
float hot_access_prob = 0.8;
float hot_update_prob = 0.33;

typedef struct {
    int id;
    double q_gen_time;
    double u_arr_time;
} node;

FACILITY server;
TABLE query_delay, cache_hit_ratio;
node *nodes;
float total_queries = 0;
float cache_hits = 0;

void client();
void generate_query(node *n);
void query_result(node *n);
void handle_csim_error_message(long err);

int main() {
    long err;
    create(“simple_pull_based_cache”);
    nodes = (node *)malloc(NUM_CLIENTS * sizeof(node));
    err = facility(“Server”, &server);
    handle_csim_error_message(err);
    table_init(“Query Delay”, &query_delay);
    table_init(“Cache Hit Ratio”, &cache_hit_ratio);

    // Simulating
    for (size_t q = 0; q < sizeof(t_query_arr) / sizeof(t_query_arr[0]); q++) {
        for (size_t u = 0; u < sizeof(t_update_arr) / sizeof(t_update_arr[0]); u++) {
            reset();

            total_queries = 0;
            cache_hits = 0;

            for (int i = 0; i < NUM_CLIENTS; i++) {
                nodes[i].id = i;
                nodes[i].q_gen_time = t_query_arr[q];
                nodes[i].u_arr_time = t_update_arr[u];
                node_activity(client);
            }

            schedule(START, 0.0);
            schedule(END, 10e4);
            simulate();

            printf(“Cache hit ratio: %.2f\n”, cache_hits / total_queries);
            printf(“Query delay: %.2f\n”, tbl_mean(query_delay));
            printf(“\n”);
        }
    }

    // Clean up
    table_rm(query_delay);
    table_rm(cache_hit_ratio);
    err = facility_rm(server);
    handle_csim_error_message(err);
    cleanup();
    free(nodes);

    return 0;
}

void client() {
    node *n = nodes[node_id()];
    while (clock < 10e4) {
        hold(exponential(n->q_gen_time));

        float prob = lrand48() / (float)RAND_MAX;

        // Hot data item or cold data item
        int data_item;
        if (prob < hot_access_prob) {
            data_item = lrand48() % NUM_HOT_ITEMS + 1;
        } else {
            data_item = NUM_HOT_ITEMS + (lrand48() % (DB_SIZE - NUM_HOT_ITEMS));
        }

        generate_query(n);
    }
}

void generate_query(node *n) {
    request(server);
    double q_start_time = clock;
    hold(DATA_ITEM_SIZE * 8 / BANDWIDTH);

    float prob = lrand48() / (float)RAND_MAX;

    // Query can be answered using the local cache
    if (prob < (CACHE_SIZE / (double)DB_SIZE)) {
        cache_hits++;
        release(server);

        // Send a check message to the server
        request(server);
        hold(DATA_ITEM_SIZE * 8 / BANDWIDTH);

        // Receive confirm message from the server
        release(server);

    } else {
        // Request data item from the server
        release(server);
        query_result(n);
    }

    // Calculate query delay
    double q_delay = clock - q_start_time;
    sample(query_delay, q_delay);

    total_queries++;
}

void query_result(node *n) {
    hold(exponential(n->u_arr_time));

    // Probability of hot data item update
    float prob = lrand48() / (float)RAND_MAX;

    if (prob < hot_update_prob) {
        request(server);
        hold(DATA_ITEM_SIZE * 8 / BANDWIDTH);

        // Update hot data item
        release(server);
    }
}

void handle_csim_error_message(long err) {
    if (err != 0) {
        printf(“Error: %s\n”, csim_error_message[err]);
        exit(1);
    }
}


can you recheck this code and see if there are any logical or any other errors, the code is supposed to be for the following scenario, if it doesnt follow the scenario kindly change it till it does,
Implement a simple pull-based cache invalidation scheme by using CSIM in C. In the scheme, a node generates a query and sends a request message to a server if the queried data item is not found in its local cache. If the node generates a query that can be answered by its local cache, it sends a check message to the server for validity. The server replies to the node with a requested data item or a confirm message. A set of data items is updated in the server. This scheme ensures a strong consistency that guarantees to access the most updated data items. Note that remove a cold state before collecting any results. use the following simulation parameters .make sure to output cache hit ratio and (ii) query delay by changing mean query generation time and mean update arrival time. 
Parameter Values 
Number of clients 5 
Database (DB) size 500 items 
Data item size 1024 bytes
 Bandwidth 10000 bits/s 
Cache size 100 items 
Cache replacement policy LRU 
Mean query generate time (T_query) 5, 10, 25, 50, 100 seconds 
Hot data items 1 to 50 
Cold data items remainder of DB 
Hot data access prob. 0.8 
Mean update arrival time (T_update) 5, 10, 20, 100, 200 seconds 
Hot data update prob. 0.33