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

FreeBSD Manual Pages


home | help
sg_vector_create(3)					   sg_vector_create(3)

       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

       #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

       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);

       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 vec-
       tor remains untouched.

       sg_vector_resize() increases or decreases the amount of allocated  ele-
       ments  in the specified vector. The amount of allocated elements	is al-
       ways a multiple of the intialisation parameter block_size. In the  spe-
       cial  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 stor-
       age 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 vec-
       tor 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_get_nelements() returns the number of	elements the given data	 area,
       encompasses  by	a statgrab vector, contains. The vector	head is	inter-
       nally calculated	from the given pointer to the first vector element.

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

       Except sg_get_nelements() and sg_free_stats_buf() none of  above	 func-
       tions  can be called from outside of the	libstatgrab sources. The docu-
       mented structures and APIs may change without warning. The  description
       of all other API	is intended to be read from libstatgrab	developers on-

       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.

       As mentioned, the vector	implementation uses strategies from the	object
       oriented	programming concept named "polymorphism".   A  vector  is  de-
       scribed	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_IN-
       FO_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


       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


       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);


       To simplify the working with the	vector management functions, some pre-
       processor  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##_vec-

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

       VECTOR_CREATE_OR_RESIZE()  calls	sg_vector_create() when	the given vec-
       tor 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 intructions 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.

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



libstatgrab			  2019-03-08		   sg_vector_create(3)


Want to link to this manual page? Use this URL:

home | help