Skip site navigation (1)Skip section navigation (2)

  
 
  

home | help
sg_vector_create(3)					     sg_vector_create(3)

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 man-
     agement

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_vec-
					tor_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_vec-
				     tor *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 ini-
     tially allocated (to avoid too many calls to realloc() during later sg_vec-
     tor_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 re-
     mains untouched.

     sg_vector_resize() increases or decreases the amount of allocated	elements
     in  the specified vector. The amount of allocated elements is always a mul-
     tiple 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 el-
     ement data type as the source vector. It returns an error code != to SG_ER-
     ROR_NONE if something went wrong.

     sg_vector_compute_diff() computes a difference vector  between  the  vector
     containing  current  statistics and another vector containing older statis-
     tics. 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_com-
     pute_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 pro-
     gram is aborted. When sg_prove_vector() returns, it returns SG_ERROR_NONE.

     sg_get_nelements()  returns the number of elements the given data area, en-
     compasses 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   VEC-
     TOR_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 pre-
     processor macros are available. They are shown here as if they  were  func-
     tions 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 other-
     wise.  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_ER-
     ROR_CLEANUP  are  executed to cleanup before returning from current subrou-
     tine 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 vec-
     tor structures (struct sg_vector *).

SEE ALSO
     statgrab(3)

WEBSITE
     <https://libstatgrab.org/>

libstatgrab			   2019-10-03		     sg_vector_create(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=sg_vector_resize&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>

home | help