source: lib/data-struct/vector.c @ ead9478

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivelibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since ead9478 was ead9478, checked in by Richard Sanger <rsangerarj@…>, 7 years ago

Use size_t rather than int for the data structures. Export vector, deque and ring_buffer for testing and use in programs.
Remove some inlines for now since these result in lots of compile warnings when also exported, the compiler is probably smart enough anyway.

  • Property mode set to 100644
File size: 3.6 KB
Line 
1#include "vector.h"
2
3#include <stdlib.h>
4#include <string.h>
5#include <assert.h>
6
7DLLEXPORT void libtrace_vector_init(libtrace_vector_t *v, size_t element_size) {
8        v->element_size = element_size;
9        v->size = 0; // Starts empty
10        v->max_size = 128; // Pick a largish size to begin with
11        v->elements = malloc(v->max_size * v->element_size);
12        assert(pthread_mutex_init(&v->lock, NULL) == 0);
13}
14
15DLLEXPORT void libtrace_vector_destroy(libtrace_vector_t *v) {
16        assert(pthread_mutex_destroy(&v->lock) == 0);
17        free(v->elements);
18        // Be safe make sure we wont work any more
19        v->elements = NULL;
20        v->size = 0;
21        v->max_size = 0;
22        v->element_size = 0;
23}
24
25DLLEXPORT void libtrace_vector_push_back(libtrace_vector_t *v, void *d) {
26        assert(pthread_mutex_lock(&v->lock) == 0);
27        if (v->size >= v->max_size) {
28                /* Resize */
29                v->max_size *= 2;
30                v->elements = realloc(v->elements, v->max_size * v->element_size);
31                assert(v->elements);
32        }
33        memcpy(&v->elements[v->size*v->element_size], d, v->element_size);
34        v->size++;
35        assert(pthread_mutex_unlock(&v->lock) == 0);
36}
37
38DLLEXPORT size_t libtrace_vector_get_size(libtrace_vector_t *v) {
39        return v->size;
40}
41
42DLLEXPORT int libtrace_vector_get(libtrace_vector_t *v, size_t location, void *d) {
43        assert(pthread_mutex_lock(&v->lock) == 0);
44        if (location >= v->size) {
45                assert(pthread_mutex_unlock(&v->lock) == 0);
46                return 0;
47        }
48        memcpy(d, &v->elements[location*v->element_size], v->element_size);
49        assert(pthread_mutex_unlock(&v->lock) == 0);
50        return 1;
51}
52
53DLLEXPORT int libtrace_vector_remove_front(libtrace_vector_t *v) {
54        size_t i;
55        assert(pthread_mutex_lock(&v->lock) == 0);
56        if (!v->size) {
57                assert(pthread_mutex_unlock(&v->lock) == 0);
58                return 0;
59        }
60        v->size--;
61        // Of coarse this is mega slow
62        for (i = 0; i < v->size * v->element_size; i++)
63                v->elements[i] = v->elements[i+v->element_size];
64        assert(pthread_mutex_unlock(&v->lock) == 0);
65        return 1;
66}
67
68static inline void memswap(void *a, void *b, size_t size) {
69        char c;
70        size_t i;
71        for (i=0; i<size; i++) {
72                c = ((char *)a)[i];
73                ((char *)a)[i] = ((char *)b)[i];
74                ((char *)b)[i] = c;
75        }
76}
77// Note elements must be the same size
78// This also empties the second source array
79DLLEXPORT void libtrace_vector_append(libtrace_vector_t *dest, libtrace_vector_t *src)
80{
81        assert(dest->element_size == src->element_size);
82        if (src->size == 0) // Nothing to do if this is the case
83                return;
84        assert(pthread_mutex_lock(&dest->lock) == 0);
85        assert(pthread_mutex_lock(&src->lock) == 0);
86        if (src->size == 0) // Double check now we've got the locks - Nothing to do if this is the case
87                goto unlock;
88        if (dest->size == 0) {
89                memswap(&dest->max_size, &src->max_size, sizeof(src->max_size));
90                memswap(&dest->size, &src->size, sizeof(src->size));
91                memswap(&dest->element_size, &src->element_size, sizeof(src->element_size));
92                memswap(&dest->elements, &src->elements, sizeof(src->elements));
93        } else {
94                size_t oldmax = dest->max_size;
95                while (dest->max_size - dest->size < src->size) dest->max_size *= 2;
96                if (oldmax != dest->max_size)
97                        dest->elements = realloc(dest->elements, dest->max_size * dest->element_size);
98                // Now do the move
99                memcpy(&dest->elements[dest->element_size * dest->size], src->elements, src->element_size * src->size);
100                // Update the dest size
101                dest->size += src->size;
102                // Wipe the src
103                src->size = 0;
104        }
105unlock:
106        assert(pthread_mutex_unlock(&src->lock) == 0);
107        assert(pthread_mutex_unlock(&dest->lock) == 0);
108}
109
110DLLEXPORT void libtrace_zero_vector(libtrace_vector_t *v)
111{
112        v->max_size = 0;
113        v->size = 0;
114        v->element_size = 0;
115        v->elements = NULL;     
116}
117
118DLLEXPORT void libtrace_vector_empty(libtrace_vector_t *v) {
119        assert(pthread_mutex_lock(&v->lock) == 0);
120        v->size = 0;
121        assert(pthread_mutex_unlock(&v->lock) == 0);
122}
Note: See TracBrowser for help on using the repository browser.