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

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

Move the data structures out of the way and into there own folder and tidy file naming.

  • 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 inline void libtrace_vector_init(libtrace_vector_t *v, int 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 inline 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 inline 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 inline int libtrace_vector_get_size(libtrace_vector_t *v) {
39        return v->size;
40}
41
42DLLEXPORT inline int libtrace_vector_get(libtrace_vector_t *v, int 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 inline int libtrace_vector_remove_front(libtrace_vector_t *v) {
54        int 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, int size) {
69        char c;
70        int 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
78DLLEXPORT inline void libtrace_vector_append(libtrace_vector_t *dest, libtrace_vector_t *src)
79{
80        assert(dest->element_size == src->element_size);
81        if (src->size == 0) // Nothing to do if this is the case
82                return;
83        assert(pthread_mutex_lock(&dest->lock) == 0);
84        assert(pthread_mutex_lock(&src->lock) == 0);
85        if (src->size == 0) // Double check now we've got the locks - Nothing to do if this is the case
86                goto unlock;
87        if (dest->size == 0) {
88                memswap(&dest->max_size, &src->max_size, sizeof(src->max_size));
89                memswap(&dest->size, &src->size, sizeof(src->size));
90                memswap(&dest->element_size, &src->element_size, sizeof(src->element_size));
91                memswap(&dest->elements, &src->elements, sizeof(src->elements));
92        } else {
93                int oldmax = dest->max_size;
94                while (dest->max_size - dest->size < src->size) dest->max_size *= 2;
95                if (oldmax != dest->max_size)
96                        dest->elements = realloc(dest->elements, dest->max_size * dest->element_size);
97                // Now do the move
98                memcpy(&dest->elements[dest->element_size * dest->size], src->elements, src->element_size * src->size);
99                // Update the dest size
100                dest->size += src->size;
101                // Wipe the src
102                src->size = 0;
103        }
104unlock:
105        assert(pthread_mutex_unlock(&src->lock) == 0);
106        assert(pthread_mutex_unlock(&dest->lock) == 0);
107}
108
109DLLEXPORT inline void libtrace_zero_vector(libtrace_vector_t *v)
110{
111        v->max_size = 0;
112        v->size = 0;
113        v->element_size = 0;
114        v->elements = NULL;     
115}
116
117DLLEXPORT inline void libtrace_vector_empty(libtrace_vector_t *v) {
118        assert(pthread_mutex_lock(&v->lock) == 0);
119        v->size = 0;
120        assert(pthread_mutex_unlock(&v->lock) == 0);
121}
Note: See TracBrowser for help on using the repository browser.