aboutsummaryrefslogtreecommitdiff
path: root/deque.c
diff options
context:
space:
mode:
Diffstat (limited to 'deque.c')
-rw-r--r--deque.c102
1 files changed, 51 insertions, 51 deletions
diff --git a/deque.c b/deque.c
index 070040b..eab623b 100644
--- a/deque.c
+++ b/deque.c
@@ -12,28 +12,28 @@ typedef int T;
12struct deque { 12struct deque {
13 T **map; 13 T **map;
14 14
15 size_t first_chunk; 15 size_t map_begin;
16 size_t last_chunk; 16 size_t map_end;
17 size_t map_capacity;
17 18
18 size_t start; 19 size_t offset;
19 size_t size; 20 size_t size;
20 size_t capacity;
21}; 21};
22 22
23void 23void
24deque_init(struct deque *d) 24deque_init(struct deque *d)
25{ 25{
26 d->first_chunk = 0; 26 d->map_begin = 0;
27 d->last_chunk = 0; 27 d->map_end = 0;
28 d->start = 0; 28 d->offset = 0;
29 d->size = 0; 29 d->size = 0;
30 30
31 // TODO: Error handling 31 // TODO: Error handling
32 d->map = calloc(START_MAP_CAPACITY, sizeof *d->map); 32 d->map = calloc(START_MAP_CAPACITY, sizeof *d->map);
33 if ( d->map != NULL ) { 33 if ( d->map != NULL ) {
34 d->capacity = START_MAP_CAPACITY; 34 d->map_capacity = START_MAP_CAPACITY;
35 35
36 for ( size_t i = 0; i != d->capacity; ++i ) { 36 for ( size_t i = 0; i != d->map_capacity; ++i ) {
37 d->map[i] = NULL; 37 d->map[i] = NULL;
38 } 38 }
39 } 39 }
@@ -43,7 +43,7 @@ void
43deque_free(struct deque *d) 43deque_free(struct deque *d)
44{ 44{
45 // free all chunks 45 // free all chunks
46 for ( size_t i = 0; i != d->capacity; ++i ) { 46 for ( size_t i = 0; i != d->map_capacity; ++i ) {
47 free(d->map[i]); 47 free(d->map[i]);
48 } 48 }
49 49
@@ -54,13 +54,13 @@ deque_free(struct deque *d)
54static void 54static void
55grow_map(struct deque *d) 55grow_map(struct deque *d)
56{ 56{
57 const size_t capacity = d->capacity + d->capacity / 2; 57 const size_t capacity = d->map_capacity + d->map_capacity / 2;
58 T ** map = calloc(capacity, sizeof *map); 58 T ** map = calloc(map_capacity, sizeof *map);
59 59
60 // copy elements 60 // copy elements
61 size_t i; 61 size_t i;
62 for ( i = 0; i != d->capacity; ++i ) { 62 for ( i = 0; i != d->map_capacity; ++i ) {
63 map[i] = d->map[(i + d->first_chunk) % d->capacity]; 63 map[i] = d->map[(i + d->map_begin) % d->map_capacity];
64 } 64 }
65 65
66 // initialize the rest (new) elements with NULL 66 // initialize the rest (new) elements with NULL
@@ -73,77 +73,77 @@ grow_map(struct deque *d)
73 d->map = map; 73 d->map = map;
74 74
75 // adjust pointers 75 // adjust pointers
76 d->first_chunk = 0; 76 d->map_begin = 0;
77 d->last_chunk = d->capacity - 1; 77 d->map_end = d->map_capacity - 1;
78 78
79 // set new capacity 79 // set new map_capacity
80 d->capacity = capacity; 80 d->map_capacity = capacity;
81} 81}
82 82
83static void 83static void
84map_append_chunk(struct deque *d) 84map_append_chunk(struct deque *d)
85{ 85{
86 size_t next = (d->last_chunk + 1) % d->capacity; 86 size_t next = (d->map_end + 1) % d->map_capacity;
87 87
88 if ( next == d->first_chunk ) { // Resize the map 88 if ( next == d->map_begin ) { // Resize the map
89 grow_map(d); 89 grow_map(d);
90 90
91 next = d->last_chunk + 1; 91 next = d->map_end + 1;
92 } 92 }
93 93
94 d->map[d->last_chunk] = calloc(CHUNK_CAPACITY, sizeof **d->map); 94 d->map[d->map_end] = calloc(CHUNK_CAPACITY, sizeof **d->map);
95 d->last_chunk = next; 95 d->map_end = next;
96} 96}
97 97
98static void 98static void
99map_prepend_chunk(struct deque *d) 99map_prepend_chunk(struct deque *d)
100{ 100{
101 size_t prev = (d->first_chunk + d->capacity - 1) % d->capacity; 101 size_t prev = (d->map_begin + d->map_capacity - 1) % d->map_capacity;
102 102
103 if ( prev == d->last_chunk ) { 103 if ( prev == d->map_end ) {
104 grow_map(d); 104 grow_map(d);
105 105
106 prev = d->capacity - 1; 106 prev = d->map_capacity - 1;
107 } 107 }
108 108
109 d->map[prev] = calloc(CHUNK_CAPACITY, sizeof **d->map); 109 d->map[prev] = calloc(CHUNK_CAPACITY, sizeof **d->map);
110 d->first_chunk = prev; 110 d->map_begin = prev;
111} 111}
112 112
113static void 113static void
114map_remove_front_chunk(struct deque *d) 114map_remove_front_chunk(struct deque *d)
115{ 115{
116 if ( d->first_chunk == d->last_chunk ) 116 if ( d->map_begin == d->map_end )
117 return; 117 return;
118 118
119 const size_t next = (d->first_chunk + 1) % d->capacity; 119 const size_t next = (d->map_begin + 1) % d->map_capacity;
120 120
121 free(d->map[d->first_chunk]); 121 free(d->map[d->map_begin]);
122 d->map[d->first_chunk] = NULL; 122 d->map[d->map_begin] = NULL;
123 123
124 d->first_chunk = next; 124 d->map_begin = next;
125} 125}
126 126
127static void 127static void
128map_remove_tail_chunk(struct deque *d) 128map_remove_tail_chunk(struct deque *d)
129{ 129{
130 if ( d->first_chunk == d->last_chunk ) 130 if ( d->map_begin == d->map_end )
131 return; 131 return;
132 132
133 const size_t prev = (d->last_chunk + d->capacity - 1) % d->capacity; 133 const size_t prev = (d->map_end + d->map_capacity - 1) % d->map_capacity;
134 134
135 free(d->map[prev]); 135 free(d->map[prev]);
136 d->map[prev] = NULL; 136 d->map[prev] = NULL;
137 137
138 d->last_chunk = prev; 138 d->map_end = prev;
139} 139}
140 140
141void 141void
142deque_get_at(struct deque *d, size_t idx, T *data) 142deque_get_at(struct deque *d, size_t idx, T *data)
143{ 143{
144 const size_t offset = d->start + idx; 144 const size_t offset = d->offset + idx;
145 const size_t chunk_off = offset % CHUNK_CAPACITY; 145 const size_t chunk_off = offset % CHUNK_CAPACITY;
146 const size_t chunk_num = ((offset / CHUNK_CAPACITY) + d->first_chunk) % d->capacity; 146 const size_t chunk_num = ((offset / CHUNK_CAPACITY) + d->map_begin) % d->map_capacity;
147 147
148 *data = d->map[chunk_num][chunk_off]; 148 *data = d->map[chunk_num][chunk_off];
149} 149}
@@ -151,13 +151,13 @@ deque_get_at(struct deque *d, size_t idx, T *data)
151void 151void
152deque_push_back(struct deque *d, T data) 152deque_push_back(struct deque *d, T data)
153{ 153{
154 const size_t offset = d->start + d->size; 154 const size_t offset = d->offset + d->size;
155 const size_t chunk_off = offset % CHUNK_CAPACITY; 155 const size_t chunk_off = offset % CHUNK_CAPACITY;
156 size_t chunk_num = ((offset / CHUNK_CAPACITY) + d->first_chunk) % d->capacity; 156 size_t chunk_num = ((offset / CHUNK_CAPACITY) + d->map_begin) % d->map_capacity;
157 157
158 if ( chunk_num == d->last_chunk ) { 158 if ( chunk_num == d->map_end ) {
159 map_append_chunk(d); 159 map_append_chunk(d);
160 chunk_num = ((offset / CHUNK_CAPACITY) + d->first_chunk) % d->capacity; 160 chunk_num = ((offset / CHUNK_CAPACITY) + d->map_begin) % d->map_capacity;
161 } 161 }
162 162
163 d->map[chunk_num][chunk_off] = data; 163 d->map[chunk_num][chunk_off] = data;
@@ -170,17 +170,17 @@ deque_pop_front(struct deque *d, T *data)
170 if ( d->size == 0 ) 170 if ( d->size == 0 )
171 return false; 171 return false;
172 172
173 const size_t chunk_off = d->start % CHUNK_CAPACITY; 173 const size_t chunk_off = d->offset % CHUNK_CAPACITY;
174 const size_t chunk_num = ((d->start / CHUNK_CAPACITY) + d->first_chunk) % d->capacity; 174 const size_t chunk_num = ((d->offset / CHUNK_CAPACITY) + d->map_begin) % d->map_capacity;
175 175
176 *data = d->map[chunk_num][chunk_off]; 176 *data = d->map[chunk_num][chunk_off];
177 177
178 --d->size; 178 --d->size;
179 ++d->start; 179 ++d->offset;
180 180
181 if ( d->size == 0 || d->start == CHUNK_CAPACITY ) { 181 if ( d->size == 0 || d->offset == CHUNK_CAPACITY ) {
182 map_remove_front_chunk(d); 182 map_remove_front_chunk(d);
183 d->start = 0; 183 d->offset = 0;
184 } 184 }
185 185
186 return true; 186 return true;
@@ -189,9 +189,9 @@ deque_pop_front(struct deque *d, T *data)
189static void 189static void
190deque_show(struct deque *d) 190deque_show(struct deque *d)
191{ 191{
192 printf("first: %zu -- last: %zu -- size: %zu -- capacity: %zu -- start: %zu\n", 192 printf("first: %zu -- last: %zu -- size: %zu -- map_capacity: %zu -- offset: %zu\n",
193 d->first_chunk, d->last_chunk, d->size, d->capacity, d->start); 193 d->map_begin, d->map_end, d->size, d->map_capacity, d->offset);
194 for ( size_t i = 0; i != d->capacity; ++i ) { 194 for ( size_t i = 0; i != d->map_capacity; ++i ) {
195 printf("%zu(%p) ", i, (void *) d->map[i]); 195 printf("%zu(%p) ", i, (void *) d->map[i]);
196 } 196 }
197 puts(""); 197 puts("");