3 changed files with 725 additions and 0 deletions
Binary file not shown.
Binary file not shown.
@ -0,0 +1,725 @@
@@ -0,0 +1,725 @@
|
||||
/* License: AGPLv3 or later. https://www.gnu.org/licenses/licenses.html
|
||||
*
|
||||
* Assignment 2 - Discrete Simulation |
||||
* Manish |
||||
* Student Login: ***** |
||||
*
|
||||
* Compile it as: |
||||
* gcc -Wall -std=c11 -o ass2 ass2.c |
||||
*/ |
||||
|
||||
#include <stdbool.h> |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
|
||||
enum category |
||||
{ |
||||
TOURIST = 0, |
||||
BUSINESS = 1, |
||||
}; |
||||
|
||||
typedef struct event |
||||
{ |
||||
// 0 for arrival 1+ for unique server ids
|
||||
int id; |
||||
double time; |
||||
int class; // 0 for tourist and 1 for business
|
||||
// service time for customer arrival and busy time for servers
|
||||
double duration; |
||||
} event; |
||||
|
||||
// customers_queue is dynamically scaled
|
||||
typedef struct customers_queue |
||||
{ |
||||
int first; |
||||
int next; |
||||
int size; // memory in use
|
||||
int capacity; // memory allocated to queue
|
||||
event* queue; |
||||
} customers_queue; |
||||
|
||||
typedef struct id_busy |
||||
{ |
||||
int id; // unique server ID
|
||||
double busy; // time server was busy
|
||||
} id_busy; |
||||
|
||||
// servers_queue are dynamically infantilized than not re-scaled
|
||||
typedef struct servers_queue |
||||
{ |
||||
int first; |
||||
int next; |
||||
int available; |
||||
int capacity; |
||||
id_busy* queue; |
||||
} servers_queue; |
||||
|
||||
// Used as temporary storages for processing
|
||||
event arrival; |
||||
event customer_in_queue; |
||||
id_busy server; |
||||
|
||||
// Dynamically initialized than not re-scaled
|
||||
event* heap; |
||||
int heap_size = 0; |
||||
|
||||
customers_queue business_q; |
||||
customers_queue tourist_q; |
||||
|
||||
servers_queue business_servers; |
||||
servers_queue tourist_servers; |
||||
|
||||
bool dummy_arrival(const event* arrival); |
||||
int read_next_arrival(FILE* file, event* e); |
||||
void read_back_next_arrival(FILE* file, event* e); |
||||
void read_front_next_arrival(FILE* file, event* e); |
||||
void shiftdown(int i); |
||||
void shiftup(int i); |
||||
void swap(event* i, event* j); |
||||
|
||||
event dequeue_customers(customers_queue* q); |
||||
void enqueue_customers(customers_queue* q, const event* e); |
||||
/* Used for sorting servers by id before printing output
|
||||
* Heap sort is used since we do not need stable sorting as all ids are unique |
||||
* and heap sort sorts in place therefore require less memory than merge sort |
||||
*/ |
||||
void server_shiftdown(servers_queue* heap, int i); |
||||
void server_makeheap(servers_queue* q); |
||||
void server_sort(servers_queue* q); |
||||
void server_swap(id_busy* i, id_busy* j); |
||||
|
||||
id_busy dequeue_servers(servers_queue* q); |
||||
void enqueue_servers(servers_queue* q, const id_busy* s); |
||||
void free_server(servers_queue* q); |
||||
|
||||
int max(int i, int j); |
||||
|
||||
int main(void) |
||||
{ |
||||
printf("Enter file name: "); |
||||
char filename[257]; |
||||
// Assuming filename/file path won't be longer than 256 characters
|
||||
scanf("%256s", filename); |
||||
|
||||
FILE* file = fopen(filename, "r"); |
||||
if (!file) |
||||
{ |
||||
perror(filename); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
|
||||
for (int pass = 1; pass <= 2; pass++) |
||||
{ |
||||
rewind(file); // move file pointer back to beginning
|
||||
|
||||
// Read no. of business and & tourist servers
|
||||
fscanf( |
||||
file, |
||||
"%d %d", |
||||
&business_servers.available, |
||||
&tourist_servers.available); |
||||
|
||||
arrival.id = 0; |
||||
if (read_next_arrival(file, &arrival) == EOF) |
||||
{ |
||||
fprintf(stderr, "Error in reading 1st arrival. Exiting\n"); |
||||
return 1; |
||||
} |
||||
|
||||
// INITIALIZE/RESET VARIABLES
|
||||
heap = malloc( |
||||
sizeof(event) |
||||
* (1 + business_servers.available + tourist_servers.available)); |
||||
|
||||
business_servers.first = 0; |
||||
business_servers.next = 0; |
||||
business_servers.capacity = business_servers.available; |
||||
business_servers.queue = malloc( |
||||
sizeof(event) * business_servers.capacity); |
||||
|
||||
tourist_servers.first = 0; |
||||
tourist_servers.next = 0; |
||||
tourist_servers.capacity = tourist_servers.available; |
||||
tourist_servers.queue = malloc( |
||||
sizeof(event) * tourist_servers.capacity); |
||||
|
||||
if (heap == NULL |
||||
|| business_servers.queue == NULL |
||||
|| tourist_servers.queue == NULL) |
||||
{ |
||||
fprintf( |
||||
stderr, |
||||
"Failed to allocate memory for all data structures\n"); |
||||
return 1; |
||||
} |
||||
|
||||
business_q.first = 0; |
||||
business_q.next = 0; |
||||
business_q.size = 0; |
||||
business_q.capacity = 0; |
||||
// Memory is allocated only if needed
|
||||
business_q.queue = NULL; |
||||
tourist_q.first = 0; |
||||
tourist_q.next = 0; |
||||
tourist_q.size = 0; |
||||
tourist_q.capacity = 0; |
||||
// Memory is allocated only if needed
|
||||
tourist_q.queue = NULL; |
||||
|
||||
for (int i = 0; i < business_servers.capacity; i++) |
||||
{ |
||||
business_servers.queue[i].id = i + 1; |
||||
business_servers.queue[i].busy = 0; |
||||
} |
||||
for (int i = 0; i < tourist_servers.capacity; i++) |
||||
{ |
||||
tourist_servers.queue[i].id = i + business_servers.capacity + 1; |
||||
tourist_servers.queue[i].busy = 0; |
||||
} |
||||
|
||||
heap[heap_size++] = arrival; |
||||
|
||||
// Statistics Variables
|
||||
double time = 0; |
||||
|
||||
int max_q_length = 0; |
||||
|
||||
int no_of_business_customers = 0; |
||||
double business_service_time = 0; |
||||
double business_q_time = 0; |
||||
int max_business_q_length = 0; |
||||
|
||||
int no_of_tourist_customers = 0; |
||||
double tourist_service_time = 0; |
||||
double tourist_q_time = 0; |
||||
int max_tourist_q_length = 0; |
||||
|
||||
// MAIN LOOP
|
||||
while (heap_size > 0) |
||||
{ |
||||
time = heap[0].time; |
||||
if (heap[0].id == 0) // Arrival
|
||||
{ |
||||
if (heap[0].class == TOURIST) |
||||
{ |
||||
no_of_tourist_customers++; |
||||
tourist_service_time += heap[0].duration; |
||||
if (tourist_servers.available) |
||||
{ |
||||
// Time when server will finish serving
|
||||
heap[0].time += heap[0].duration; |
||||
server = dequeue_servers(&tourist_servers); |
||||
heap[0].id = server.id; |
||||
// Total busy time of server
|
||||
heap[0].duration += server.busy; |
||||
shiftdown(0); |
||||
read_back_next_arrival(file, &arrival); |
||||
} |
||||
/* Available/free business servers will serve tourist
|
||||
* customer in 2nd pass if no business customer in q |
||||
* NOTE: free server implies business_q is empty |
||||
*/ |
||||
else if (pass == 2 && business_servers.available) |
||||
{ |
||||
// Time when server will finish serving
|
||||
heap[0].time += heap[0].duration; |
||||
server = dequeue_servers(&business_servers); |
||||
heap[0].id = server.id; |
||||
// Total busy time of server
|
||||
heap[0].duration += server.busy; |
||||
shiftdown(0); |
||||
read_back_next_arrival(file, &arrival); |
||||
} |
||||
// All relevant servers busy, add to tourist customers queue
|
||||
else |
||||
{ |
||||
enqueue_customers(&tourist_q, &heap[0]); |
||||
max_tourist_q_length = max( |
||||
max_tourist_q_length, tourist_q.size); |
||||
max_q_length = max( |
||||
max_q_length, tourist_q.size + business_q.size); |
||||
read_front_next_arrival(file, &arrival); |
||||
} |
||||
} |
||||
else if (heap[0].class == BUSINESS) |
||||
{ |
||||
no_of_business_customers++; |
||||
business_service_time += heap[0].duration; |
||||
if (business_servers.available) |
||||
{ |
||||
// Time when server will finish serving
|
||||
heap[0].time += heap[0].duration; |
||||
server = dequeue_servers(&business_servers); |
||||
heap[0].id = server.id; |
||||
// Total busy time of server
|
||||
heap[0].duration += server.busy; |
||||
shiftdown(0); |
||||
read_back_next_arrival(file, &arrival); |
||||
} |
||||
// All relevant servers busy, add to tourist customers queue
|
||||
else |
||||
{ |
||||
enqueue_customers(&business_q, &heap[0]); |
||||
max_business_q_length = max( |
||||
max_business_q_length, business_q.size); |
||||
max_q_length = max( |
||||
max_q_length, tourist_q.size + business_q.size); |
||||
read_front_next_arrival(file, &arrival); |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
fprintf( |
||||
stderr, |
||||
"Impossible scenario: Event = Arrival but Class = %d", |
||||
heap[0].class); |
||||
exit(1); |
||||
} |
||||
} |
||||
else if ( // Business server finished serving
|
||||
heap[0].id >= 1 && heap[0].id <= business_servers.capacity) |
||||
{ |
||||
if (business_q.size > 0) // Customers waiting in queue
|
||||
{ |
||||
customer_in_queue = dequeue_customers(&business_q); |
||||
business_q_time += time - customer_in_queue.time; |
||||
// Time when server will finish serving
|
||||
heap[0].time += customer_in_queue.duration; |
||||
// Total busy time of server
|
||||
heap[0].duration += customer_in_queue.duration; |
||||
shiftdown(0); |
||||
} |
||||
/* Freed business servers will serve tourist customer
|
||||
* 2nd pass if no business customer in q |
||||
*/ |
||||
else if (pass == 2 && tourist_q.size > 0) |
||||
{ |
||||
customer_in_queue = dequeue_customers(&tourist_q); |
||||
// Time when server will finish serving
|
||||
tourist_q_time += time - customer_in_queue.time; |
||||
heap[0].time += customer_in_queue.duration; |
||||
// Total busy time of server
|
||||
heap[0].duration += customer_in_queue.duration; |
||||
shiftdown(0); |
||||
} |
||||
else // free server at heap[0] and enqueue to business_servers
|
||||
free_server(&business_servers); |
||||
} |
||||
else if ( |
||||
heap[0].id > business_servers.capacity |
||||
&& heap[0].id <= (business_servers.capacity |
||||
+ tourist_servers.capacity)) |
||||
{ |
||||
if (tourist_q.size > 0) // Customers waiting in queue
|
||||
{ |
||||
customer_in_queue = dequeue_customers(&tourist_q); |
||||
// Time when server will finish serving
|
||||
tourist_q_time += time - customer_in_queue.time; |
||||
heap[0].time += customer_in_queue.duration; |
||||
// Total busy time of server
|
||||
heap[0].duration += customer_in_queue.duration; |
||||
shiftdown(0); |
||||
} |
||||
else // free server at heap[0] and enqueue to tourist_servers
|
||||
free_server(&tourist_servers); |
||||
} |
||||
else |
||||
{ |
||||
fprintf( |
||||
stderr, |
||||
"Impossible scenario Heap[0].id = %d is out of range\n", |
||||
heap[0].id); |
||||
exit(1); |
||||
} |
||||
} |
||||
|
||||
// COMPUTE REMAINING STATISTICS FROM TRACKED STATISTICS
|
||||
int total_customers = ( |
||||
no_of_business_customers + no_of_tourist_customers); |
||||
double avg_q_time = ( |
||||
(business_q_time + tourist_q_time) / total_customers); |
||||
double avg_q_length = ((business_q_time + tourist_q_time) / time); |
||||
double avg_service_time = ( |
||||
(business_service_time |
||||
+ business_q_time |
||||
+ tourist_q_time |
||||
+ tourist_service_time) |
||||
/ total_customers); |
||||
|
||||
double avg_business_q_time = ( |
||||
business_q_time / no_of_business_customers); |
||||
double avg_business_q_length = (business_q_time / time); |
||||
double avg_business_service_time = ( |
||||
(business_service_time + business_q_time) |
||||
/ no_of_business_customers); |
||||
|
||||
double avg_tourist_q_time = (tourist_q_time / no_of_tourist_customers); |
||||
double avg_tourist_q_length = (tourist_q_time / time); |
||||
double avg_tourist_service_time = ( |
||||
(tourist_service_time + tourist_q_time) / no_of_tourist_customers); |
||||
|
||||
// SIMULATION OUTPUT/PRINT SIMULATION STATISTICS
|
||||
char pass_title[80]; |
||||
if (pass == 1) |
||||
strncpy( |
||||
pass_title, |
||||
"Pass 1: Business servers exclusively serve business class", |
||||
80); |
||||
else if (pass == 2) |
||||
strncpy( |
||||
pass_title, |
||||
"Pass 2: Idle business servers may serve tourist class", |
||||
80); |
||||
|
||||
printf( |
||||
"%s\n\n" |
||||
"%-50s % 5d\n" |
||||
"%-50s % 8.2lf\n\n" |
||||
"%s\n" |
||||
"%-50s % 8.2lf\n" |
||||
"%-50s % 8.2lf\n" |
||||
"%-50s % 8.2lf\n" |
||||
"%-50s % 5d\n\n" |
||||
"%s\n" |
||||
"%-50s % 8.2lf\n" |
||||
"%-50s % 8.2lf\n" |
||||
"%-50s % 8.2lf\n" |
||||
"%-50s % 5d\n\n" |
||||
"%s\n" |
||||
"%-50s % 8.2lf\n" |
||||
"%-50s % 8.2lf\n" |
||||
"%-50s % 8.2lf\n" |
||||
"%-50s % 5d\n" |
||||
"\n", |
||||
pass_title, |
||||
"Number of people served: ", |
||||
total_customers, |
||||
"Time last service is completed: ", |
||||
time, |
||||
"Business class customers: ", |
||||
"Average total service time: ", |
||||
avg_business_service_time, |
||||
"Average total time in queue: ", |
||||
avg_business_q_time, |
||||
"Ave length of queue: ", |
||||
avg_business_q_length, |
||||
"Maximum number queued: ", |
||||
max_business_q_length, |
||||
"Tourist class customers:", |
||||
"Average total service time: ", |
||||
avg_tourist_service_time, |
||||
"Average total time in queue: ", |
||||
avg_tourist_q_time, |
||||
"Ave length of queue: ", |
||||
avg_tourist_q_length, |
||||
"Maximum number queued: ", |
||||
max_tourist_q_length, |
||||
"All customers:", |
||||
"Average total service time: ", |
||||
avg_service_time, |
||||
"Average total time in queue: ", |
||||
avg_q_time, |
||||
"Ave length of queue: ", |
||||
avg_q_length, |
||||
"Maximum number queued: ", |
||||
max_q_length); |
||||
|
||||
// Sort servers by ID before printing
|
||||
server_sort(&business_servers); |
||||
printf("Business class servers:\n"); |
||||
for (int i = 0; i < business_servers.capacity; i++) |
||||
printf( |
||||
"Total idle time for business class server %3d: %13.2lf\n", |
||||
business_servers.queue[i].id, |
||||
time - business_servers.queue[i].busy); |
||||
|
||||
// Sort servers by ID before printing
|
||||
server_sort(&tourist_servers); |
||||
printf("\nTourist class servers:\n"); |
||||
for (int i = 0; i < tourist_servers.capacity; i++) |
||||
printf( |
||||
"Total idle time for tourist class server %3d: %14.2lf\n", |
||||
tourist_servers.queue[i].id - business_servers.capacity, |
||||
time - tourist_servers.queue[i].busy); |
||||
|
||||
printf("\n\n\n"); |
||||
|
||||
// FREE DYNAMICALLY ALLOCATED MEMORY
|
||||
free(heap); |
||||
free(business_servers.queue); |
||||
free(tourist_servers.queue); |
||||
free(business_q.queue); |
||||
free(tourist_q.queue); |
||||
} |
||||
|
||||
fclose(file); |
||||
return 0; |
||||
} |
||||
|
||||
bool dummy_arrival(const event* arrival) |
||||
{ |
||||
return ( |
||||
arrival->time == 0 && arrival->duration == 0); |
||||
} |
||||
|
||||
int read_next_arrival(FILE* file, event* e) |
||||
{ |
||||
return fscanf(file, "%lf %d %lf", &e->time, &e->class, &e->duration); |
||||
} |
||||
|
||||
void read_back_next_arrival(FILE* file, event* e) |
||||
{ |
||||
// WARNING: Potential BUG: dummy_arrival(e) gets old arrival or new?
|
||||
if (fscanf(file, "%lf %d %lf", &e->time, &e->class, &e->duration) != EOF |
||||
&& dummy_arrival(e) == false) |
||||
{ |
||||
heap[heap_size++] = *e; |
||||
shiftup(heap_size - 1); |
||||
} |
||||
} |
||||
|
||||
void read_front_next_arrival(FILE* file, event* e) |
||||
{ |
||||
if (fscanf(file, "%lf %d %lf", &e->time, &e->class, &e->duration) != EOF |
||||
&& dummy_arrival(e) == false) |
||||
{ |
||||
heap[0] = *e; |
||||
} |
||||
else |
||||
{ // Since dummy arrival or EOF reached, pop heap[0]
|
||||
swap(&heap[0], &heap[--heap_size]); |
||||
} |
||||
shiftdown(0); |
||||
} |
||||
|
||||
void shiftdown(int i) |
||||
{ |
||||
int child = (i * 2) + 1; // left child
|
||||
if (child < heap_size) // has at least one child
|
||||
{ |
||||
if (child < heap_size - 1) // has both children
|
||||
{ |
||||
// if right child smaller
|
||||
if (heap[child].time > heap[child + 1].time) |
||||
child++; // pick right child
|
||||
} |
||||
if (heap[i].time > heap[child].time) |
||||
{ |
||||
swap(&heap[i], &heap[child]); |
||||
shiftdown(child); |
||||
} |
||||
} |
||||
} |
||||
|
||||
void shiftup(int i) |
||||
{ |
||||
if (i == 0) |
||||
return; |
||||
int parent = (i - 1) / 2; |
||||
if (heap[parent].time > heap[i].time) |
||||
{ |
||||
swap(&heap[parent], &heap[i]); |
||||
shiftup(parent); |
||||
} |
||||
} |
||||
|
||||
void swap(event* i, event* j) |
||||
{ |
||||
event tmp = *i; |
||||
*i = *j; |
||||
*j = tmp; |
||||
} |
||||
|
||||
event dequeue_customers(customers_queue* q) |
||||
{ |
||||
if (q->size-- == 0) |
||||
{ |
||||
fprintf( |
||||
stderr, |
||||
"Impossible scenario: dequeue_customers when queue empty"); |
||||
exit(1); |
||||
} |
||||
event customer = q->queue[q->first++]; |
||||
q->first %= q->capacity; |
||||
if (q->size < q->capacity / 4) |
||||
{ |
||||
int new_capacity = (q->capacity / 2) + (q->capacity % 2); |
||||
if (q->size != 0 |
||||
&& (q->first >= new_capacity || q->next >= new_capacity)) |
||||
{ |
||||
/* Original queue:
|
||||
* XX--------|-------XXX |
||||
* OR |
||||
* --------XX|XXX------- |
||||
* OR |
||||
* -----------|-XXXXX---- |
||||
* Where X has some number, - is empty place & | is new_capacity |
||||
* Than, copy queue to next location and free old space |
||||
*/ |
||||
event* new_q = malloc(sizeof(event) * new_capacity); |
||||
if (new_q == NULL) |
||||
{ |
||||
fprintf( |
||||
stderr, |
||||
"Failed to reallocate memory for customer_queue\n"); |
||||
exit(1); |
||||
} |
||||
int j = 0; |
||||
for (int i = q->first; i != q->next; i = (i + 1) % q->capacity) |
||||
{ |
||||
new_q[j++] = q->queue[i]; |
||||
} |
||||
free(q->queue); |
||||
q->queue = new_q; |
||||
q->first = 0; |
||||
q->next = j; |
||||
} |
||||
else |
||||
{ |
||||
q->queue = realloc(q->queue, sizeof(event) * new_capacity); |
||||
if (q->queue == NULL) // Probably unnecessary since shrinking
|
||||
{ |
||||
fprintf( |
||||
stderr, "Failed to reallocate memory for customer_queue\n"); |
||||
exit(1); |
||||
} |
||||
if (q->size == 0) |
||||
{ |
||||
q->first = 0; |
||||
q->next = 0; |
||||
} |
||||
} |
||||
q->capacity = new_capacity; |
||||
} |
||||
return customer; |
||||
} |
||||
|
||||
void enqueue_customers(customers_queue* q, const event* e) |
||||
{ |
||||
if (q->size == q->capacity) // Queue full
|
||||
{ |
||||
// Double queue and adjust pointers
|
||||
// max() for when no space allocated previously i.e. capacity == 0
|
||||
int new_capacity = max(q->capacity * 2, 1); |
||||
q->queue = realloc(q->queue, sizeof(event) * new_capacity); |
||||
if (q->queue == NULL) |
||||
{ |
||||
fprintf( |
||||
stderr, "Failed to reallocate memory for customer_queue\n"); |
||||
exit(1); |
||||
} |
||||
if (q->first != 0) |
||||
{ |
||||
/* Original queue:
|
||||
* XXX|XXXXXXX |
||||
* After realloc: |
||||
* XX|XXXXXXXX---------- |
||||
* After this loop: |
||||
* XX----------|XXXXXXXX |
||||
* Where X has some number, - is empty place |
||||
* and | is q->first pointer |
||||
*/ |
||||
for (int i = q->first; i < q->capacity; i++) |
||||
{ |
||||
q->queue[i + q->capacity] = q->queue[i]; |
||||
} |
||||
q->first += q->capacity; |
||||
} |
||||
/// MISSING THIS CORNER CASE WAS CAUSE OF A MAJOR BUG
|
||||
else |
||||
q->next = q->size; |
||||
|
||||
q->capacity = new_capacity; |
||||
} |
||||
q->size++; |
||||
q->queue[q->next++] = *e; |
||||
q->next %= q->capacity; |
||||
} |
||||
|
||||
id_busy dequeue_servers(servers_queue* q) |
||||
{ |
||||
if (q->available-- == 0) |
||||
{ |
||||
fprintf( |
||||
stderr, |
||||
"Impossible scenario: dequeue_servers when queue empty"); |
||||
exit(1); |
||||
} |
||||
server = q->queue[q->first++]; |
||||
q->first %= q->capacity; |
||||
return server; |
||||
} |
||||
|
||||
void enqueue_servers(servers_queue* q, const id_busy* s) |
||||
{ |
||||
if (q->available++ == q->capacity) |
||||
{ |
||||
fprintf( |
||||
stderr, "Impossible scenario: enqueue_servers when queue full"); |
||||
exit(1); |
||||
} |
||||
q->queue[q->next++] = *s; |
||||
q->next %= q->capacity; |
||||
} |
||||
|
||||
void free_server(servers_queue* q) |
||||
{ |
||||
server.id = heap[0].id; |
||||
server.busy = heap[0].duration; |
||||
enqueue_servers(q, &server); |
||||
heap[0] = heap[--heap_size]; |
||||
shiftdown(0); |
||||
} |
||||
|
||||
int max(int i, int j) |
||||
{ |
||||
return (i > j) ? i : j; |
||||
} |
||||
|
||||
void server_shiftdown(servers_queue* heap, int i) |
||||
{ |
||||
int child = (i * 2) + 1; // left child
|
||||
if (child < heap->available) // has at least one child
|
||||
{ |
||||
if (child < heap->available - 1) // has both children
|
||||
{ |
||||
// if right child smaller
|
||||
if (heap->queue[child].id < heap->queue[child + 1].id) |
||||
child++; // pick right child
|
||||
} |
||||
if (heap->queue[i].id < heap->queue[child].id) |
||||
{ |
||||
server_swap(&heap->queue[child], &heap->queue[i]); |
||||
server_shiftdown(heap, child); |
||||
} |
||||
} |
||||
} |
||||
|
||||
void server_makeheap(servers_queue* q) |
||||
{ |
||||
// Shiftdown Method
|
||||
int shiftdowns_required = (q->capacity / 2)-1; |
||||
for (int i = shiftdowns_required; i >= 0; i--) |
||||
{ |
||||
server_shiftdown(q, i); |
||||
} |
||||
} |
||||
|
||||
void server_sort(servers_queue* q) |
||||
{ |
||||
server_makeheap(q); |
||||
while(q->available > 0) |
||||
{ |
||||
server_swap(q->queue, &q->queue[--q->available]); |
||||
server_shiftdown(q, 0); |
||||
} |
||||
q->available = q->capacity; |
||||
} |
||||
|
||||
void server_swap(id_busy* i, id_busy* j) |
||||
{ |
||||
id_busy tmp = *i; |
||||
*i = *j; |
||||
*j = tmp; |
||||
} |
Loading…
Reference in new issue