Provided by: libstatgrab-dev_0.92.1-1.2build1_amd64 bug

NAME

       sg_vector_create,      sg_vector_clear,      sg_vector_resize,      sg_vector_free,      sg_vector_clone,
       sg_vector_clone_into,  sg_vector_compute_diff,  sg_prove_vector,  sg_get_nelements,  sg_free_stats_buf  -
       statgrab vector management

SYNOPSIS

       #include "statgrab.h"
       #include "vector.h"

       struct sg_vector *sg_vector_create (size_t block_size, size_t alloc_count, size_t initial_used, const
                                          sg_vector_init_info * const info);

       void sg_vector_clear (struct sg_vector *vector);

       struct sg_vector *sg_vector_resize (struct sg_vector *vector);

       void sg_vector_free (struct sg_vector *vector);

       struct sg_vector *sg_vector_clone (const struct sg_vector *src);

       sg_error sg_vector_clone_into (struct sg_vector **dest, const struct sg_vector *src);

       sg_error sg_vector_compute_diff (struct sg_vector **dest, const struct sg_vector *cur_vector, const
                                       struct sg_vector *last_vector);

       sg_error sg_prove_vector (const struct sg_vector *vec);

       size_t sg_get_nelements (const void *data);

       sg_error sg_free_stats_buf (void *data);

DESCRIPTION

       sg_vector_create()  allocates  and initialises a new statgrab vector with initial_used elements ready for
       use. Space for alloc_count elements is initially allocated (to avoid too many calls to  realloc()  during
       later  sg_vector_resize()  calls).  The  value of block_size must be a power of 2, it's rounded up to the
       next power of 2 when it's not. If alloc_count is not a multiple of block_size, it's  rounded  up  to  the
       next multiple of block_size. It returns a pointer to the newly created vector.

       sg_vector_clear()  destroys  all elements contained in the given vector. In opposite to sg_vector_resize(
       x, 0 ) the allocated size of the vector remains untouched.

       sg_vector_resize() increases or decreases the amount of allocated elements in the specified  vector.  The
       amount  of  allocated  elements  is  always a multiple of the initialisation parameter block_size. In the
       special case, sg_vector_resize() is called with 0 in argument new_count, the vector is  freed  after  all
       vector elements had been destroyed. It returns the pointer to the resized vector.

       sg_vector_free() destroys all vector elements and deallocates the storage belonging to the given vector.

       sg_vector_clone()  clones  all  elements  of  the  given  vector  into a new vector created with the same
       specification as the referenced one. It returns a pointer to the cloned vector.

       sg_vector_clone_into() clones all elements of the given source vector into the given target  vector.  The
       target  vector  must  be created for the same element data type as the source vector. It returns an error
       code != to SG_ERROR_NONE if something went wrong.

       sg_vector_compute_diff() computes a difference vector between the vector  containing  current  statistics
       and another vector containing older statistics. If an element exists in the current vector but not in the
       opposite one, it's cloned into the result vector. If an element exists only in the  opposite  vector,  it
       doesn't  appear in the target vector.  sg_vector_compute_diff() returns an error code != to SG_ERROR_NONE
       if something went wrong.

       sg_prove_vector() proves whether a pointer to a vector really points to  a  vector.  In  case  the  given
       vector  pointer  points  to  corrupted  data,  the program is aborted. When sg_prove_vector() returns, it
       returns SG_ERROR_NONE.

       sg_get_nelements() returns the number of elements the given data area, encompasses by a statgrab  vector,
       contains. The vector head is internally calculated from the given pointer to the first vector element.

       sg_free_stats_buf() frees the vector emcompassing the given data area.

NOTES

       Except  sg_get_nelements()  and sg_free_stats_buf() none of above functions can be called from outside of
       the libstatgrab sources. The documented structures and APIs may change without warning.  The  description
       of all other API is intended to be read from libstatgrab developers only.

       Each vector is created from two elements: the vector information and the list of elements:

       template <class T, class Impl>
       struct sg_vector {
               size_t used_count;
               size_t alloc_count;
               size_t block_shift;
               Impl vector_implementation;
               T elements[alloc_count];
       };

       Of course, it is not valid C, so being tricky was the solution:

       typedef struct sg_vector {
            size_t used_count;
            size_t alloc_count;
            size_t block_shift;
            struct sg_vector_init_info info;
       } sg_vector;

       struct sg_vector_size_helper {
            struct sg_vector v;
            long long ll;
       };

       #define VECTOR_SIZE offsetof(struct sg_vector_size_helper,ll)

       /* Return the data ptr of a vector */
       #define VECTOR_DATA(vector) \
            (vector ? (void *)(((char *)vector)+VECTOR_SIZE) : NULL)

       #define VECTOR_ADDR_ARITH(ptr) \
            (sg_vector *)(((char *)(ptr))-VECTOR_SIZE)
       /* Return the vector for a data */
       #define VECTOR_ADDRESS(ptr) \
            ((ptr) ? (SG_ERROR_NONE == sg_prove_vector(VECTOR_ADDR_ARITH(ptr)) ? VECTOR_ADDR_ARITH(ptr) : NULL ) : NULL)

       This  also  allows  user functions as sg_get_nelements() and sg_free_stats_buf() to switch easily between
       the vector structure and the content.

   THE VECTOR SPECIALISATION STRUCTURE
       As mentioned, the vector implementation uses strategies from  the  object  oriented  programming  concept
       named  "polymorphism".   A  vector  is  described  by  a small object containing inherent attributes like
       element size and a bunch of "virtual methods" to do element related tasks like initialising or destroying
       elements.

       typedef void (*vector_init_function)(void *item);
       typedef sg_error (*vector_copy_function)(const void *src, void *dst);
       typedef sg_error (*vector_compute_diff_function)(void *dst, const void *src);
       typedef int (*vector_compare_function)(const void *a, const void *b);
       typedef void (*vector_destroy_function)(void *item);

       struct sg_vector_init_info {
               size_t item_size;
               vector_init_function init_fn;
               vector_copy_function copy_fn;
               vector_compute_diff_function compute_diff_fn;
               vector_compare_function compare_fn;
               vector_destroy_function destroy_fn;
       };

       The  instances  of struct sg_vector_init_info are conceptional statically initialised by using either the
       preprocessor macro VECTOR_INIT_INFO_FULL_INIT(type) or VECTOR_INIT_INFO_EMPTY_INIT(type).   Here're  some
       examples to demonstrate how it's meant:

       Initialising CPU statistics vector description

       VECTOR_INIT_INFO_EMPTY_INIT(sg_cpu_stats);

       Initialising Host-Info statistics vector description

       static void sg_os_stats_item_init(sg_os_stats *d);
       static void sg_os_stats_item_destroy(sg_os_stats *d);

       #define sg_os_stats_item_copy NULL
       #define sg_os_stats_item_compute_diff NULL
       #define sg_os_stats_item_compare NULL

       VECTOR_INIT_INFO_FULL_INIT(sg_os_stats);

       Initialising Disk-IO statistics vector description

       static void sg_disk_io_stats_item_init(sg_disk_io_stats *d);
       static sg_error sg_disk_io_stats_item_copy(sg_disk_io_stats *d, const sg_disk_io_stats *s);
       static sg_error sg_disk_io_stats_item_compute_diff(const sg_disk_io_stats *s, sg_disk_io_stats *d);
       static int sg_disk_io_stats_item_compare(const sg_disk_io_stats *a, const sg_disk_io_stats *b);
       static void sg_disk_io_stats_item_destroy(sg_disk_io_stats *d);

       VECTOR_INIT_INFO_FULL_INIT(sg_disk_io_stats);

   WORKING WITH VECTORS
       To  simplify  the  working  with the vector management functions, some preprocessor macros are available.
       They are shown here as if they were functions to ease understanding.

       struct sg_vector *VECTOR_CREATE (identifier type, size_t block_size);

       void VECTOR_CLEAR (struct sg_vector *vector);

       struct sg_vector *VECTOR_CREATE_OR_RESIZE (struct sg_vector *vector, size_t new_count, identifier type);

       void VECTOR_UPDATE (struct sg_vector **vectorptr, size_t new_count, datatype *data, identifier datatype);

       void VECTOR_ITEM_COUNT (struct sg_vector *vector);

       VECTOR_CREATE() calls sg_vector_create() with alloc_count = block_size and initial_used  =  0  using  the
       vector specialisation type##_vector_init_info.

       VECTOR_CLEAR() simply calls sg_vector_clear(). This macro exists only for conformity.

       VECTOR_CREATE_OR_RESIZE()  calls  sg_vector_create()  when  the  given  vector  pointer points to NULL or
       sg_vector_resize() otherwise. The result of the appropriate function is returned.

       VECTOR_UPDATE() calls VECTOR_CREATE_OR_RESIZE() and sets data to  the  first  element  of  the  resulting
       vector  when  a  non-NULL  pointer got, to NULL otherwise.  When VECTOR_CREATE_OR_RESIZE() returns a NULL
       pointer   and   new_count   is   not   equal   to   0   (zero),   the   instructions   from   the   macro
       VECTOR_UPDATE_ERROR_CLEANUP  are  executed  to  cleanup before returning from current subroutine with the
       error which has been occurred.

       VECTOR_ITEM_COUNT() returns 0 for a non-existing vector (vector  ==  0)  and  the  number  of  containing
       elements otherwise.

RETURN VALUES

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

SEE ALSO

       statgrab(3)

WEBSITE

       ⟨https://libstatgrab.org/⟩