OCT 1. 更新vector

This commit is contained in:
huangxin 2023-02-10 14:08:56 +08:00
parent 445a82aa8f
commit 6c2e5c464d
2 changed files with 368 additions and 328 deletions

View File

@ -11,10 +11,6 @@
#ifndef SRC_ZVECTOR_H_ #ifndef SRC_ZVECTOR_H_
#define SRC_ZVECTOR_H_ #define SRC_ZVECTOR_H_
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -27,8 +23,11 @@ extern "C" {
// so we know on which platform and which features // so we know on which platform and which features
// we can use: // we can use:
#include "zvector_checks.h" #include "zvector_checks.h"
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif
// Include c_vector configuration header // Include vector configuration header
#include "zvector_config.h" #include "zvector_config.h"
// Declare required structs: // Declare required structs:
@ -39,25 +38,28 @@ typedef struct p_vector *c_vector;
/* /*
* Vector Properties Flags can be used to tell ZVector * Vector Properties Flags can be used to tell ZVector
* which types of properties we want to enable for each * which types of properties we want to enable for each
* given c_vector we are creating. * given vector we are creating.
* Each c_vector can have multiple properties enabled at the * Each vector can have multiple properties enabled at the
* same time, you can use the typical C form to specify multiple * same time, you can use the typical C form to specify multiple
* properties for the same c_vector: * properties for the same vector:
* *
* ZV_SEC_WIPE | ZV_BYREF * ZV_SEC_WIPE | ZV_BYREF
* *
* The above will create a c_vector that supports passing items to * The above will create a vector that supports passing items to
* it by reference (instead of copying them into the c_vector) and * it by reference (instead of copying them into the vector) and
* having Secure Wipe enabled, so that when an element is deleted * having Secure Wipe enabled, so that when an element is deleted
* its reference will also be fully zeroed out before freeing it. * its reference will also be fully zeroed out before freeing it.
*/ */
enum ZVECT_PROPERTIES { enum ZVECT_PROPERTIES {
ZV_NONE = 0, // Sets or Resets all c_vector's properties to 0. ZV_NONE = 0, // Sets or Resets all vector's properties to 0.
ZV_SEC_WIPE = 1 << 0, // Sets the c_vector for automatic Secure Wipe of items. ZV_SEC_WIPE = 1 << 0, // Sets the vector for automatic Secure Wipe of items.
ZV_BYREF = 1 << 1, // Sets the c_vector to store items by reference instead of copying them as per default. ZV_BYREF = 1 << 1, // Sets the vector to store items by reference instead of
ZV_CIRCULAR = 1 // copying them as per default.
<< 2, // Sets the c_vector to be a circular c_vector (so it will not grow in capacity automatically). Elements will be overwritten as in typical circular buffers! ZV_CIRCULAR = 1 << 2, // Sets the vector to be a circular vector (so it will
ZV_NOLOCKING = 1 << 3, // This Property means the c_vector will not use mutexes, be careful using it! // not grow in capacity automatically). Elements will be
// overwritten as in typical circular buffers!
ZV_NOLOCKING = 1 << 3, // This Property means the vector will not use mutexes,
// be careful using it!
}; };
enum ZVECT_ERR { enum ZVECT_ERR {
@ -72,6 +74,8 @@ enum ZVECT_ERR {
ZVERR_OPNOTALLOWED = -9 ZVERR_OPNOTALLOWED = -9
}; };
extern unsigned int LOG_PRIORITY;
/***************************** /*****************************
** Public API declaration: ** ** Public API declaration: **
*****************************/ *****************************/
@ -79,7 +83,7 @@ enum ZVECT_ERR {
// Vector construction/Destruction and memory control: // Vector construction/Destruction and memory control:
/* /*
* vect_create creates and returns a new c_vector * vect_create creates and returns a new vector
* of the specified "capacity", with a storage area that * of the specified "capacity", with a storage area that
* can store items of "item_size" size and, if we want to * can store items of "item_size" size and, if we want to
* have an automatic secure erasing enabled (ZV_SEC_WIPE * have an automatic secure erasing enabled (ZV_SEC_WIPE
@ -90,16 +94,16 @@ enum ZVECT_ERR {
c_vector vect_create(zvect_index capacity, size_t item_size, uint32_t properties); c_vector vect_create(zvect_index capacity, size_t item_size, uint32_t properties);
/* /*
* vect_destroy destroys the specified c_vector and, if * vect_destroy destroys the specified vector and, if
* secure_wipe is enabled, also ensure erasing each single * secure_wipe is enabled, also ensure erasing each single
* value in the c_vector before destroying it. * value in the vector before destroying it.
*/ */
void vect_destroy(c_vector); void vect_destroy(c_vector);
/* /*
* vect_shrink is useful when operating on systems with * vect_shrink is useful when operating on systems with
* small amount of RAM, and it basically allows to shrink * small amount of RAM, and it basically allows to shrink
* the c_vector capacity to match the actual used size, to * the vector capacity to match the actual used size, to
* save unused memory locations. * save unused memory locations.
*/ */
void vect_shrink(c_vector const v); void vect_shrink(c_vector const v);
@ -107,7 +111,7 @@ void vect_shrink(c_vector const v);
/* /*
* vect_set_wipefunct allows you to pass ZVector a pointer to a custom * vect_set_wipefunct allows you to pass ZVector a pointer to a custom
* function (of your creation) to securely wipe data from the c_vector v * function (of your creation) to securely wipe data from the vector v
* when automatic safe wipe is called. * when automatic safe wipe is called.
*/ */
void vect_set_wipefunct(c_vector const v, void (*f1)(const void *item, size_t size)); void vect_set_wipefunct(c_vector const v, void (*f1)(const void *item, size_t size));
@ -115,29 +119,43 @@ void vect_set_wipefunct(c_vector const v, void (*f1)(const void *item, size_t si
// Vector state checks: // Vector state checks:
/* /*
* vect_is_empty returns true if the c_vector is empty * vect_is_empty returns true if the vector is empty
* and false if the c_vector is NOT empty. * and false if the vector is NOT empty.
*/ */
bool vect_is_empty(c_vector const v); int vect_is_empty(struct p_vector *const v);
/* /*
* vect_size returns the actual size (the number of) * vect_size returns the actual size (the number of)
* USED slots in the c_vector storage. * USED slots in the vector storage.
*/ */
zvect_index vect_size(c_vector const v); zvect_index vect_size(c_vector const v);
/* /*
* vect_clear clears out a c_vector and also resizes it * vect_size returns the maximum size (the max number of)
* slots in the vector storage.
*/
zvect_index vect_max_size(c_vector const v);
void *vect_begin(c_vector const v);
void *vect_end(c_vector const v);
/*
* vect_clear clears out a vector and also resizes it
* to its initial capacity. * to its initial capacity.
*/ */
void vect_clear(c_vector const v); void vect_clear(c_vector const v);
/*
* Vector status bits control
*/
bool vect_check_status(const c_vector v, zvect_index flag_id); bool vect_check_status(const c_vector v, zvect_index flag_id);
bool vect_set_status(const c_vector v, zvect_index flag_id); bool vect_set_status(const c_vector v, zvect_index flag_id);
bool vect_clear_status(const c_vector v, zvect_index flag_id); bool vect_clear_status(const c_vector v, zvect_index flag_id);
bool vect_toggle_status(const c_vector v, zvect_index flag_id);
#if (ZVECT_THREAD_SAFE == 1) #if (ZVECT_THREAD_SAFE == 1)
// Vector Thread Safe functions: // Vector Thread Safe functions:
@ -164,34 +182,34 @@ void vect_lock_enable(void);
void vect_lock_disable(void); void vect_lock_disable(void);
/* /*
* vect_lock allows you to lock the given c_vector to * vect_lock allows you to lock the given vector to
* have exclusive write access from your own thread. * have exclusive write access from your own thread.
* When you lock a c_vector directly then ZVector will * When you lock a vector directly then ZVector will
* NOT use its internal locking mechanism for that * NOT use its internal locking mechanism for that
* specific c_vector. * specific vector.
* *
* Example of use: To lock a c_vector called v * Example of use: To lock a vector called v
* vect_lock(v); * vect_lock(v);
*/ */
zvect_retval vect_lock(c_vector const v); zvect_retval vect_lock(c_vector const v);
/* /*
* vect_trylock will try to lock the given c_vector to * vect_trylock will try to lock the given vector to
* have exclusive write access from your own thread. * have exclusive write access from your own thread.
* When you lock a c_vector directly then ZVector will * When you lock a vector directly then ZVector will
* NOT use its internal locking mechanism for that * NOT use its internal locking mechanism for that
* specific c_vector. * specific vector.
* *
* Example of use: To lock a c_vector called v * Example of use: To lock a vector called v
* vect_trylock(v); * vect_trylock(v);
*/ */
zvect_retval vect_trylock(c_vector const v); zvect_retval vect_trylock(c_vector const v);
/* /*
* vect_lock allows you to unlock the given c_vector that * vect_lock allows you to unlock the given vector that
* you have previously locked with vect_lock. * you have previously locked with vect_lock.
* *
* Example of use: To unlock a c_vector called v * Example of use: To unlock a vector called v
* vect_unlock(v); * vect_unlock(v);
*/ */
zvect_retval vect_unlock(c_vector const v); zvect_retval vect_unlock(c_vector const v);
@ -223,11 +241,11 @@ zvect_retval vect_sem_post(const c_vector v);
/* /*
* vect_push and vect_pop are used to use the * vect_push and vect_pop are used to use the
* c_vector as a dynamic stack. * vector as a dynamic stack.
* *
* int i = 3; * int i = 3;
* vect_push(v, &i) pushes the element 3 at the * vect_push(v, &i) pushes the element 3 at the
* back of the c_vector v, which * back of the vector v, which
* corresponds to the top of a * corresponds to the top of a
* Stack. * Stack.
*/ */
@ -235,25 +253,25 @@ void vect_push(c_vector const v, const void *item);
/* /*
* vect_pop(v) "pops" (returns) the element * vect_pop(v) "pops" (returns) the element
* at the back of the c_vector as * at the back of the vector as
* a regular pop would do with * a regular pop would do with
* an element at the top of a * an element at the top of a
* stack. Remember when you use * stack. Remember when you use
* vect_pop the element you * vect_pop the element you
* receive is also removed from * receive is also removed from
* the c_vector! * the vector!
*/ */
void *vect_pop(c_vector const v); void *vect_pop(c_vector const v);
#define vect_pop_back(x) vect_pop(x) #define vect_pop_back(x) vect_pop(x)
/* /*
* vect_add adds a new item into the c_vector and, * vect_add adds a new item into the vector and,
* if required, will also reorganize the c_vector. * if required, will also reorganize the vector.
* *
* int i = 3; * int i = 3;
* vect_add(v, &i) will add the new item 3 in * vect_add(v, &i) will add the new item 3 in
* the c_vector v at the end * the vector v at the end
* (or back) of the c_vector v. * (or back) of the vector v.
*/ */
void vect_add(c_vector const v, const void *item); void vect_add(c_vector const v, const void *item);
#define vect_push_back(x, y) vect_add(x, y) #define vect_push_back(x, y) vect_add(x, y)
@ -261,7 +279,7 @@ void vect_add(c_vector const v, const void *item);
/* /*
* int i = 4; * int i = 4;
* vect_add_at(v, &i, 2) will add the new item 4 at * vect_add_at(v, &i, 2) will add the new item 4 at
* position 2 in the c_vector v * position 2 in the vector v
* and move all the elements * and move all the elements
* from the original 2nd onward * from the original 2nd onward
* of a position to make space * of a position to make space
@ -272,22 +290,22 @@ void vect_add_at(c_vector const v, const void *item, zvect_index index);
/* /*
* int i = 5; * int i = 5;
* vect_add_front(v, &i) will add the new item 5 at * vect_add_front(v, &i) will add the new item 5 at
* the beginning of the c_vector * the beginning of the vector
* v (or front) and will also * v (or front) and will also
* move all the existing * move all the existing
* elements of one position in * elements of one position in
* the c_vector to make space for * the vector to make space for
* the new item 5 at the front * the new item 5 at the front
* of c_vector v. * of vector v.
*/ */
void vect_add_front(c_vector const v, const void *item); void vect_add_front(c_vector const v, const void *item);
#define vect_push_front(x, y) vect_add_front(x, y) #define vect_push_front(x, y) vect_add_front(x, y)
/* /*
* vect_get returns an item from the specified c_vector * vect_get returns an item from the specified vector
* *
* vect_get(v) will return the ast element in * vect_get(v) will return the ast element in
* the v c_vector (but will not remove * the v vector (but will not remove
* the element as it happens in * the element as it happens in
* vect_pop(v)). * vect_pop(v)).
*/ */
@ -297,25 +315,25 @@ void *vect_get(c_vector const v);
/* /*
* *
* vect_get_at(v, 3) will return the element at location * vect_get_at(v, 3) will return the element at location
* 3 in the c_vector v. * 3 in the vector v.
*/ */
void *vect_get_at(c_vector const v, const zvect_index i); void *vect_get_at(c_vector const v, const zvect_index i);
#define vect_at(v, x) vect_get_at(v, x) #define vect_at(v, x) vect_get_at(v, x)
/* /*
* vect_get_front(v) will return the first element in * vect_get_front(v) will return the first element in
* the c_vector v. * the vector v.
*/ */
void *vect_get_front(c_vector const v); void *vect_get_front(c_vector const v);
#define vect_front(v) vect_get_front(v) #define vect_front(v) vect_get_front(v)
/* /*
*vect_put allows you to REPLACE an item *vect_put allows you to REPLACE an item
* in the c_vector. * in the vector.
* *
* int i = 3; * int i = 3;
* vect_put(v, &i) will replace the last element * vect_put(v, &i) will replace the last element
* in the c_vector with 3. * in the vector with 3.
*/ */
void vect_put(c_vector const v, const void *item); void vect_put(c_vector const v, const void *item);
@ -323,7 +341,7 @@ void vect_put(c_vector const v, const void *item);
* *
* int i = 4; * int i = 4;
* vect_put_at(v, &i, 2) will replace the 3rd element * vect_put_at(v, &i, 2) will replace the 3rd element
* (2 + 1, as c_vector's 1st item * (2 + 1, as vector's 1st item
* starts at v[0]) with the * starts at v[0]) with the
* item 4. * item 4.
*/ */
@ -333,54 +351,54 @@ void vect_put_at(c_vector const v, const void *item, const zvect_index i);
* *
* int i = 5; * int i = 5;
* vect_put_front(v, &i) will replace the 1st element * vect_put_front(v, &i) will replace the 1st element
* of the c_vector with the item * of the vector with the item
* 5. * 5.
*/ */
void vect_put_front(c_vector const v, const void *item); void vect_put_front(c_vector const v, const void *item);
/* /*
* vect_remove removes an item from the c_vector * vect_remove removes an item from the vector
* and reorganise the c_vector. It also returns * and reorganise the vector. It also returns
* the item remove from the c_vector, so you can * the item remove from the vector, so you can
* use it to simulate a stack behaviour as well. * use it to simulate a stack behaviour as well.
* *
* vect_remove(v) will remove and return the * vect_remove(v) will remove and return the
* last item in the c_vector. * last item in the vector.
*/ */
void *vect_remove(c_vector const v); void *vect_remove(c_vector const v);
/* /*
* vect_remove_at(v, 3) will remove the 3rd item in * vect_remove_at(v, 3) will remove the 3rd item in
* the c_vector and return it. * the vector and return it.
*/ */
void *vect_remove_at(c_vector const v, const zvect_index i); void *vect_remove_at(c_vector const v, const zvect_index i);
/* /*
* vect_remove_front(v) will remove the 1st item in * vect_remove_front(v) will remove the 1st item in
* the c_vector and return it. * the vector and return it.
*/ */
void *vect_remove_front(c_vector const v); void *vect_remove_front(c_vector const v);
/* /*
* vect_delete deletes an item from the c_vector * vect_delete deletes an item from the vector
* and reorganise the c_vector. It does not return * and reorganise the vector. It does not return
* the item like remove. * the item like remove.
* *
* vect_delete(v) will delete and the last * vect_delete(v) will delete and the last
* item in the c_vector. * item in the vector.
*/ */
void vect_delete(c_vector const v); void vect_delete(c_vector const v);
/* /*
* vect_delete_at(v, 3) will delete the 3rd item in * vect_delete_at(v, 3) will delete the 3rd item in
* the c_vector. * the vector.
*/ */
void vect_delete_at(c_vector const v, const zvect_index i); void vect_delete_at(c_vector const v, const zvect_index i);
/* /*
* vect_delete_range(v, 20, 30) * vect_delete_range(v, 20, 30)
* will delete items from item * will delete items from item
* 20 to item 30 in the c_vector * 20 to item 30 in the vector
* v. * v.
*/ */
void vect_delete_range(c_vector const v, const zvect_index first_element, const zvect_index last_element); void vect_delete_range(c_vector const v, const zvect_index first_element, const zvect_index last_element);
@ -388,7 +406,7 @@ void vect_delete_range(c_vector const v, const zvect_index first_element, const
/* /*
* *
* vect_delete_front(v) will delete the 1st item in * vect_delete_front(v) will delete the 1st item in
* the c_vector. * the vector.
*/ */
void vect_delete_front(c_vector const v); void vect_delete_front(c_vector const v);
@ -401,11 +419,11 @@ void vect_delete_front(c_vector const v);
/* /*
* vect_swap is a function that allows you to swap two * vect_swap is a function that allows you to swap two
* items in the same c_vector. * items in the same vector.
* You just pass the c_vector and the index of both the * You just pass the vector and the index of both the
* two items to swap. * two items to swap.
* *
* For example to swap item 3 with item 22 on c_vector v * For example to swap item 3 with item 22 on vector v
* use: * use:
* vect_swap(v, 3, 22); * vect_swap(v, 3, 22);
*/ */
@ -413,23 +431,23 @@ void vect_swap(c_vector const v, const zvect_index s, const zvect_index e);
/* /*
* vect_swap_range is a function that allows to swap * vect_swap_range is a function that allows to swap
* a range of items in the same c_vector. * a range of items in the same vector.
* You just pass the c_vector, the index of the first item * You just pass the vector, the index of the first item
* to swap, the index of the last item to swap and the * to swap, the index of the last item to swap and the
* index of the first item to swap with. * index of the first item to swap with.
* *
* For example to swap items from 10 to 20 with items * For example to swap items from 10 to 20 with items
* from 30 to 40 on c_vector v, use: * from 30 to 40 on vector v, use:
* vect_swap_range(v, 10, 20, 30); * vect_swap_range(v, 10, 20, 30);
*/ */
void vect_swap_range(c_vector const v, const zvect_index s1, const zvect_index e1, const zvect_index s2); void vect_swap_range(c_vector const v, const zvect_index s1, const zvect_index e1, const zvect_index s2);
/* /*
* vect_rotate_left is a function that allows to rotate * vect_rotate_left is a function that allows to rotate
* a c_vector of "i" positions to the left (or from the * a vector of "i" positions to the left (or from the
* "front" to the "end"). * "front" to the "end").
* *
* For example to rotate a c_vector called v of 5 positions * For example to rotate a vector called v of 5 positions
* to the left, use: * to the left, use:
* vect_rotate_left(v, 5); * vect_rotate_left(v, 5);
*/ */
@ -437,34 +455,34 @@ void vect_rotate_left(c_vector const v, const zvect_index i);
/* /*
* vect_rotate_right is a function that allows to rotate * vect_rotate_right is a function that allows to rotate
* a c_vector of "i" positions to the right (or from the * a vector of "i" positions to the right (or from the
* "end" to the "front"). * "end" to the "front").
* *
* For example to rotate a c_vector called v of 5 positions * For example to rotate a vector called v of 5 positions
* to the right, use: * to the right, use:
* vect_rotate_right(v, 5); * vect_rotate_right(v, 5);
*/ */
void vect_rotate_right(c_vector const v, const zvect_index i); void vect_rotate_right(c_vector const v, const zvect_index i);
/* /*
* vect_qsort allows you to sort a given c_vector. * vect_qsort allows you to sort a given vector.
* The algorithm used to sort a c_vector is Quicksort with * The algorithm used to sort a vector is Quicksort with
* 3 ways partitioning which is generally much faster than * 3 ways partitioning which is generally much faster than
* traditional quicksort. * traditional quicksort.
* *
* To sort a c_vector you need to provide a custom function * To sort a vector you need to provide a custom function
* that allows vect_sort to determine the order and which * that allows vect_sort to determine the order and which
* elements of a c_vector are used to order it in the way * elements of a vector are used to order it in the way
* you desire. It pretty much works as a regular C qsort * you desire. It pretty much works as a regular C qsort
* function. It quite fast given that it only reorders * function. It quite fast given that it only reorders
* pointers to your datastructures stored in the c_vector. * pointers to your datastructures stored in the vector.
* *
*/ */
void vect_qsort(c_vector const v, int (*compare_func)(const void *, const void *)); void vect_qsort(c_vector const v, int (*compare_func)(const void *, const void *));
/* /*
* vect_bsearch is a function that allows to perform * vect_bsearch is a function that allows to perform
* a binary search over the c_vector we pass to it to * a binary search over the vector we pass to it to
* find the item "key" using the comparison function * find the item "key" using the comparison function
* "f1". * "f1".
* *
@ -474,31 +492,26 @@ void vect_qsort(c_vector const v, int (*compare_func)(const void *, const void *
* some improvements over the original one (look at the * some improvements over the original one (look at the
* sources for more details). * sources for more details).
* *
* For example to search for the number 5 in a c_vector * For example to search for the number 5 in a vector
* called v using a compare function called "my_compare" * called v using a compare function called "my_compare"
* use: * use:
* int i = 5; * int i = 5;
* vect_bsearch(v, &i, my_compare); * vect_bsearch(v, &i, my_compare);
*/ */
#ifdef __cplusplus
extern "C" {
#endif
bool vect_bsearch(c_vector const v, const void *key, int (*f1)(const void *, const void *), zvect_index *item_index); bool vect_bsearch(c_vector const v, const void *key, int (*f1)(const void *, const void *), zvect_index *item_index);
#ifdef __cplusplus
}
#endif
/* /*
* vect_add_ordered allows the insertion of new items in * vect_add_ordered allows the insertion of new items in
* an ordered fashion. Please note that for this to work * an ordered fashion. Please note that for this to work
* fine you should always use only ordered vectors or if * fine you should always use only ordered vectors or if
* an empty c_vector use vect_add_ordered only to add new * an empty vector use vect_add_ordered only to add new
* values to it! * values to it!
* *
* As for any other ordered function you must provide * As for any other ordered function you must provide
* your own compare function (syntax is the usual one, * your own compare function (syntax is the usual one,
* and it's the same as for regular CLib qsort function) * and it's the same as for regular CLib qsort function)
* *
* To add item 3 to a c_vector called v using vect_add_ordered * To add item 3 to a vector called v using vect_add_ordered
* (assuming your compare function is called my_compare), * (assuming your compare function is called my_compare),
* use: * use:
* *
@ -513,23 +526,23 @@ void vect_add_ordered(c_vector const v, const void *value, int (*f1)(const void
/* /*
* vect_apply allows you to apply a C function to * vect_apply allows you to apply a C function to
* each item in the c_vector, so you just pass the c_vector, * each item in the vector, so you just pass the vector,
* the function you want to execute against each item on * the function you want to execute against each item on
* a c_vector and make sure such function is declared and * a vector and make sure such function is declared and
* defined to accept a "void *" pointer which will be the * defined to accept a "void *" pointer which will be the
* pointer to the single item in the c_vector passed to your * pointer to the single item in the vector passed to your
* function. The function has no return value because it's * function. The function has no return value because it's
* not necessary if you receive the pointer to the item. * not necessary if you receive the pointer to the item.
* You can simply update the content of the memory pointed * You can simply update the content of the memory pointed
* by the item passed and that is much faster than having * by the item passed and that is much faster than having
* to deal with return values especially when you'll be * to deal with return values especially when you'll be
* using complex data structures as item of the c_vector. * using complex data structures as item of the vector.
*/ */
void vect_apply(c_vector const v, void (*f1)(void *)); void vect_apply(c_vector const v, void (*f1)(void *));
/* /*
* vect_apply_if is a function that will apply "f1" C function * vect_apply_if is a function that will apply "f1" C function
* to each and every item in c_vector v1, IF the return value of * to each and every item in vector v1, IF the return value of
* function f2 is true. So it allows what is known as conditional * function f2 is true. So it allows what is known as conditional
* application. f2 will receive an item from v1 as first parameter * application. f2 will receive an item from v1 as first parameter
* and an item from v2 (at the same position of the item in v1) as * and an item from v2 (at the same position of the item in v1) as
@ -557,20 +570,22 @@ void vect_apply(c_vector const v, void (*f1)(void *));
*/ */
void vect_apply_if(c_vector const v1, c_vector const v2, void (*f1)(void *), bool (*f2)(void *, void *)); void vect_apply_if(c_vector const v1, c_vector const v2, void (*f1)(void *), bool (*f2)(void *, void *));
void vect_apply_range(c_vector const v, void (*f)(void *), const zvect_index x, const zvect_index y);
// Operations with multiple vectors: // Operations with multiple vectors:
/* /*
* vect_copy is a function that allows to copy a specified * vect_copy is a function that allows to copy a specified
* set of elements from a c_vector to another. * set of elements from a vector to another.
* Please note: only vectors with the same data size (the * Please note: only vectors with the same data size (the
* parameter we pass during the creation of both vectors) * parameter we pass during the creation of both vectors)
* can be copied into the other! * can be copied into the other!
* *
* vect_copy(v1, v2, 3, 5) will copy all the items in * vect_copy(v1, v2, 3, 5) will copy all the items in
* c_vector v2, from the 4th item * vector v2, from the 4th item
* till the 9th (3 + 5, remember * till the 9th (3 + 5, remember
* c_vector items start from 0) in * vector items start from 0) in
* the c_vector v1. So at the end * the vector v1. So at the end
* of the process you'll have such * of the process you'll have such
* items copied at the end of v1. * items copied at the end of v1.
*/ */
@ -578,17 +593,17 @@ void vect_copy(c_vector const v1, c_vector const v2, zvect_index start, zvect_in
/* /*
* vect_insert is a function that allows to copy a specified * vect_insert is a function that allows to copy a specified
* set of elements from a c_vector to another and "insert" * set of elements from a vector to another and "insert"
* them from a specified position in the destination c_vector. * them from a specified position in the destination vector.
* Please note: only vectors with the same data size (the * Please note: only vectors with the same data size (the
* parameter we pass during the creation of both vectors) * parameter we pass during the creation of both vectors)
* can be copied into the other! * can be copied into the other!
* *
* vect_insert(v1, v2, 3, 5, 7) will copy all the items in * vect_insert(v1, v2, 3, 5, 7) will copy all the items in
* c_vector v2, from the 4th item * vector v2, from the 4th item
* till the 9th (3 + 5, remember * till the 9th (3 + 5, remember
* c_vector items start from 0) in * vector items start from 0) in
* the c_vector v1 from position 7. * the vector v1 from position 7.
* So at the end of the process * So at the end of the process
* you'll have such items "inserted" * you'll have such items "inserted"
* inside v1. * inside v1.
@ -601,9 +616,9 @@ void vect_insert(c_vector const v1,
/* /*
* vect_move is a function that allows to move a specified * vect_move is a function that allows to move a specified
* set of items from one c_vector to another. * set of items from one vector to another.
* It will also re-organise the source c_vector and (obviously) * It will also re-organise the source vector and (obviously)
* expand the destination c_vector if needed. * expand the destination vector if needed.
* Please note: only vectors of the same data size can be moved * Please note: only vectors of the same data size can be moved
* one into the other! * one into the other!
* *
@ -615,11 +630,11 @@ void vect_move(c_vector const v1, c_vector const v2, zvect_index start, zvect_in
/* /*
* vect_move_if is a function that allows to move a specified * vect_move_if is a function that allows to move a specified
* set of items from one c_vector to another if the condition * set of items from one vector to another if the condition
* returned by the function pointed by f2 function pointer * returned by the function pointed by f2 function pointer
* is true. * is true.
* It will also re-organise the source c_vector and (obviously) * It will also re-organise the source vector and (obviously)
* expand the destination c_vector if needed. * expand the destination vector if needed.
* Please note: only vectors of the same data size can be moved * Please note: only vectors of the same data size can be moved
* one into the other! * one into the other!
* *
@ -637,9 +652,9 @@ zvect_retval vect_move_if(c_vector const v1,
/* /*
* vect_merge is a function that merges together 2 vectors of * vect_merge is a function that merges together 2 vectors of
* the same data size. At the end of the process, the source * the same data size. At the end of the process, the source
* c_vector will be destroyed. * vector will be destroyed.
* *
* vect_merge(v1, v2) will merge c_vector v2 to v1 and then * vect_merge(v1, v2) will merge vector v2 to v1 and then
* destroy v2. So at the end of the job * destroy v2. So at the end of the job
* v1 will contain the old v1 items + * v1 will contain the old v1 items +
* all v2 items. * all v2 items.

View File

@ -17,18 +17,20 @@
/* /*
* Few code standard notes: * Few code standard notes:
* *
* p_ <- indicate a PRIVATE method or variable. Not reachable outside this module. * p_ <- indicate a PRIVATE method or variable. Not reachable outside this
* module.
* *
*/ */
// Include standard C libs headers /* Include standard C libs headers */
#include <assert.h> #include <assert.h>
#include <stddef.h> #include <stddef.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
// Include vector.h header /* Include vector.h header */
#include "zvector/zvector.h" #include "zvector/zvector.h"
#include "misc.h"
#if (OS_TYPE == 1) #if (OS_TYPE == 1)
#if (!defined(macOS)) #if (!defined(macOS))
@ -105,16 +107,19 @@ enum {
// Useful macros // Useful macros
// # define min(x, y) (((x) < (y)) ? (x) : (y)) // # define min(x, y) (((x) < (y)) ? (x) : (y))
#define max(x, y) (((x) > (y)) ? (x) : (y)) #define max(x, y) (((x) > (y)) ? (x) : (y))
#ifndef UNUSED
#define UNUSED(x) (void)x #define UNUSED(x) (void)x
#endif
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
// Define the vector data structure: /* Define the vector data structure:
*
// This is ZVector core data structure, it is the structure of a ZVector vector :) * This is ZVector core data structure, it is the structure of a ZVector
// Please note: fields order is based on "most used fields" to help a bit with cache * vector :)
* Please note: fields order is based on "most used fields" to help a bit
* with cache
*/
struct ZVECT_PACKING p_vector { struct ZVECT_PACKING p_vector {
zvect_index cap_left; // - Max capacity allocated on the zvect_index cap_left; // - Max capacity allocated on the
// left. // left.
@ -189,6 +194,9 @@ struct ZVECT_PACKING p_vector {
#endif // ZVECT_THREAD_SAFE #endif // ZVECT_THREAD_SAFE
} ZVECT_DATAALIGN; } ZVECT_DATAALIGN;
// Internal representation of a vector
typedef struct p_vector *const ivector;
// Initialisation state: // Initialisation state:
static uint32_t p_init_state = 0; static uint32_t p_init_state = 0;
@ -219,8 +227,12 @@ unsigned int LOG_PRIORITY = (ZVLP_ERROR | ZVLP_HIGH | ZVLP_MEDIUM | ZVLP_LOW | Z
unsigned int LOG_PRIORITY = (ZVLP_ERROR | ZVLP_HIGH | ZVLP_MEDIUM); unsigned int LOG_PRIORITY = (ZVLP_ERROR | ZVLP_HIGH | ZVLP_MEDIUM);
#endif #endif
// Local declaration of private functions
void p_init_zvect(void);
zvect_retval p_vect_clear(ivector v);
// This is a vprintf wrapper nothing special: // This is a vprintf wrapper nothing special:
static void LOG_MOD(int const priority, const char *const format, ...) { static void log_msg(int const priority, const char *const format, ...) {
va_list args; va_list args;
va_start(args, format); va_start(args, format);
@ -262,9 +274,9 @@ static void *safe_strncpy(const char *const str_src, size_t max_len) {
str_dst = (void *)malloc(sizeof(char *) * (sizeof(tmp_dst) + 1)); str_dst = (void *)malloc(sizeof(char *) * (sizeof(tmp_dst) + 1));
if (str_dst == NULL) { if (str_dst == NULL) {
LOG_MOD(ZVLP_ERROR, "Error: %*i, %s\n", 8, -1000, "Out of memory!"); log_msg(ZVLP_ERROR, "Error: %*i, %s\n", 8, -1000, "Out of memory!");
} else { } else {
strncpy((char *)str_dst, tmp_dst, sizeof(char) * max_len); strncpy((char *)str_dst, tmp_dst, max_len);
} }
return str_dst; return str_dst;
} }
@ -276,7 +288,7 @@ static void
p_throw_error(const zvect_retval error_code, const char *error_message) { p_throw_error(const zvect_retval error_code, const char *error_message) {
int32_t locally_allocated = 0; int32_t locally_allocated = 0;
char *message = NULL; char *message = NULL;
unsigned long msg_len = 0; size_t msg_len = 0;
if (error_message == NULL) { if (error_message == NULL) {
msg_len = sizeof(char *) * 255; msg_len = sizeof(char *) * 255;
@ -288,13 +300,13 @@ p_throw_error(const zvect_retval error_code, const char *error_message) {
if (locally_allocated) { if (locally_allocated) {
switch (error_code) { switch (error_code) {
case ZVERR_VECTUNDEF: case ZVERR_VECTUNDEF:
message = (char *)safe_strncpy("Undefined or uninitialized c_vector.\n\0", msg_len); message = (char *)safe_strncpy("Undefined or uninitialized vector.\n\0", msg_len);
break; break;
case ZVERR_IDXOUTOFBOUND: case ZVERR_IDXOUTOFBOUND:
message = (char *)safe_strncpy("Index out of bound.\n\0", msg_len); message = (char *)safe_strncpy("Index out of bound.\n\0", msg_len);
break; break;
case ZVERR_OUTOFMEM: case ZVERR_OUTOFMEM:
message = (char *)safe_strncpy("Not enough memory to allocate space for the c_vector.\n\0", msg_len); message = (char *)safe_strncpy("Not enough memory to allocate space for the vector.\n\0", msg_len);
break; break;
case ZVERR_VECTCORRUPTED: case ZVERR_VECTCORRUPTED:
message = (char *)safe_strncpy("Vector corrupted.\n\0", msg_len); message = (char *)safe_strncpy("Vector corrupted.\n\0", msg_len);
@ -303,11 +315,12 @@ p_throw_error(const zvect_retval error_code, const char *error_message) {
message = (char *)safe_strncpy("Race condition detected, cannot continue.\n\0", msg_len); message = (char *)safe_strncpy("Race condition detected, cannot continue.\n\0", msg_len);
break; break;
case ZVERR_VECTTOOSMALL: case ZVERR_VECTTOOSMALL:
message = (char *)safe_strncpy("Destination c_vector is smaller than source.\n\0", msg_len); message = (char *)safe_strncpy("Destination vector is smaller than source.\n\0", msg_len);
break; break;
case ZVERR_VECTDATASIZE: case ZVERR_VECTDATASIZE:
message = (char *)safe_strncpy( message = (char *)safe_strncpy(
"This operation requires two (or more vectors) with the same data size.\n\0", "This operation requires two (or more "
"vectors) with the same data size.\n\0",
msg_len); msg_len);
break; break;
case ZVERR_VECTEMPTY: case ZVERR_VECTEMPTY:
@ -324,7 +337,7 @@ p_throw_error(const zvect_retval error_code, const char *error_message) {
message = (char *)safe_strncpy(error_message, msg_len); message = (char *)safe_strncpy(error_message, msg_len);
} }
LOG_MOD(ZVLP_ERROR, "Error: %*i, %s\n", 8, error_code, message); log_msg(ZVLP_ERROR, "Error: %*i, %s\n", 8, error_code, message);
if (locally_allocated) { if (locally_allocated) {
free((void *)message); free((void *)message);
} }
@ -374,9 +387,9 @@ static inline
ZVECT_ALWAYSINLINE ZVECT_ALWAYSINLINE
static inline void *p_vect_memmove(const void *__restrict dst, const void *__restrict src, size_t size) { static inline void *p_vect_memmove(const void *__restrict dst, const void *__restrict src, size_t size) {
#ifdef DEBUG #ifdef DEBUG
LOG_MOD(ZVLP_INFO, "p_vect_memmove: dst %*p\n", 14, dst); log_msg(ZVLP_INFO, "p_vect_memmove: dst %*p\n", 14, dst);
LOG_MOD(ZVLP_INFO, "p_vect_memmove: src %*p\n", 14, src); log_msg(ZVLP_INFO, "p_vect_memmove: src %*p\n", 14, src);
LOG_MOD(ZVLP_INFO, "p_vect_memmove: size %*u\n", 14, size); log_msg(ZVLP_INFO, "p_vect_memmove: size %*u\n", 14, size);
#endif #endif
return memmove((void *)dst, src, size); return memmove((void *)dst, src, size);
} }
@ -437,10 +450,14 @@ static inline void mutex_destroy(pthread_mutex_t *lock) {
static inline int semaphore_init static inline int semaphore_init
#if !defined(macOS) #if !defined(macOS)
(sem_t *sem, int value) { (sem_t *sem, int value)
#else
(dispatch_semaphore_t *sem, int value)
#endif
{
#if !defined(macOS)
return sem_init(sem, 0, value); return sem_init(sem, 0, value);
#else #else
(dispatch_semaphore_t *sem, int value) {
*sem = dispatch_semaphore_create(value); *sem = dispatch_semaphore_create(value);
return 0; return 0;
#endif #endif
@ -448,10 +465,14 @@ static inline int semaphore_init
static inline int semaphore_destroy static inline int semaphore_destroy
#if !defined(macOS) #if !defined(macOS)
(sem_t *sem) { (sem_t *sem)
#else
(dispatch_semaphore_t *sem)
#endif
{
#if !defined(macOS)
return sem_destroy(sem); return sem_destroy(sem);
#else #else
(dispatch_semaphore_t *sem) {
return 0; // dispatch_semaphore_destroy(sem); return 0; // dispatch_semaphore_destroy(sem);
(void)sem; (void)sem;
#endif #endif
@ -526,8 +547,8 @@ static inline zvect_retval lock_after_signal(const c_vector v, const int32_t loc
/* /*
* TODO: Write a generic function to allow user to use signals: * TODO: Write a generic function to allow user to use signals:
static inline zvect_retval wait_for_signal(const vector v, const int32_t lock_type, bool (*f1)(const vector v), ) { static inline zvect_retval wait_for_signal(const c_vector v, const int32_t
if (lock_type >= v->lock_type) { lock_type, bool (*f1)(const c_vector v), ) { if (lock_type >= v->lock_type) {
//if (!mutex_trylock(&(v->lock))) { //if (!mutex_trylock(&(v->lock))) {
while(!(*f1)(v)) { while(!(*f1)(v)) {
// wait until we get a signal // wait until we get a signal
@ -598,7 +619,7 @@ static inline zvect_index p_vect_size(const c_vector v) {
return (v->end > v->begin) ? (v->end - v->begin) : (v->begin - v->end); return (v->end > v->begin) ? (v->end - v->begin) : (v->begin - v->end);
} }
static inline void p_item_safewipe(c_vector const v, void *const item) { static inline void p_item_safewipe(ivector v, void *const item) {
if (item != NULL) { if (item != NULL) {
if (!(v->status & ZVS_CUST_WIPE_ON)) { if (!(v->status & ZVS_CUST_WIPE_ON)) {
memset(item, 0, v->data_size); memset(item, 0, v->data_size);
@ -627,7 +648,7 @@ bool vect_set_status(const c_vector v, zvect_index flag_id) {
zvect_retval rval = p_usr_status(flag_id); zvect_retval rval = p_usr_status(flag_id);
if (!rval) { if (!rval) {
v->status |= 1UL << flag_id; v->status |= 1 << flag_id;
} }
return (bool)rval; return (bool)rval;
@ -637,7 +658,7 @@ bool vect_clear_status(const c_vector v, zvect_index flag_id) {
zvect_retval rval = p_usr_status(flag_id); zvect_retval rval = p_usr_status(flag_id);
if (!rval) { if (!rval) {
v->status &= ~(1UL << flag_id); v->status &= ~(1 << flag_id);
} }
return (bool)rval; return (bool)rval;
@ -647,13 +668,13 @@ bool vect_toggle_status(const c_vector v, zvect_index flag_id) {
zvect_retval rval = p_usr_status(flag_id); zvect_retval rval = p_usr_status(flag_id);
if (!rval) { if (!rval) {
v->status ^= (1UL << flag_id); v->status ^= (1 << flag_id);
} }
return rval; return rval;
} }
static void p_free_items(c_vector const v, zvect_index first, zvect_index offset) { static void p_free_items(ivector v, zvect_index first, zvect_index offset) {
if (p_vect_size(v) == 0) { if (p_vect_size(v) == 0) {
return; return;
} }
@ -685,9 +706,7 @@ static void p_free_items(c_vector const v, zvect_index first, zvect_index offset
/* /*
* Set vector capacity to a specific new_capacity value * Set vector capacity to a specific new_capacity value
*/ */
static zvect_retval p_vect_set_capacity(c_vector const v, static zvect_retval p_vect_set_capacity(ivector v, const zvect_index direction, const zvect_index new_capacity_) {
const zvect_index direction,
const zvect_index new_capacity_) {
zvect_index new_capacity = new_capacity_; zvect_index new_capacity = new_capacity_;
if (new_capacity <= v->init_capacity) { if (new_capacity <= v->init_capacity) {
@ -741,7 +760,7 @@ static zvect_retval p_vect_set_capacity(c_vector const v,
/* /*
* This function increase the CAPACITY of a vector. * This function increase the CAPACITY of a vector.
*/ */
static zvect_retval p_vect_increase_capacity(c_vector const v, const zvect_index direction) { static zvect_retval p_vect_increase_capacity(ivector v, const zvect_index direction) {
zvect_index new_capacity; zvect_index new_capacity;
if (!direction) { if (!direction) {
@ -774,7 +793,7 @@ static zvect_retval p_vect_increase_capacity(c_vector const v, const zvect_index
/* /*
* This function decrease the CAPACITY of a vector. * This function decrease the CAPACITY of a vector.
*/ */
static zvect_retval p_vect_decrease_capacity(c_vector const v, const zvect_index direction) { static zvect_retval p_vect_decrease_capacity(ivector v, const zvect_index direction) {
// Check if new capacity is smaller than initial capacity // Check if new capacity is smaller than initial capacity
if (p_vect_capacity(v) <= v->init_capacity) { if (p_vect_capacity(v) <= v->init_capacity) {
return 0; return 0;
@ -849,7 +868,7 @@ static zvect_retval p_vect_decrease_capacity(c_vector const v, const zvect_index
* not its size. To reduce the size of a vector we * not its size. To reduce the size of a vector we
* need to remove items from it. * need to remove items from it.
*/ */
static zvect_retval p_vect_shrink(c_vector const v) { static zvect_retval p_vect_shrink(ivector v) {
if (v->init_capacity < 2) { if (v->init_capacity < 2) {
v->init_capacity = 2; v->init_capacity = 2;
} }
@ -867,8 +886,8 @@ static zvect_retval p_vect_shrink(c_vector const v) {
} }
// shrink the vector: // shrink the vector:
// Given that zvector supports vectors that can grow on the left and on the right // Given that zvector supports vectors that can grow on the left and on the
// I cannot use realloc here. // right I cannot use realloc here.
void **new_data = (void **)malloc(sizeof(void *) * new_capacity); void **new_data = (void **)malloc(sizeof(void *) * new_capacity);
if (new_data == NULL) { if (new_data == NULL) {
return ZVERR_OUTOFMEM; return ZVERR_OUTOFMEM;
@ -900,7 +919,7 @@ static zvect_retval p_vect_shrink(c_vector const v) {
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
// Creation and destruction primitives: // Creation and destruction primitives:
zvect_retval p_vect_clear(c_vector const v) { zvect_retval p_vect_clear(ivector v) {
// Clear the vector: // Clear the vector:
if (!vect_is_empty(v)) { if (!vect_is_empty(v)) {
p_free_items(v, 0, (p_vect_size(v) - 1)); p_free_items(v, 0, (p_vect_size(v) - 1));
@ -910,7 +929,8 @@ zvect_retval p_vect_clear(c_vector const v) {
v->begin = v->end = 0; v->begin = v->end = 0;
// Shrink Vector's capacity: // Shrink Vector's capacity:
// p_vect_shrink(v); // commented this out to make vect_clear behave more like the clear method in C++ // p_vect_shrink(v); // commented this out to make vect_clear behave more like
// the clear method in C++
return 0; return 0;
} }
@ -973,7 +993,7 @@ static zvect_retval p_vect_destroy(c_vector v, uint32_t flags) {
// Vector data storage primitives: // Vector data storage primitives:
// inline implementation for all put: // inline implementation for all put:
static inline zvect_retval p_vect_put_at(c_vector const v, const void *value, const zvect_index i) { static zvect_retval p_vect_put_at(ivector v, const void *value, const zvect_index i) {
// Check if the index passed is out of bounds: // Check if the index passed is out of bounds:
zvect_index idx = i; zvect_index idx = i;
if (!(v->flags & ZV_CIRCULAR)) { if (!(v->flags & ZV_CIRCULAR)) {
@ -1003,7 +1023,7 @@ static inline zvect_retval p_vect_put_at(c_vector const v, const void *value, co
} }
// inline implementation for all add(s): // inline implementation for all add(s):
static inline zvect_retval p_vect_add_at(c_vector const v, const void *value, const zvect_index i) { static inline zvect_retval p_vect_add_at(ivector v, const void *value, const zvect_index i) {
zvect_index idx = i; zvect_index idx = i;
// Get vector size: // Get vector size:
@ -1122,7 +1142,7 @@ static inline zvect_retval p_vect_add_at(c_vector const v, const void *value, co
} }
// This is the inline implementation for all the remove and pop // This is the inline implementation for all the remove and pop
static inline zvect_retval p_vect_remove_at(c_vector const v, const zvect_index i, void **item) { static inline zvect_retval p_vect_remove_at(ivector v, const zvect_index i, void **item) {
zvect_index idx = i; zvect_index idx = i;
// Get the vector size: // Get the vector size:
@ -1237,7 +1257,7 @@ static inline zvect_retval p_vect_remove_at(c_vector const v, const zvect_index
} }
// This is the inline implementation for all the "delete" methods // This is the inline implementation for all the "delete" methods
static inline zvect_retval p_vect_delete_at(c_vector const v, static inline zvect_retval p_vect_delete_at(ivector v,
const zvect_index start, const zvect_index start,
const zvect_index offset, const zvect_index offset,
uint32_t flags) { uint32_t flags) {
@ -1260,13 +1280,13 @@ static inline zvect_retval p_vect_delete_at(c_vector const v,
zvect_index tot_items = start + offset; zvect_index tot_items = start + offset;
#ifdef DEBUG #ifdef DEBUG
/* /*
LOG_MOD(ZVLP_INFO, "p_vect_delete_at: start %*u\n", 14, start); log_msg(ZVLP_INFO, "p_vect_delete_at: start %*u\n", 14, start);
LOG_MOD(ZVLP_INFO, "p_vect_delete_at: offset %*u\n", 14, offset); log_msg(ZVLP_INFO, "p_vect_delete_at: offset %*u\n", 14, offset);
LOG_MOD(ZVLP_INFO, "p_vect_delete_at: tot_items %*u\n", 14, tot_items); log_msg(ZVLP_INFO, "p_vect_delete_at: tot_items %*u\n", 14, tot_items);
LOG_MOD(ZVLP_INFO, "p_vect_delete_at: v->begin %*u\n", 14, v->begin); log_msg(ZVLP_INFO, "p_vect_delete_at: v->begin %*u\n", 14, v->begin);
LOG_MOD(ZVLP_INFO, "p_vect_delete_at: v->end %*u\n", 14, v->end); log_msg(ZVLP_INFO, "p_vect_delete_at: v->end %*u\n", 14, v->end);
LOG_MOD(ZVLP_INFO, "p_vect_delete_at: vsize %*u\n", 14, vsize); log_msg(ZVLP_INFO, "p_vect_delete_at: vsize %*u\n", 14, vsize);
LOG_MOD(ZVLP_INFO, "p_vect_delete_at: data %*p\n", 14, v->data); log_msg(ZVLP_INFO, "p_vect_delete_at: data %*p\n", 14, v->data);
*/ */
#endif #endif
if ((vsize > 1) && (start < (vsize - 1)) && (tot_items < vsize) && (v->data != NULL)) { if ((vsize > 1) && (start < (vsize - 1)) && (tot_items < vsize) && (v->data != NULL)) {
@ -1274,7 +1294,8 @@ static inline zvect_retval p_vect_delete_at(c_vector const v,
#ifdef DEBUG #ifdef DEBUG
/* for (zvect_index ptrID = start; ptrID < start + offset; ptrID++) /* for (zvect_index ptrID = start; ptrID < start + offset; ptrID++)
{ {
LOG_MOD(ZVLP_INFO, "p_vect_delete_at: data ptr %*p\n", 14, v->data + (v->begin + ptrID)); log_msg(ZVLP_INFO, "p_vect_delete_at: data ptr %*p\n", 14,
v->data + (v->begin + ptrID));
}*/ }*/
#endif #endif
// Safe erase items? // Safe erase items?
@ -1343,7 +1364,7 @@ static inline zvect_retval p_vect_delete_at(c_vector const v,
* Public method to request ZVector to * Public method to request ZVector to
* shrink a vector. * shrink a vector.
*/ */
void vect_shrink(c_vector const v) { void vect_shrink(ivector v) {
#if (ZVECT_THREAD_SAFE == 1) #if (ZVECT_THREAD_SAFE == 1)
zvect_retval lock_owner = get_mutex_lock(v, 1); zvect_retval lock_owner = get_mutex_lock(v, 1);
#endif #endif
@ -1365,23 +1386,24 @@ void vect_shrink(c_vector const v) {
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
// Vector Structural Information report: // Vector Structural Information report:
bool vect_is_empty(c_vector const v) { int vect_is_empty(ivector v) {
return !p_vect_check(v) ? (p_vect_size(v) == 0) : (bool)ZVERR_VECTUNDEF; return !p_vect_check(v) ? ((p_vect_size(v) == 0) ? TRUE : FALSE) : FALSE;
//return !p_vect_check(v) ? (p_vect_size(v) == 0) : (bool)ZVERR_VECTUNDEF;
} }
zvect_index vect_size(c_vector const v) { zvect_index vect_size(ivector v) {
return !p_vect_check(v) ? p_vect_size(v) : 0; return !p_vect_check(v) ? p_vect_size(v) : 0;
} }
zvect_index vect_max_size(c_vector const v) { zvect_index vect_max_size(ivector v) {
return !p_vect_check(v) ? zvect_index_max : 0; return (!p_vect_check(v) ? zvect_index_max : 0);
} }
void *vect_begin(c_vector const v) { void *vect_begin(ivector v) {
return !p_vect_check(v) ? v->data[v->begin] : NULL; return !p_vect_check(v) ? v->data[v->begin] : NULL;
} }
void *vect_end(c_vector const v) { void *vect_end(ivector v) {
return !p_vect_check(v) ? v->data[v->end] : NULL; return !p_vect_check(v) ? v->data[v->end] : NULL;
} }
@ -1490,27 +1512,27 @@ void vect_lock_disable(void) {
locking_disabled = true; locking_disabled = true;
} }
static inline zvect_retval p_vect_lock(c_vector const v) { static inline zvect_retval p_vect_lock(ivector v) {
return (locking_disabled || (v->flags & ZV_NOLOCKING)) ? 0 : get_mutex_lock(v, 3); return (locking_disabled || (v->flags & ZV_NOLOCKING)) ? 0 : get_mutex_lock(v, 3);
} }
zvect_retval vect_lock(c_vector const v) { zvect_retval vect_lock(ivector v) {
return p_vect_lock(v); return p_vect_lock(v);
} }
static inline zvect_retval p_vect_unlock(c_vector const v) { static inline zvect_retval p_vect_unlock(ivector v) {
return (locking_disabled || (v->flags & ZV_NOLOCKING)) ? 0 : get_mutex_unlock(v, 3); return (locking_disabled || (v->flags & ZV_NOLOCKING)) ? 0 : get_mutex_unlock(v, 3);
} }
zvect_retval vect_unlock(c_vector const v) { zvect_retval vect_unlock(ivector v) {
return p_vect_unlock(v); return p_vect_unlock(v);
} }
static inline zvect_retval p_vect_trylock(c_vector const v) { static inline zvect_retval p_vect_trylock(ivector v) {
return (locking_disabled || (v->flags & ZV_NOLOCKING)) ? 0 : check_mutex_trylock(v, 3); return (locking_disabled || (v->flags & ZV_NOLOCKING)) ? 0 : check_mutex_trylock(v, 3);
} }
zvect_retval vect_trylock(c_vector const v) { zvect_retval vect_trylock(ivector v) {
return p_vect_trylock(v); return p_vect_trylock(v);
} }
@ -1531,11 +1553,12 @@ zvect_retval vect_sem_post(const c_vector v) {
} }
/* /*
static inline zvect_retval p_vect_wait_for_signal(const vector v) { static inline zvect_retval p_vect_wait_for_signal(const c_vector v) {
return (locking_disabled || (v->flags & ZV_NOLOCKING)) ? 1 : wait_for_signal(v, 3); return (locking_disabled || (v->flags & ZV_NOLOCKING)) ? 1 :
wait_for_signal(v, 3);
} }
inline zvect_retval vect_wait_for_signal(const vector v) { inline zvect_retval vect_wait_for_signal(const c_vector v) {
return p_vect_wait_for_signal(v); return p_vect_wait_for_signal(v);
} }
*/ */
@ -1563,7 +1586,7 @@ zvect_retval vect_broadcast_signal(const c_vector v) {
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
// Vector Data Storage functions: // Vector Data Storage functions:
void vect_clear(c_vector const v) { void vect_clear(ivector v) {
// check if the vector exists: // check if the vector exists:
zvect_retval rval = p_vect_check(v); zvect_retval rval = p_vect_check(v);
if (rval) { if (rval) {
@ -1590,10 +1613,9 @@ JOB_DONE:
} }
void vect_set_wipefunct(const c_vector v, void (*f1)(const void *, size_t)) { void vect_set_wipefunct(const c_vector v, void (*f1)(const void *, size_t)) {
v->SfWpFunc = (void *)malloc(sizeof(void *)); // v->SfWpFunc = (void *)malloc(sizeof(void *));
if (v->SfWpFunc == NULL) { // if (v->SfWpFunc == NULL)
p_throw_error(ZVERR_OUTOFMEM, NULL); // p_throw_error(ZVERR_OUTOFMEM, NULL);
}
// Set custom Safe Wipe function: // Set custom Safe Wipe function:
v->SfWpFunc = f1; v->SfWpFunc = f1;
@ -1602,7 +1624,8 @@ void vect_set_wipefunct(const c_vector v, void (*f1)(const void *, size_t)) {
} }
// Add an item at the END (top) of the vector // Add an item at the END (top) of the vector
inline void vect_push(const c_vector v, const void *value) { void vect_push(const c_vector v, const void *value) {
zvect_index vsize = 0;
zvect_retval rval = p_vect_check(v); zvect_retval rval = p_vect_check(v);
if (rval) { if (rval) {
goto JOB_DONE; goto JOB_DONE;
@ -1625,7 +1648,7 @@ inline void vect_push(const c_vector v, const void *value) {
// push will use index 0 and the rule in ZVector is // push will use index 0 and the rule in ZVector is
// when we use index 0 we may need to expand on the // when we use index 0 we may need to expand on the
// left. So let's check if we do for this vector: // left. So let's check if we do for this vector:
zvect_index vsize = p_vect_size(v); vsize = p_vect_size(v);
// Check if we need to expand on thr right side: // Check if we need to expand on thr right side:
if ((v->end >= v->cap_right) && ((rval = p_vect_increase_capacity(v, 1)) != 0)) { if ((v->end >= v->cap_right) && ((rval = p_vect_increase_capacity(v, 1)) != 0)) {
@ -1703,7 +1726,7 @@ JOB_DONE:
} }
// Add an item at the FRONT of the vector // Add an item at the FRONT of the vector
void vect_add_front(c_vector const v, const void *value) { void vect_add_front(ivector v, const void *value) {
zvect_retval rval = p_vect_check(v); zvect_retval rval = p_vect_check(v);
if (rval) { if (rval) {
goto JOB_DONE; goto JOB_DONE;
@ -1741,7 +1764,7 @@ JOB_DONE:
} }
// inline implementation for all get(s): // inline implementation for all get(s):
static inline void *p_vect_get_at(c_vector const v, const zvect_index i) { static inline void *p_vect_get_at(ivector v, const zvect_index i) {
// Check if passed index is out of bounds: // Check if passed index is out of bounds:
if (i >= p_vect_size(v)) { if (i >= p_vect_size(v)) {
p_throw_error(ZVERR_IDXOUTOFBOUND, NULL); p_throw_error(ZVERR_IDXOUTOFBOUND, NULL);
@ -1751,7 +1774,7 @@ static inline void *p_vect_get_at(c_vector const v, const zvect_index i) {
return v->data[v->begin + i]; return v->data[v->begin + i];
} }
void *vect_get(c_vector const v) { void *vect_get(ivector v) {
// check if the vector exists: // check if the vector exists:
zvect_retval rval = p_vect_check(v); zvect_retval rval = p_vect_check(v);
if (!rval) { if (!rval) {
@ -1763,7 +1786,7 @@ void *vect_get(c_vector const v) {
return NULL; return NULL;
} }
void *vect_get_at(c_vector const v, const zvect_index i) { void *vect_get_at(ivector v, const zvect_index i) {
// check if the vector exists: // check if the vector exists:
zvect_retval rval = p_vect_check(v); zvect_retval rval = p_vect_check(v);
if (!rval) { if (!rval) {
@ -1775,7 +1798,7 @@ void *vect_get_at(c_vector const v, const zvect_index i) {
return NULL; return NULL;
} }
void *vect_get_front(c_vector const v) { void *vect_get_front(ivector v) {
// check if the vector exists: // check if the vector exists:
zvect_retval rval = p_vect_check(v); zvect_retval rval = p_vect_check(v);
if (!rval) { if (!rval) {
@ -1787,7 +1810,7 @@ void *vect_get_front(c_vector const v) {
return NULL; return NULL;
} }
void vect_put(c_vector const v, const void *value) { void vect_put(ivector v, const void *value) {
zvect_retval rval = p_vect_check(v); zvect_retval rval = p_vect_check(v);
if (rval) { if (rval) {
goto JOB_DONE; goto JOB_DONE;
@ -1811,7 +1834,7 @@ JOB_DONE:
} }
} }
void vect_put_at(c_vector const v, const void *value, const zvect_index i) { void vect_put_at(ivector v, const void *value, const zvect_index i) {
zvect_retval rval = p_vect_check(v); zvect_retval rval = p_vect_check(v);
if (rval) { if (rval) {
goto JOB_DONE; goto JOB_DONE;
@ -1835,7 +1858,7 @@ JOB_DONE:
} }
} }
void vect_put_front(c_vector const v, const void *value) { void vect_put_front(ivector v, const void *value) {
zvect_retval rval = p_vect_check(v); zvect_retval rval = p_vect_check(v);
if (rval) { if (rval) {
goto JOB_DONE; goto JOB_DONE;
@ -1859,7 +1882,7 @@ JOB_DONE:
} }
} }
inline void *vect_pop(c_vector const v) { void *vect_pop(ivector v) {
void *item = NULL; void *item = NULL;
zvect_retval rval = p_vect_check(v); zvect_retval rval = p_vect_check(v);
if (rval) { if (rval) {
@ -1889,7 +1912,7 @@ JOB_DONE:
return item; return item;
} }
void *vect_remove(c_vector const v) { void *vect_remove(ivector v) {
void *item = NULL; void *item = NULL;
zvect_retval rval = p_vect_check(v); zvect_retval rval = p_vect_check(v);
if (rval) { if (rval) {
@ -1919,7 +1942,7 @@ JOB_DONE:
return item; return item;
} }
void *vect_remove_at(c_vector const v, const zvect_index i) { void *vect_remove_at(ivector v, const zvect_index i) {
void *item = NULL; void *item = NULL;
zvect_retval rval = p_vect_check(v); zvect_retval rval = p_vect_check(v);
if (rval) { if (rval) {
@ -1948,7 +1971,7 @@ JOB_DONE:
return item; return item;
} }
void *vect_remove_front(c_vector const v) { void *vect_remove_front(ivector v) {
void *item = NULL; void *item = NULL;
zvect_retval rval = p_vect_check(v); zvect_retval rval = p_vect_check(v);
if (rval) { if (rval) {
@ -1978,7 +2001,7 @@ JOB_DONE:
} }
// Delete an item at the END of the vector // Delete an item at the END of the vector
void vect_delete(c_vector const v) { void vect_delete(ivector v) {
zvect_retval rval = p_vect_check(v); zvect_retval rval = p_vect_check(v);
if (rval) { if (rval) {
goto JOB_DONE; goto JOB_DONE;
@ -2027,8 +2050,9 @@ JOB_DONE:
} }
} }
// Delete a range of items from "first_element" to "last_element" on the vector v // Delete a range of items from "first_element" to "last_element" on the vector
void vect_delete_range(c_vector const v, const zvect_index first_element, const zvect_index last_element) { // v
void vect_delete_range(ivector v, const zvect_index first_element, const zvect_index last_element) {
zvect_retval rval = p_vect_check(v); zvect_retval rval = p_vect_check(v);
if (rval) { if (rval) {
goto JOB_DONE; goto JOB_DONE;
@ -2054,7 +2078,7 @@ JOB_DONE:
} }
// Delete an item at the BEGINNING of a vector v // Delete an item at the BEGINNING of a vector v
void vect_delete_front(c_vector const v) { void vect_delete_front(ivector v) {
zvect_retval rval = p_vect_check(v); zvect_retval rval = p_vect_check(v);
if (rval) { if (rval) {
goto JOB_DONE; goto JOB_DONE;
@ -2084,7 +2108,7 @@ JOB_DONE:
// Vector Data Manipulation functions // Vector Data Manipulation functions
#ifdef ZVECT_DMF_EXTENSIONS #ifdef ZVECT_DMF_EXTENSIONS
void vect_swap(c_vector const v, const zvect_index i1, const zvect_index i2) { void vect_swap(ivector v, const zvect_index i1, const zvect_index i2) {
// Check parameters: // Check parameters:
if (i1 == i2) { if (i1 == i2) {
return; return;
@ -2125,7 +2149,7 @@ JOB_DONE:
} }
} }
void vect_swap_range(c_vector const v, const zvect_index s1, const zvect_index e1, const zvect_index s2) { void vect_swap_range(ivector v, const zvect_index s1, const zvect_index e1, const zvect_index s2) {
// Check parameters: // Check parameters:
if (s1 == s2) { if (s1 == s2) {
return; return;
@ -2174,7 +2198,7 @@ JOB_DONE:
} }
} }
void vect_rotate_left(c_vector const v, const zvect_index i) { void vect_rotate_left(ivector v, const zvect_index i) {
// check if the vector exists: // check if the vector exists:
zvect_retval rval = p_vect_check(v); zvect_retval rval = p_vect_check(v);
@ -2230,7 +2254,7 @@ JOB_DONE:
} }
} }
void vect_rotate_right(c_vector const v, const zvect_index i) { void vect_rotate_right(ivector v, const zvect_index i) {
// check if the vector exists: // check if the vector exists:
zvect_retval rval = p_vect_check(v); zvect_retval rval = p_vect_check(v);
if (rval) { if (rval) {
@ -2287,7 +2311,7 @@ JOB_DONE:
} }
#ifdef TRADITIONAL_QSORT #ifdef TRADITIONAL_QSORT
static inline zvect_index p_partition(vector v, static inline zvect_index p_partition(c_vector v,
zvect_index low, zvect_index low,
zvect_index high, zvect_index high,
int (*compare_func)(const void *, const void *)) { int (*compare_func)(const void *, const void *)) {
@ -2309,7 +2333,10 @@ static inline zvect_index p_partition(vector v,
return (i + 1); return (i + 1);
} }
static void p_vect_qsort(vector v, zvect_index low, zvect_index high, int (*compare_func)(const void *, const void *)) { static void p_vect_qsort(c_vector v,
zvect_index low,
zvect_index high,
int (*compare_func)(const void *, const void *)) {
if (low < high) { if (low < high) {
zvect_index pi = p_partition(v, low, high, compare_func); zvect_index pi = p_partition(v, low, high, compare_func);
p_vect_qsort(v, low, pi - 1, compare_func); p_vect_qsort(v, low, pi - 1, compare_func);
@ -2423,7 +2450,7 @@ JOB_DONE:
} }
#ifdef TRADITIONAL_BINARY_SEARCH #ifdef TRADITIONAL_BINARY_SEARCH
static bool p_standard_binary_search(vector v, static bool p_standard_binary_search(c_vector v,
const void *key, const void *key,
zvect_index *item_index, zvect_index *item_index,
int (*f1)(const void *, const void *)) { int (*f1)(const void *, const void *)) {
@ -2461,7 +2488,7 @@ static bool p_standard_binary_search(vector v,
// original design, most notably the use of custom compare // original design, most notably the use of custom compare
// function that makes it suitable also to search through strings // function that makes it suitable also to search through strings
// and other types of vectors. // and other types of vectors.
static bool p_adaptive_binary_search(c_vector const v, static bool p_adaptive_binary_search(ivector v,
const void *key, const void *key,
zvect_index *item_index, zvect_index *item_index,
int (*f1)(const void *, const void *)) { int (*f1)(const void *, const void *)) {
@ -2540,7 +2567,7 @@ MONOBOUND:
} }
#endif // ! TRADITIONAL_BINARY_SEARCH #endif // ! TRADITIONAL_BINARY_SEARCH
bool vect_bsearch(c_vector const v, const void *key, int (*f1)(const void *, const void *), zvect_index *item_index) { bool vect_bsearch(ivector v, const void *key, int (*f1)(const void *, const void *), zvect_index *item_index) {
// Check parameters: // Check parameters:
if ((key == NULL) || (f1 == NULL) || (p_vect_size(v) == 0)) { if ((key == NULL) || (f1 == NULL) || (p_vect_size(v) == 0)) {
return false; return false;
@ -2588,7 +2615,7 @@ JOB_DONE:
* functions, the vect_add_ordered is an exception because it * functions, the vect_add_ordered is an exception because it
* requires vect_bserach and vect_qsort to be available. * requires vect_bserach and vect_qsort to be available.
*/ */
void vect_add_ordered(c_vector const v, const void *value, int (*f1)(const void *, const void *)) { void vect_add_ordered(ivector v, const void *value, int (*f1)(const void *, const void *)) {
// Check parameters: // Check parameters:
if (value == NULL) { if (value == NULL) {
return; return;
@ -2658,7 +2685,7 @@ JOB_DONE:
#ifdef ZVECT_SFMD_EXTENSIONS #ifdef ZVECT_SFMD_EXTENSIONS
// Single Function Call Multiple Data operations extensions: // Single Function Call Multiple Data operations extensions:
void vect_apply(c_vector const v, void (*f)(void *)) { void vect_apply(ivector v, void (*f)(void *)) {
// Check Parameters: // Check Parameters:
if (f == NULL) { if (f == NULL) {
return; return;
@ -2691,7 +2718,7 @@ JOB_DONE:
} }
} }
void vect_apply_range(c_vector const v, void (*f)(void *), const zvect_index x, const zvect_index y) { void vect_apply_range(ivector v, void (*f)(void *), const zvect_index x, const zvect_index y) {
// Check parameters: // Check parameters:
if (f == NULL) { if (f == NULL) {
return; return;
@ -2740,7 +2767,7 @@ JOB_DONE:
} }
} }
void vect_apply_if(c_vector const v1, c_vector const v2, void (*f1)(void *), bool (*f2)(void *, void *)) { void vect_apply_if(ivector v1, ivector v2, void (*f1)(void *), bool (*f2)(void *, void *)) {
// Check parameters: // Check parameters:
if (f1 == NULL || f2 == NULL) { if (f1 == NULL || f2 == NULL) {
return; return;
@ -2782,7 +2809,7 @@ JOB_DONE:
} }
} }
void vect_copy(c_vector const v1, c_vector const v2, const zvect_index s2, const zvect_index e2) { void vect_copy(ivector v1, ivector v2, const zvect_index s2, const zvect_index e2) {
// check if the vectors v1 and v2 exist: // check if the vectors v1 and v2 exist:
zvect_retval rval = p_vect_check(v1) | p_vect_check(v2); zvect_retval rval = p_vect_check(v1) | p_vect_check(v2);
if (rval) { if (rval) {
@ -2846,11 +2873,7 @@ JOB_DONE:
* position s1). * position s1).
* *
*/ */
void vect_insert(c_vector const v1, void vect_insert(ivector v1, ivector v2, const zvect_index s2, const zvect_index e2, const zvect_index s1) {
c_vector const v2,
const zvect_index s2,
const zvect_index e2,
const zvect_index s1) {
// check if the vectors v1 and v2 exist: // check if the vectors v1 and v2 exist:
zvect_retval rval = p_vect_check(v1) | p_vect_check(v2); zvect_retval rval = p_vect_check(v1) | p_vect_check(v2);
if (rval) { if (rval) {
@ -2949,11 +2972,11 @@ JOB_DONE:
* the end of it). * the end of it).
* *
*/ */
static inline zvect_retval p_vect_move(c_vector const v1, c_vector v2, const zvect_index s2, const zvect_index e2) { static inline zvect_retval p_vect_move(ivector v1, c_vector v2, const zvect_index s2, const zvect_index e2) {
zvect_retval rval = 0; zvect_retval rval = 0;
#ifdef DEBUG #ifdef DEBUG
LOG_MOD(ZVLP_INFO, "p_vect_move: move pointers set from v2 to v1\n"); log_msg(ZVLP_INFO, "p_vect_move: move pointers set from v2 to v1\n");
#endif #endif
// We can only copy vectors with the same data_size! // We can only copy vectors with the same data_size!
if (v1->data_size != v2->data_size) { if (v1->data_size != v2->data_size) {
@ -2977,8 +3000,9 @@ static inline zvect_retval p_vect_move(c_vector const v1, c_vector v2, const zve
} }
#ifdef DEBUG #ifdef DEBUG
LOG_MOD(ZVLP_INFO, log_msg(ZVLP_INFO,
"p_vect_move: v2 capacity = %*u, begin = %*u, end = %*u, size = %*u, s2 = %*u, ee2 = %*u\n", "p_vect_move: v2 capacity = %*u, begin = %*u, end = %*u, size = %*u, "
"s2 = %*u, ee2 = %*u\n",
10, 10,
p_vect_capacity(v2), p_vect_capacity(v2),
10, 10,
@ -2992,7 +3016,7 @@ static inline zvect_retval p_vect_move(c_vector const v1, c_vector v2, const zve
10, 10,
ee2); ee2);
LOG_MOD(ZVLP_INFO, log_msg(ZVLP_INFO,
"p_vect_move: v1 capacity = %*u, begin = %*u, end = %*u, size = %*u\n", "p_vect_move: v1 capacity = %*u, begin = %*u, end = %*u, size = %*u\n",
10, 10,
p_vect_capacity(v1), p_vect_capacity(v1),
@ -3010,7 +3034,7 @@ static inline zvect_retval p_vect_move(c_vector const v1, c_vector v2, const zve
} }
#ifdef DEBUG #ifdef DEBUG
LOG_MOD(ZVLP_INFO, log_msg(ZVLP_INFO,
"p_vect_move: v1 capacity = %*u, begin = %*u, end = %*u, size = %*u\n", "p_vect_move: v1 capacity = %*u, begin = %*u, end = %*u, size = %*u\n",
10, 10,
p_vect_capacity(v1), p_vect_capacity(v1),
@ -3021,7 +3045,7 @@ static inline zvect_retval p_vect_move(c_vector const v1, c_vector v2, const zve
10, 10,
p_vect_size(v1)); p_vect_size(v1));
LOG_MOD(ZVLP_INFO, "p_vect_move: ready to copy pointers set\n"); log_msg(ZVLP_INFO, "p_vect_move: ready to copy pointers set\n");
#endif #endif
// Move v2 (from s2) in v1 at the end of v1: // Move v2 (from s2) in v1 at the end of v1:
const void *rptr = NULL; const void *rptr = NULL;
@ -3044,7 +3068,7 @@ static inline zvect_retval p_vect_move(c_vector const v1, c_vector v2, const zve
v1->end += ee2; v1->end += ee2;
#ifdef DEBUG #ifdef DEBUG
LOG_MOD(ZVLP_INFO, "p_vect_move: done copy pointers set\n"); log_msg(ZVLP_INFO, "p_vect_move: done copy pointers set\n");
#endif #endif
// Clean up v2 memory slots that no longer belong to v2: // Clean up v2 memory slots that no longer belong to v2:
@ -3052,7 +3076,7 @@ static inline zvect_retval p_vect_move(c_vector const v1, c_vector v2, const zve
DONE_PROCESSING: DONE_PROCESSING:
#ifdef DEBUG #ifdef DEBUG
LOG_MOD(ZVLP_INFO, log_msg(ZVLP_INFO,
"p_vect_move: v1 capacity = %*u, begin = %*u, end = %*u, size = %*u\n", "p_vect_move: v1 capacity = %*u, begin = %*u, end = %*u, size = %*u\n",
10, 10,
p_vect_capacity(v1), p_vect_capacity(v1),
@ -3062,7 +3086,7 @@ DONE_PROCESSING:
v1->end, v1->end,
10, 10,
p_vect_size(v1)); p_vect_size(v1));
LOG_MOD(ZVLP_INFO, log_msg(ZVLP_INFO,
"p_vect_move: v2 capacity = %*u, begin = %*u, end = %*u, size = %*u\n", "p_vect_move: v2 capacity = %*u, begin = %*u, end = %*u, size = %*u\n",
10, 10,
p_vect_capacity(v2), p_vect_capacity(v2),
@ -3082,7 +3106,7 @@ DONE_PROCESSING:
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
// vect_move moves a portion of a vector (v2) into another (v1): // vect_move moves a portion of a vector (v2) into another (v1):
void vect_move(c_vector const v1, c_vector v2, const zvect_index s2, const zvect_index e2) { void vect_move(ivector v1, c_vector v2, const zvect_index s2, const zvect_index e2) {
// check if the vectors v1 and v2 exist: // check if the vectors v1 and v2 exist:
zvect_retval rval = p_vect_check(v1) | p_vect_check(v2); zvect_retval rval = p_vect_check(v1) | p_vect_check(v2);
if (rval) { if (rval) {
@ -3095,10 +3119,10 @@ void vect_move(c_vector const v1, c_vector v2, const zvect_index s2, const zvect
zvect_retval lock_owner1 = (locking_disabled || (v1->flags & ZV_NOLOCKING)) ? 0 : get_mutex_lock(v1, 1); zvect_retval lock_owner1 = (locking_disabled || (v1->flags & ZV_NOLOCKING)) ? 0 : get_mutex_lock(v1, 1);
#endif #endif
#ifdef DEBUG #ifdef DEBUG
LOG_MOD(ZVLP_INFO, "vect_move: --- begin ---\n"); log_msg(ZVLP_INFO, "vect_move: --- begin ---\n");
#if (ZVECT_THREAD_SAFE == 1) #if (ZVECT_THREAD_SAFE == 1)
LOG_MOD(ZVLP_INFO, "vect_move: lock_owner1 for vector v1: %*u\n", 10, lock_owner1); log_msg(ZVLP_INFO, "vect_move: lock_owner1 for vector v1: %*u\n", 10, lock_owner1);
LOG_MOD(ZVLP_INFO, "vect_move: lock_owner2 for vector v2: %*u\n", 10, lock_owner2); log_msg(ZVLP_INFO, "vect_move: lock_owner2 for vector v2: %*u\n", 10, lock_owner2);
#endif // ZVECT_THREAD_SAFE #endif // ZVECT_THREAD_SAFE
#endif #endif
@ -3123,7 +3147,7 @@ DONE_PROCESSING:
} }
#endif #endif
#ifdef DEBUG #ifdef DEBUG
LOG_MOD(ZVLP_INFO, "vect_move: --- end ---\n"); log_msg(ZVLP_INFO, "vect_move: --- end ---\n");
#endif #endif
JOB_DONE: JOB_DONE:
@ -3135,8 +3159,9 @@ JOB_DONE:
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
// vect_move_if moves a portion of a vector (v2) into another (v1) if f2 is true: // vect_move_if moves a portion of a vector (v2) into another (v1) if f2 is
zvect_retval vect_move_if(c_vector const v1, // true:
zvect_retval vect_move_if(ivector v1,
c_vector v2, c_vector v2,
const zvect_index s2, const zvect_index s2,
const zvect_index e2, const zvect_index e2,
@ -3153,10 +3178,10 @@ zvect_retval vect_move_if(c_vector const v1,
zvect_retval lock_owner1 = (locking_disabled || (v1->flags & ZV_NOLOCKING)) ? 0 : get_mutex_lock(v1, 1); zvect_retval lock_owner1 = (locking_disabled || (v1->flags & ZV_NOLOCKING)) ? 0 : get_mutex_lock(v1, 1);
#endif #endif
#ifdef DEBUG #ifdef DEBUG
LOG_MOD(ZVLP_INFO, "vect_move_if: --- begin ---\n"); log_msg(ZVLP_INFO, "vect_move_if: --- begin ---\n");
#if (ZVECT_THREAD_SAFE == 1) #if (ZVECT_THREAD_SAFE == 1)
LOG_MOD(ZVLP_INFO, "vect_move_if: lock_owner1 for vector v1: %*u\n", 10, lock_owner1); log_msg(ZVLP_INFO, "vect_move_if: lock_owner1 for vector v1: %*u\n", 10, lock_owner1);
LOG_MOD(ZVLP_INFO, "vect_move_if: lock_owner2 for vector v2: %*u\n", 10, lock_owner2); log_msg(ZVLP_INFO, "vect_move_if: lock_owner2 for vector v2: %*u\n", 10, lock_owner2);
#endif // ZVECT_THREAD_SAFE #endif // ZVECT_THREAD_SAFE
#endif #endif
@ -3181,7 +3206,7 @@ DONE_PROCESSING:
} }
#endif #endif
#ifdef DEBUG #ifdef DEBUG
LOG_MOD(ZVLP_INFO, "vect_move_if: --- end ---\n"); log_msg(ZVLP_INFO, "vect_move_if: --- end ---\n");
#endif #endif
JOB_DONE: JOB_DONE:
@ -3198,7 +3223,7 @@ JOB_DONE:
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// vect_move_on_signal // vect_move_on_signal
zvect_retval vect_move_on_signal(c_vector const v1, zvect_retval vect_move_on_signal(ivector v1,
c_vector v2, c_vector v2,
const zvect_index s2, const zvect_index s2,
const zvect_index e2, const zvect_index e2,
@ -3215,44 +3240,44 @@ zvect_retval vect_move_on_signal(c_vector const v1,
zvect_retval lock_owner1 = (locking_disabled || (v1->flags & ZV_NOLOCKING)) ? 0 : get_mutex_lock(v1, 1); zvect_retval lock_owner1 = (locking_disabled || (v1->flags & ZV_NOLOCKING)) ? 0 : get_mutex_lock(v1, 1);
#ifdef DEBUG #ifdef DEBUG
LOG_MOD(ZVLP_MEDIUM, "vect_move_on_signal: --- start waiting ---\n"); log_msg(ZVLP_MEDIUM, "vect_move_on_signal: --- start waiting ---\n");
#endif #endif
// wait until we get a signal // wait until we get a signal
while (!(*f2)(v1, v2) && !(v2->status && (bool)ZVS_USR1_FLAG)) { while (!(*f2)(v1, v2) && !(v2->status)) {
pthread_cond_wait(&(v2->cond), &(v2->lock)); pthread_cond_wait(&(v2->cond), &(v2->lock));
} }
v2->status &= ~(ZVS_USR1_FLAG); v2->status &= ~(ZVS_USR1_FLAG);
// v2->status |= ZVS_USR_FLAG; // v2->status |= ZVS_USR_FLAG;
#ifdef DEBUG #ifdef DEBUG
LOG_MOD(ZVLP_MEDIUM, "Set status flag: %*i\n", 10, vect_check_status(v2, 1)); log_msg(ZVLP_MEDIUM, "Set status flag: %*i\n", 10, vect_check_status(v2, 1));
LOG_MOD(ZVLP_MEDIUM, "vect_move_on_signal: --- received signal ---\n"); log_msg(ZVLP_MEDIUM, "vect_move_on_signal: --- received signal ---\n");
LOG_MOD(ZVLP_MEDIUM, "vect_move_on_signal: --- begin ---\n"); log_msg(ZVLP_MEDIUM, "vect_move_on_signal: --- begin ---\n");
#endif #endif
// Proceed with move items: // Proceed with move items:
rval = p_vect_move(v1, v2, s2, e2); rval = p_vect_move(v1, v2, s2, e2);
#ifdef DEBUG #ifdef DEBUG
LOG_MOD(ZVLP_MEDIUM, "vect_move_on_signal: --- end ---\n"); log_msg(ZVLP_MEDIUM, "vect_move_on_signal: --- end ---\n");
#endif #endif
v2->status &= ~(ZVS_USR1_FLAG); v2->status &= ~(ZVS_USR1_FLAG);
#ifdef DEBUG #ifdef DEBUG
LOG_MOD(ZVLP_MEDIUM, "Reset status flag: %*i\n", 10, vect_check_status(v2, 1)); log_msg(ZVLP_MEDIUM, "Reset status flag: %*i\n", 10, vect_check_status(v2, 1));
#endif #endif
// DONE_PROCESSING: // DONE_PROCESSING:
#ifdef DEBUG #ifdef DEBUG
LOG_MOD(ZVLP_MEDIUM, "v1 owner? %*i\n", 10, lock_owner1); log_msg(ZVLP_MEDIUM, "v1 owner? %*i\n", 10, lock_owner1);
#endif #endif
if (lock_owner1) { if (lock_owner1) {
get_mutex_unlock(v1, 1); get_mutex_unlock(v1, 1);
} }
#ifdef DEBUG #ifdef DEBUG
LOG_MOD(ZVLP_MEDIUM, "v2 owner? %*i\n", 10, lock_owner2); log_msg(ZVLP_MEDIUM, "v2 owner? %*i\n", 10, lock_owner2);
#endif #endif
rval = p_vect_delete_at(v2, s2, e2 - 1, 0); rval = p_vect_delete_at(v2, s2, e2 - 1, 0);
if (lock_owner2) { if (lock_owner2) {
@ -3271,7 +3296,7 @@ JOB_DONE:
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// vect_merge merges a vector (v2) into another (v1) // vect_merge merges a vector (v2) into another (v1)
void vect_merge(c_vector const v1, c_vector v2) { void vect_merge(ivector v1, c_vector v2) {
// check if the vector v1 exists: // check if the vector v1 exists:
zvect_retval rval = p_vect_check(v1) | p_vect_check(v2); zvect_retval rval = p_vect_check(v1) | p_vect_check(v2);
if (rval) { if (rval) {
@ -3284,10 +3309,10 @@ void vect_merge(c_vector const v1, c_vector v2) {
#endif #endif
#ifdef DEBUG #ifdef DEBUG
LOG_MOD(ZVLP_INFO, "vect_merge: --- begin ---\n"); log_msg(ZVLP_INFO, "vect_merge: --- begin ---\n");
#if (ZVECT_THREAD_SAFE == 1) #if (ZVECT_THREAD_SAFE == 1)
LOG_MOD(ZVLP_INFO, "vect_merge: lock_owner1 for vector v1: %*u\n", 10, lock_owner1); log_msg(ZVLP_INFO, "vect_merge: lock_owner1 for vector v1: %*u\n", 10, lock_owner1);
LOG_MOD(ZVLP_INFO, "vect_merge: lock_owner2 for vector v2: %*u\n", 10, lock_owner2); log_msg(ZVLP_INFO, "vect_merge: lock_owner2 for vector v2: %*u\n", 10, lock_owner2);
#endif // ZVECT_THREAD_SAFE #endif // ZVECT_THREAD_SAFE
#endif // DEBUG #endif // DEBUG
@ -3304,7 +3329,7 @@ void vect_merge(c_vector const v1, c_vector v2) {
} }
#ifdef DEBUG #ifdef DEBUG
LOG_MOD(ZVLP_INFO, log_msg(ZVLP_INFO,
"vect_merge: v2 capacity = %*u, begin = %*u, end: %*u, size = %*u\n", "vect_merge: v2 capacity = %*u, begin = %*u, end: %*u, size = %*u\n",
10, 10,
p_vect_capacity(v2), p_vect_capacity(v2),
@ -3314,7 +3339,7 @@ void vect_merge(c_vector const v1, c_vector v2) {
v2->end, v2->end,
10, 10,
p_vect_size(v2)); p_vect_size(v2));
LOG_MOD(ZVLP_INFO, log_msg(ZVLP_INFO,
"vect_merge: v1 capacity = %*u, begin = %*u, end: %*u, size = %*u\n", "vect_merge: v1 capacity = %*u, begin = %*u, end: %*u, size = %*u\n",
10, 10,
p_vect_capacity(v1), p_vect_capacity(v1),
@ -3332,7 +3357,7 @@ void vect_merge(c_vector const v1, c_vector v2) {
} }
#ifdef DEBUG #ifdef DEBUG
LOG_MOD(ZVLP_INFO, log_msg(ZVLP_INFO,
"vect_merge: v1 capacity = %*u, begin = %*u, end: %*u, size = %*u\n", "vect_merge: v1 capacity = %*u, begin = %*u, end: %*u, size = %*u\n",
10, 10,
p_vect_capacity(v1), p_vect_capacity(v1),
@ -3351,7 +3376,7 @@ void vect_merge(c_vector const v1, c_vector v2) {
v1->end += p_vect_size(v2); v1->end += p_vect_size(v2);
#ifdef DEBUG #ifdef DEBUG
LOG_MOD(ZVLP_INFO, log_msg(ZVLP_INFO,
"vect_merge: v1 capacity = %*u, begin = %*u, end: %*u, size = %*u\n", "vect_merge: v1 capacity = %*u, begin = %*u, end: %*u, size = %*u\n",
10, 10,
p_vect_capacity(v1), p_vect_capacity(v1),
@ -3384,7 +3409,7 @@ DONE_PROCESSING:
// free memory correctly. // free memory correctly.
#endif #endif
#ifdef DEBUG #ifdef DEBUG
LOG_MOD(ZVLP_INFO, "vect_merge: --- end ---\n"); log_msg(ZVLP_INFO, "vect_merge: --- end ---\n");
#endif #endif
JOB_DONE: JOB_DONE: