Skip to content

Commit 0b10f3a

Browse files
committed
Extension to Vector API.
Signed-off-by: Timothy Rule (VM/EMT3) <[email protected]>
1 parent b6012fa commit 0b10f3a

File tree

2 files changed

+80
-37
lines changed

2 files changed

+80
-37
lines changed

dse/clib/collections/vector.h

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ typedef struct Vector {
2323
VectorCompar compar;
2424
} vtable;
2525
size_t capacity;
26+
size_t initial_capacity;
2627
size_t length;
2728
size_t item_size;
2829
void* items;
@@ -35,6 +36,7 @@ static __inline__ int __vector_resize(Vector* v, size_t hint)
3536
free(v->items);
3637
v->items = NULL;
3738
v->capacity = 0;
39+
v->length = 0;
3840
} else if (hint > v->length) {
3941
if (v->items == NULL) {
4042
v->items = calloc(hint, v->item_size);
@@ -58,6 +60,7 @@ static __inline__ Vector vector_make(
5860
Vector v = {
5961
.item_size = item_size,
6062
.capacity = capacity ? capacity : VECTOR_DEFAULT_CAPACITY,
63+
.initial_capacity = capacity ? capacity : VECTOR_DEFAULT_CAPACITY,
6164
.vtable.compar = compar_func,
6265
};
6366
__vector_resize(&v, v.capacity);
@@ -72,7 +75,11 @@ static __inline__ size_t vector_len(Vector* v)
7275
static __inline__ int vector_push(Vector* v, void* item)
7376
{
7477
if (v == NULL) return -EINVAL;
75-
if (v->length == v->capacity) __vector_resize(v, v->capacity * 2);
78+
if (v->capacity == 0) {
79+
__vector_resize(v, v->initial_capacity);
80+
} else if (v->length == v->capacity) {
81+
__vector_resize(v, v->capacity * 2);
82+
}
7683
v->length += 1;
7784
if (item) {
7885
size_t offset = (v->length - 1) * v->item_size;
@@ -125,24 +132,24 @@ static __inline__ int vector_sort(Vector* v)
125132
return 0;
126133
}
127134

128-
static __inline__ int vector_find(
135+
static __inline__ void* vector_find(
129136
Vector* v, void* key, size_t start, void* item)
130137
{
131-
if (v == NULL) return -EINVAL;
132-
if (key == NULL) return -EINVAL;
133-
if (v->length == 0 || v->items == NULL) return -ENODATA;
134-
if (v->vtable.compar == NULL) return -EINVAL;
135-
if (start >= v->length) return -EINVAL;
138+
if (v == NULL) return NULL;
139+
if (key == NULL) return NULL;
140+
if (v->length == 0 || v->items == NULL) return NULL;
141+
if (v->vtable.compar == NULL) return NULL;
142+
if (start >= v->length) return NULL;
136143
size_t offset = start * v->item_size;
137144
void* result = bsearch(key, v->items + offset, v->length - start,
138145
v->item_size, v->vtable.compar);
139146
if (result) {
140147
if (item) {
141148
memcpy(item, result, v->item_size);
142149
}
143-
return 0;
150+
return result;
144151
} else {
145-
return 1;
152+
return NULL;
146153
}
147154
}
148155

@@ -168,10 +175,18 @@ static __inline__ int vector_range(Vector* v, void* from_key, void* to_key,
168175
return 0;
169176
}
170177

171-
static __inline__ void vector_clear(Vector* v, size_t capacity)
178+
static __inline__ void vector_clear(Vector* v)
179+
{
180+
if (v == NULL) return;
181+
if (v->items == NULL) return;
182+
memset(v->items, 0, v->capacity * v->item_size);
183+
v->length = 0;
184+
}
185+
186+
static __inline__ void vector_reset(Vector* v)
172187
{
173188
if (v == NULL) return;
174-
__vector_resize(v, capacity);
189+
__vector_resize(v, 0);
175190
}
176191

177192

tests/collections/test_vector.c

Lines changed: 54 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#include <dse/clib/collections/vector.h>
99

1010

11-
#define UNUSED(x) ((void)x)
11+
#define UNUSED(x) ((void)x)
1212

1313

1414
static int test_setup(void** state)
@@ -51,16 +51,17 @@ void test_vector__make_clear(void** state)
5151
assert_null(vector_at(NULL, 0, NULL));
5252
assert_int_equal(-EINVAL, vector_delete_at(NULL, 0));
5353
assert_int_equal(-EINVAL, vector_sort(NULL));
54-
assert_int_equal(-EINVAL, vector_find(NULL, NULL, 0, NULL));
54+
assert_null(vector_find(NULL, NULL, 0, NULL));
5555
assert_int_equal(-EINVAL, vector_range(NULL, NULL, NULL, NULL, NULL));
56-
vector_clear(NULL, 0);
56+
vector_clear(NULL);
57+
vector_reset(NULL);
5758

5859
// Make default capacity.
5960
v = vector_make(sizeof(VectorItem), 0, NULL);
6061
assert_int_equal(v.capacity, 64);
6162
assert_int_equal(v.item_size, sizeof(VectorItem));
6263
assert_non_null(v.items);
63-
vector_clear(&v, 0);
64+
vector_reset(&v);
6465
assert_int_equal(v.capacity, 0);
6566
assert_null(v.items);
6667

@@ -69,7 +70,7 @@ void test_vector__make_clear(void** state)
6970
assert_int_equal(v.capacity, 4);
7071
assert_int_equal(v.item_size, sizeof(VectorItem));
7172
assert_non_null(v.items);
72-
vector_clear(&v, 0);
73+
vector_reset(&v);
7374
assert_int_equal(v.capacity, 0);
7475
assert_null(v.items);
7576

@@ -81,13 +82,14 @@ void test_vector__make_clear(void** state)
8182
assert_int_equal(v.capacity, 0);
8283
assert_int_equal(v.item_size, sizeof(VectorItem));
8384
assert_null(v.items);
84-
vector_clear(&v, 4);
85-
assert_int_equal(v.capacity, 4);
86-
assert_non_null(v.items);
87-
vector_clear(&v, 2);
88-
assert_int_equal(v.capacity, 2);
89-
assert_non_null(v.items);
90-
vector_clear(&v, 0);
85+
vector_clear(&v);
86+
assert_int_equal(v.capacity, 0);
87+
assert_int_equal(v.length, 0);
88+
assert_null(v.items);
89+
vector_reset(&v);
90+
assert_int_equal(v.capacity, 0);
91+
assert_int_equal(v.length, 0);
92+
assert_null(v.items);
9193
}
9294

9395
void test_vector__push_pop(void** state)
@@ -121,7 +123,8 @@ void test_vector__push_pop(void** state)
121123
assert_int_equal(1, vi.key); // Previous value, check returns!.
122124
assert_int_equal(0, vector_len(&v));
123125
assert_int_equal(4, v.capacity);
124-
vector_clear(&v, 0);
126+
vector_reset(&v);
127+
125128

126129
// NULL items.
127130
v = vector_make(sizeof(VectorItem), 2, NULL);
@@ -132,7 +135,30 @@ void test_vector__push_pop(void** state)
132135
assert_int_equal(0, vector_pop(&v, NULL));
133136
assert_int_equal(0, vector_len(&v));
134137
assert_int_equal(2, v.capacity);
135-
vector_clear(&v, 0);
138+
vector_reset(&v);
139+
140+
141+
// PUSH and clear/reset.
142+
v = vector_make(sizeof(VectorItem), 2, NULL);
143+
assert_int_equal(2, v.capacity);
144+
assert_int_equal(0, vector_len(&v));
145+
146+
// PUSH PULL with resize.
147+
assert_int_equal(0, vector_push(&v, &(VectorItem){ .key = 1, .data = 11 }));
148+
assert_int_equal(0, vector_push(&v, &(VectorItem){ .key = 2, .data = 22 }));
149+
assert_int_equal(2, v.capacity);
150+
assert_int_equal(2, vector_len(&v));
151+
vector_clear(&v);
152+
assert_int_equal(2, v.capacity);
153+
assert_int_equal(0, vector_len(&v));
154+
vector_reset(&v);
155+
assert_int_equal(0, v.capacity);
156+
assert_int_equal(0, vector_len(&v));
157+
assert_int_equal(0, vector_push(&v, &(VectorItem){ .key = 1, .data = 11 }));
158+
assert_int_equal(0, vector_push(&v, &(VectorItem){ .key = 2, .data = 22 }));
159+
assert_int_equal(2, v.capacity);
160+
assert_int_equal(2, vector_len(&v));
161+
vector_reset(&v);
136162
}
137163

138164
void test_vector__at(void** state)
@@ -164,7 +190,7 @@ void test_vector__at(void** state)
164190

165191
assert_null(vector_at(&v, 3, NULL));
166192

167-
vector_clear(&v, 0);
193+
vector_reset(&v);
168194
}
169195

170196
void test_vector__sort_find(void** state)
@@ -192,20 +218,22 @@ void test_vector__sort_find(void** state)
192218
assert_null(vector_at(&v, 3, NULL));
193219

194220
// Find.
195-
assert_int_equal(0, vector_find(&v, &(VectorItem){ .key = 1 }, 0, &vi));
221+
assert_non_null(vector_find(&v, &(VectorItem){ .key = 1 }, 0, &vi));
196222
assert_int_equal(1, vi.key);
197-
assert_int_equal(0, vector_find(&v, &(VectorItem){ .key = 2 }, 0, &vi));
223+
VectorItem* vi_p = vector_find(&v, &(VectorItem){ .key = 1 }, 0, NULL);
224+
assert_non_null(vi_p);
225+
assert_int_equal(1, vi_p->key);
226+
assert_non_null(vector_find(&v, &(VectorItem){ .key = 2 }, 0, &vi));
198227
assert_int_equal(2, vi.key);
199-
assert_int_equal(0, vector_find(&v, &(VectorItem){ .key = 3 }, 0, &vi));
228+
assert_non_null(vector_find(&v, &(VectorItem){ .key = 3 }, 0, &vi));
200229
assert_int_equal(3, vi.key);
201-
assert_int_equal(1, vector_find(&v, &(VectorItem){ .key = 4 }, 0, &vi));
230+
assert_null(vector_find(&v, &(VectorItem){ .key = 4 }, 0, &vi));
202231
assert_int_equal(3, vi.key);
203-
assert_int_equal(1, vector_find(&v, &(VectorItem){ .key = 1 }, 1, &vi));
204-
assert_int_equal(1, vector_find(&v, &(VectorItem){ .key = 2 }, 2, &vi));
205-
assert_int_equal(
206-
-EINVAL, vector_find(&v, &(VectorItem){ .key = 3 }, 3, &vi));
232+
assert_null(vector_find(&v, &(VectorItem){ .key = 1 }, 1, &vi));
233+
assert_null(vector_find(&v, &(VectorItem){ .key = 2 }, 2, &vi));
234+
assert_null(vector_find(&v, &(VectorItem){ .key = 3 }, 3, &vi));
207235

208-
vector_clear(&v, 0);
236+
vector_reset(&v);
209237
}
210238

211239
int RangeCallback(void* item, void* data)
@@ -271,7 +299,7 @@ void test_vector__range(void** state)
271299
&(VectorItem){ .key = 3 }, RangeCallbackv22, &range_counter));
272300
assert_int_equal(0, range_counter);
273301

274-
vector_clear(&v, 0);
302+
vector_reset(&v);
275303
}
276304

277305
void test_vector__delete_at(void** state)
@@ -307,7 +335,7 @@ void test_vector__delete_at(void** state)
307335
assert_int_equal(-ENODATA, vector_delete_at(&v, 0));
308336
assert_int_equal(0, vector_len(&v));
309337

310-
vector_clear(&v, 0);
338+
vector_reset(&v);
311339
}
312340

313341

0 commit comments

Comments
 (0)