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

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivendag_formatrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since ee6e802 was ee6e802, checked in by Shane Alcock <salcock@…>, 4 years ago

Updated copyright blurb on all source files

In some cases, this meant adding copyright blurbs to files that
had never had them before.

  • Property mode set to 100644
File size: 5.2 KB
Line 
1/*
2 *
3 * Copyright (c) 2007-2016 The University of Waikato, Hamilton, New Zealand.
4 * All rights reserved.
5 *
6 * This file is part of libtrace.
7 *
8 * This code has been developed by the University of Waikato WAND
9 * research group. For further information please see http://www.wand.net.nz/
10 *
11 * libtrace is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation; either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * libtrace is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 * GNU Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public License
22 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 *
24 *
25 */
26#include "vector.h"
27
28#include <stdlib.h>
29#include <string.h>
30#include <assert.h>
31
32DLLEXPORT void libtrace_vector_init(libtrace_vector_t *v, size_t element_size) {
33        v->element_size = element_size;
34        v->size = 0; // Starts empty
35        v->max_size = 128; // Pick a largish size to begin with
36        v->elements = malloc(v->max_size * v->element_size);
37        ASSERT_RET(pthread_mutex_init(&v->lock, NULL), == 0);
38}
39
40DLLEXPORT void libtrace_vector_destroy(libtrace_vector_t *v) {
41        ASSERT_RET(pthread_mutex_destroy(&v->lock), == 0);
42        free(v->elements);
43        // Be safe make sure we wont work any more
44        v->elements = NULL;
45        v->size = 0;
46        v->max_size = 0;
47        v->element_size = 0;
48}
49
50DLLEXPORT void libtrace_vector_push_back(libtrace_vector_t *v, void *d) {
51        ASSERT_RET(pthread_mutex_lock(&v->lock), == 0);
52        if (v->size >= v->max_size) {
53                /* Resize */
54                v->max_size *= 2;
55                v->elements = realloc(v->elements, v->max_size * v->element_size);
56                assert(v->elements);
57        }
58        memcpy(&v->elements[v->size*v->element_size], d, v->element_size);
59        v->size++;
60        ASSERT_RET(pthread_mutex_unlock(&v->lock), == 0);
61}
62
63DLLEXPORT size_t libtrace_vector_get_size(libtrace_vector_t *v) {
64        return v->size;
65}
66
67DLLEXPORT int libtrace_vector_get(libtrace_vector_t *v, size_t location, void *d) {
68        ASSERT_RET(pthread_mutex_lock(&v->lock), == 0);
69        if (location >= v->size) {
70                ASSERT_RET(pthread_mutex_unlock(&v->lock), == 0);
71                return 0;
72        }
73        memcpy(d, &v->elements[location*v->element_size], v->element_size);
74        ASSERT_RET(pthread_mutex_unlock(&v->lock), == 0);
75        return 1;
76}
77
78DLLEXPORT int libtrace_vector_remove_front(libtrace_vector_t *v) {
79        size_t i;
80        ASSERT_RET(pthread_mutex_lock(&v->lock), == 0);
81        if (!v->size) {
82                ASSERT_RET(pthread_mutex_unlock(&v->lock), == 0);
83                return 0;
84        }
85        v->size--;
86        // Of course this is mega slow
87        for (i = 0; i < v->size * v->element_size; i++)
88                v->elements[i] = v->elements[i+v->element_size];
89        ASSERT_RET(pthread_mutex_unlock(&v->lock), == 0);
90        return 1;
91}
92
93static inline void memswap(void *a, void *b, size_t size) {
94        char c;
95        size_t i;
96        for (i=0; i<size; i++) {
97                c = ((char *)a)[i];
98                ((char *)a)[i] = ((char *)b)[i];
99                ((char *)b)[i] = c;
100        }
101}
102// Note elements must be the same size
103// This also empties the second source array
104DLLEXPORT void libtrace_vector_append(libtrace_vector_t *dest, libtrace_vector_t *src)
105{
106        assert(dest->element_size == src->element_size);
107        if (src->size == 0) // Nothing to do if this is the case
108                return;
109        ASSERT_RET(pthread_mutex_lock(&dest->lock), == 0);
110        ASSERT_RET(pthread_mutex_lock(&src->lock), == 0);
111        if (src->size == 0) // Double check now we've got the locks - Nothing to do if this is the case
112                goto unlock;
113        if (dest->size == 0) {
114                memswap(&dest->max_size, &src->max_size, sizeof(src->max_size));
115                memswap(&dest->size, &src->size, sizeof(src->size));
116                memswap(&dest->element_size, &src->element_size, sizeof(src->element_size));
117                memswap(&dest->elements, &src->elements, sizeof(src->elements));
118        } else {
119                size_t oldmax = dest->max_size;
120                while (dest->max_size - dest->size < src->size) dest->max_size *= 2;
121                if (oldmax != dest->max_size)
122                        dest->elements = realloc(dest->elements, dest->max_size * dest->element_size);
123                // Now do the move
124                memcpy(&dest->elements[dest->element_size * dest->size], src->elements, src->element_size * src->size);
125                // Update the dest size
126                dest->size += src->size;
127                // Wipe the src
128                src->size = 0;
129        }
130unlock:
131        ASSERT_RET(pthread_mutex_unlock(&src->lock), == 0);
132        ASSERT_RET(pthread_mutex_unlock(&dest->lock), == 0);
133}
134
135DLLEXPORT void libtrace_zero_vector(libtrace_vector_t *v)
136{
137        v->max_size = 0;
138        v->size = 0;
139        v->element_size = 0;
140        v->elements = NULL;
141}
142
143DLLEXPORT void libtrace_vector_empty(libtrace_vector_t *v) {
144        ASSERT_RET(pthread_mutex_lock(&v->lock), == 0);
145        v->size = 0;
146        ASSERT_RET(pthread_mutex_unlock(&v->lock), == 0);
147}
148
149
150DLLEXPORT void libtrace_vector_apply_function(libtrace_vector_t *v, vector_data_fn fn)
151{
152        size_t cur;
153        ASSERT_RET(pthread_mutex_lock(&v->lock), == 0);
154        for (cur = 0; cur < v->size; cur++) {
155                (*fn)(&v->elements[cur*v->element_size]);
156        }
157        ASSERT_RET(pthread_mutex_unlock(&v->lock), == 0);
158}
159
160DLLEXPORT void libtrace_vector_qsort(libtrace_vector_t *v, int (*compar)(const void *, const void*)) {
161        ASSERT_RET(pthread_mutex_lock(&v->lock), == 0);
162        qsort(v->elements, v->element_size, v->element_size, compar);
163        ASSERT_RET(pthread_mutex_unlock(&v->lock), == 0);
164}
Note: See TracBrowser for help on using the repository browser.