-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconveyor.c
152 lines (128 loc) · 3.23 KB
/
conveyor.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "conveyor.h"
static struct conveyor_object *dequeue( struct conveyor_queue *q )
{
struct conveyor_object *obj;
if (q->n == 0)
return NULL;
obj = &q->queue[q->tail];
q->total_value -= obj->value;
q->n--;
q->tail = (q->tail + 1) % q->max;
return obj;
}
static void enqueue( struct conveyor_queue *q, double value, double limit )
{
if (q->n == q->max)
{
fprintf(stderr, "conveyor enqueue: attempting to enqueue (max %d) on a full queue!\n", q->max);
exit(1);
}
q->total_value += value;
q->queue[q->head].value = value;
q->queue[q->head].limit = limit;
q->n++;
q->head = (q->head + 1) % q->max;
}
static struct conveyor_object *queue_peek( struct conveyor_queue *q )
{
if ( q->n == 0 )
return NULL;
return &q->queue[q->tail];
}
/* Initialize the conveyor. Make sure that size allows for enough space.
At least ((1 / td) * conv_time) * add_influx_per_td */
void initialize_conveyor( struct conveyor *conv, double conv_time, double outflux_rate, int size)
{
/* Initialize struct conveyor */
conv->time = 0.0;
conv->conv_time = conv_time;
conv->outflux_rate = outflux_rate;
conv->queue = malloc( sizeof(struct conveyor_queue) );
if (!conv->queue)
{
fprintf(stderr, "malloc failed\n");
exit(1);
}
/* Initialize struct conveyor_queue */
conv->queue->total_value = 0.0;
conv->queue->head = 0;
conv->queue->tail = 0;
conv->queue->n = 0;
conv->queue->max = size;
conv->queue->queue = malloc(sizeof(struct conveyor_object) * size);
if (!conv->queue->queue)
{
fprintf(stderr, "malloc failed\n");
exit(1);
}
}
void update_conveyor( struct conveyor *conv, double td )
{
int i, n;
struct conveyor_object *obj;
struct conveyor_queue *q;
double outflux;
/* Update outflux for each item */
q = conv->queue;
i = q->tail;
n = q->n;
while (n)
{
obj = &q->queue[i];
outflux = obj->value * ((conv->outflux_rate * OUTFLUX_CORRECTION_FACTOR) * td);
obj->value = obj->value - outflux;
q->total_value -= outflux;
n--;
i = (i + 1) % q->max;
}
/* Update conveyor time */
conv->time += td;
}
double conveyor_get_outflux( struct conveyor *conv )
{
struct conveyor_object *obj;
double ret = 0.0;
while ((obj = queue_peek(conv->queue)) != NULL)
{
/* Oldest object is not yet done */
if (obj->limit > conv->time)
break;
/* Dequeue and add the value to the return value */
obj = dequeue(conv->queue);
ret += obj->value;
}
/* Return object value plus any other conveyor objects ready to be released */
return ret;
}
void conveyor_add_influx( double value, struct conveyor *conv )
{
enqueue(conv->queue, value, conv->time + conv->conv_time);
}
double conveyor_get_population( struct conveyor *conv )
{
return conv->queue->total_value;
}
/*
double conveyor_get_population_analytic( struct conveyor *conv )
{
int i, n;
struct conveyor_object *obj;
struct conveyor_queue *q;
double total = 0.0, t;
q = conv->queue;
i = q->tail;
n = q->n;
while (n)
{
obj = &q->queue[i];
t = conv->time - obj->time_start;
total += obj->value * pow(M_E, (conv->outflux_rate * t));
n--;
i = (i + 1) % q->max;
}
return total;
}
*/