1sg_vector_create(3)                                        sg_vector_create(3)
2
3
4

NAME

6       sg_vector_create,  sg_vector_clear,  sg_vector_resize,  sg_vector_free,
7       sg_vector_clone,     sg_vector_clone_into,      sg_vector_compute_diff,
8       sg_prove_vector,  sg_get_nelements, sg_free_stats_buf - statgrab vector
9       management
10

SYNOPSIS

12       #include "statgrab.h"
13       #include "vector.h"
14
15
16       struct sg_vector *sg_vector_create (size_t block_size, size_t
17                                          alloc_count, size_t initial_used,
18                                          const sg_vector_init_info * const
19                                          info);
20
21       void sg_vector_clear (struct sg_vector *vector);
22
23       struct sg_vector *sg_vector_resize (struct sg_vector *vector);
24
25       void sg_vector_free (struct sg_vector *vector);
26
27       struct sg_vector *sg_vector_clone (const struct sg_vector *src);
28
29       sg_error sg_vector_clone_into (struct sg_vector **dest, const struct
30                                     sg_vector *src);
31
32       sg_error sg_vector_compute_diff (struct sg_vector **dest, const struct
33                                       sg_vector *cur_vector, const struct
34                                       sg_vector *last_vector);
35
36       sg_error sg_prove_vector (const struct sg_vector *vec);
37
38       size_t sg_get_nelements (const void *data);
39
40       sg_error sg_free_stats_buf (void *data);
41

DESCRIPTION

43       sg_vector_create() allocates and initialises a new statgrab vector with
44       initial_used  elements ready for use. Space for alloc_count elements is
45       initially allocated (to avoid too many calls to realloc() during  later
46       sg_vector_resize()  calls).  The value of block_size must be a power of
47       2, it's rounded up to the next power of 2 when it's not. If alloc_count
48       is  not  a multiple of block_size, it's rounded up to the next multiple
49       of block_size. It returns a pointer to the newly created vector.
50
51       sg_vector_clear() destroys all elements contained in the given  vector.
52       In  opposite to sg_vector_resize( x, 0 ) the allocated size of the vec‐
53       tor remains untouched.
54
55       sg_vector_resize() increases or decreases the amount of allocated  ele‐
56       ments  in the specified vector. The amount of allocated elements is al‐
57       ways a multiple of the intialisation parameter block_size. In the  spe‐
58       cial  case,  sg_vector_resize() is called with 0 in argument new_count,
59       the vector is freed after all vector elements had  been  destroyed.  It
60       returns the pointer to the resized vector.
61
62       sg_vector_free() destroys all vector elements and deallocates the stor‐
63       age belonging to the given vector.
64
65       sg_vector_clone() clones all elements of the given vector  into  a  new
66       vector  created  with  the same specification as the referenced one. It
67       returns a pointer to the cloned vector.
68
69       sg_vector_clone_into() clones all elements of the given  source  vector
70       into the given target vector. The target vector must be created for the
71       same element data type as the source vector. It returns an  error  code
72       != to SG_ERROR_NONE if something went wrong.
73
74       sg_vector_compute_diff()  computes a difference vector between the vec‐
75       tor containing current statistics and another vector  containing  older
76       statistics.  If  an element exists in the current vector but not in the
77       opposite one, it's cloned into the result vector. If an element  exists
78       only  in  the  opposite vector, it doesn't appear in the target vector.
79       sg_vector_compute_diff() returns an error code != to  SG_ERROR_NONE  if
80       something went wrong.
81
82       sg_prove_vector() proves whether a pointer to a vector really points to
83       a vector. In case the given vector pointer points  to  corrupted  data,
84       the  program  is  aborted.  When  sg_prove_vector() returns, it returns
85       SG_ERROR_NONE.
86
87       sg_get_nelements() returns the number of elements the given data  area,
88       encompasses  by  a statgrab vector, contains. The vector head is inter‐
89       nally calculated from the given pointer to the first vector element.
90
91       sg_free_stats_buf() frees the vector emcompassing the given data area.
92

NOTES

94       Except sg_get_nelements() and sg_free_stats_buf() none of  above  func‐
95       tions  can be called from outside of the libstatgrab sources. The docu‐
96       mented structures and APIs may change without warning. The  description
97       of all other API is intended to be read from libstatgrab developers on‐
98       ly.
99
100       Each vector is created from two elements: the  vector  information  and
101       the list of elements:
102
103       template <class T, class Impl>
104       struct sg_vector {
105               size_t used_count;
106               size_t alloc_count;
107               size_t block_shift;
108               Impl vector_implementation;
109               T elements[alloc_count];
110       };
111
112
113       Of course, it is not valid C, so being tricky was the solution:
114
115       typedef struct sg_vector {
116            size_t used_count;
117            size_t alloc_count;
118            size_t block_shift;
119            struct sg_vector_init_info info;
120       } sg_vector;
121
122       struct sg_vector_size_helper {
123            struct sg_vector v;
124            long long ll;
125       };
126
127       #define VECTOR_SIZE offsetof(struct sg_vector_size_helper,ll)
128
129       /* Return the data ptr of a vector */
130       #define VECTOR_DATA(vector) \
131            (vector ? (void *)(((char *)vector)+VECTOR_SIZE) : NULL)
132
133       #define VECTOR_ADDR_ARITH(ptr) \
134            (sg_vector *)(((char *)(ptr))-VECTOR_SIZE)
135       /* Return the vector for a data */
136       #define VECTOR_ADDRESS(ptr) \
137            ((ptr) ? (SG_ERROR_NONE == sg_prove_vector(VECTOR_ADDR_ARITH(ptr)) ? VECTOR_ADDR_ARITH(ptr) : NULL ) : NULL)
138
139
140       This   also   allows   user   functions   as   sg_get_nelements()   and
141       sg_free_stats_buf() to switch easily between the vector  structure  and
142       the content.
143
144   THE VECTOR SPECIALISATION STRUCTURE
145       As mentioned, the vector implementation uses strategies from the object
146       oriented programming concept named "polymorphism".   A  vector  is  de‐
147       scribed  by  a small object containing inherent attributes like element
148       size and a bunch of "virtual methods" to do element related tasks  like
149       initialising or destroying elements.
150
151       typedef void (*vector_init_function)(void *item);
152       typedef sg_error (*vector_copy_function)(const void *src, void *dst);
153       typedef sg_error (*vector_compute_diff_function)(void *dst, const void *src);
154       typedef int (*vector_compare_function)(const void *a, const void *b);
155       typedef void (*vector_destroy_function)(void *item);
156
157       struct sg_vector_init_info {
158               size_t item_size;
159               vector_init_function init_fn;
160               vector_copy_function copy_fn;
161               vector_compute_diff_function compute_diff_fn;
162               vector_compare_function compare_fn;
163               vector_destroy_function destroy_fn;
164       };
165
166
167       The instances of struct sg_vector_init_info are conceptional statically
168       initialised by using  either  the  preprocessor  macro  VECTOR_INIT_IN‐
169       FO_FULL_INIT(type)  or VECTOR_INIT_INFO_EMPTY_INIT(type).  Here're some
170       examples to demonstrate how it's meant:
171
172       Initialising CPU statistics vector description
173
174       VECTOR_INIT_INFO_EMPTY_INIT(sg_cpu_stats);
175
176
177       Initialising Host-Info statistics vector description
178
179       static void sg_os_stats_item_init(sg_os_stats *d);
180       static void sg_os_stats_item_destroy(sg_os_stats *d);
181
182       #define sg_os_stats_item_copy NULL
183       #define sg_os_stats_item_compute_diff NULL
184       #define sg_os_stats_item_compare NULL
185
186       VECTOR_INIT_INFO_FULL_INIT(sg_os_stats);
187
188
189       Initialising Disk-IO statistics vector description
190
191       static void sg_disk_io_stats_item_init(sg_disk_io_stats *d);
192       static sg_error sg_disk_io_stats_item_copy(sg_disk_io_stats *d, const sg_disk_io_stats *s);
193       static sg_error sg_disk_io_stats_item_compute_diff(const sg_disk_io_stats *s, sg_disk_io_stats *d);
194       static int sg_disk_io_stats_item_compare(const sg_disk_io_stats *a, const sg_disk_io_stats *b);
195       static void sg_disk_io_stats_item_destroy(sg_disk_io_stats *d);
196
197       VECTOR_INIT_INFO_FULL_INIT(sg_disk_io_stats);
198
199
200   WORKING WITH VECTORS
201       To simplify the working with the vector management functions, some pre‐
202       processor  macros  are  available.  They are shown here as if they were
203       functions to ease understanding.
204
205       struct sg_vector *VECTOR_CREATE (identifier type, size_t block_size);
206
207       void VECTOR_CLEAR (struct sg_vector *vector);
208
209       struct sg_vector *VECTOR_CREATE_OR_RESIZE (struct sg_vector *vector,
210                       size_t new_count, identifier type);
211
212       void VECTOR_UPDATE (struct sg_vector **vectorptr, size_t new_count,
213                          datatype *data, identifier datatype);
214
215       void VECTOR_ITEM_COUNT (struct sg_vector *vector);
216
217       VECTOR_CREATE() calls sg_vector_create() with alloc_count =  block_size
218       and  initial_used  =  0  using  the  vector  specialisation type##_vec‐
219       tor_init_info.
220
221       VECTOR_CLEAR() simply calls sg_vector_clear(). This macro  exists  only
222       for conformity.
223
224       VECTOR_CREATE_OR_RESIZE()  calls sg_vector_create() when the given vec‐
225       tor pointer points to NULL or sg_vector_resize() otherwise. The  result
226       of the appropriate function is returned.
227
228       VECTOR_UPDATE()  calls  VECTOR_CREATE_OR_RESIZE()  and sets data to the
229       first element of the resulting vector when a non-NULL pointer  got,  to
230       NULL  otherwise.  When VECTOR_CREATE_OR_RESIZE() returns a NULL pointer
231       and new_count is not equal to 0 (zero), the intructions from the  macro
232       VECTOR_UPDATE_ERROR_CLEANUP  are  executed  to cleanup before returning
233       from current subroutine with the error which has been occurred.
234
235       VECTOR_ITEM_COUNT() returns 0 for a non-existing vector (vector  ==  0)
236       and the number of containing elements otherwise.
237

RETURN VALUES

239       Beside  error codes, the return values, if any, are always a pointer to
240       vector structures (struct sg_vector *).
241

SEE ALSO

243       statgrab(3)
244

WEBSITE

246https://libstatgrab.org/
247
248
249
250libstatgrab                       2019-03-08               sg_vector_create(3)
Impressum