From 6c2e5c464d7b0d58c17dbc173d4cd127c4b0f9ad Mon Sep 17 00:00:00 2001 From: huangxin Date: Fri, 10 Feb 2023 14:08:56 +0800 Subject: [PATCH] =?UTF-8?q?OCT=201.=20=E6=9B=B4=E6=96=B0vector?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- srcs/libs/include/zvector/zvector.h | 245 ++++++++------- srcs/libs/misc/zvector.c | 451 +++++++++++++++------------- 2 files changed, 368 insertions(+), 328 deletions(-) diff --git a/srcs/libs/include/zvector/zvector.h b/srcs/libs/include/zvector/zvector.h index a9c5074..b7155ee 100644 --- a/srcs/libs/include/zvector/zvector.h +++ b/srcs/libs/include/zvector/zvector.h @@ -11,10 +11,6 @@ #ifndef SRC_ZVECTOR_H_ #define SRC_ZVECTOR_H_ -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -#pragma once -#endif - #ifdef __cplusplus extern "C" { #endif @@ -27,8 +23,11 @@ extern "C" { // so we know on which platform and which features // we can use: #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" // Declare required structs: @@ -39,25 +38,28 @@ typedef struct p_vector *c_vector; /* * Vector Properties Flags can be used to tell ZVector * which types of properties we want to enable for each - * given c_vector we are creating. - * Each c_vector can have multiple properties enabled at the + * given vector we are creating. + * Each vector can have multiple properties enabled at the * 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 * - * The above will create a c_vector that supports passing items to - * it by reference (instead of copying them into the c_vector) and + * The above will create a vector that supports passing items to + * it by reference (instead of copying them into the vector) and * having Secure Wipe enabled, so that when an element is deleted * its reference will also be fully zeroed out before freeing it. */ enum ZVECT_PROPERTIES { - ZV_NONE = 0, // Sets or Resets all c_vector's properties to 0. - ZV_SEC_WIPE = 1 << 0, // Sets the c_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_CIRCULAR = 1 - << 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_NOLOCKING = 1 << 3, // This Property means the c_vector will not use mutexes, be careful using it! + ZV_NONE = 0, // Sets or Resets all vector's properties to 0. + ZV_SEC_WIPE = 1 << 0, // Sets the vector for automatic Secure Wipe of items. + ZV_BYREF = 1 << 1, // Sets the vector to store items by reference instead of + // copying them as per default. + ZV_CIRCULAR = 1 << 2, // Sets the vector to be a circular vector (so it will + // 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 { @@ -72,6 +74,8 @@ enum ZVECT_ERR { ZVERR_OPNOTALLOWED = -9 }; +extern unsigned int LOG_PRIORITY; + /***************************** ** Public API declaration: ** *****************************/ @@ -79,7 +83,7 @@ enum ZVECT_ERR { // 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 * can store items of "item_size" size and, if we want to * 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); /* - * 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 - * value in the c_vector before destroying it. + * value in the vector before destroying it. */ void vect_destroy(c_vector); /* * vect_shrink is useful when operating on systems with * 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. */ 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 - * 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. */ 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: /* - * vect_is_empty returns true if the c_vector is empty - * and false if the c_vector is NOT empty. + * vect_is_empty returns true if the vector is 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) - * USED slots in the c_vector storage. + * USED slots in the vector storage. */ 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. */ 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_set_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) // Vector Thread Safe functions: @@ -164,34 +182,34 @@ void vect_lock_enable(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. - * 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 - * 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); */ 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. - * 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 - * 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); */ 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. * - * Example of use: To unlock a c_vector called v + * Example of use: To unlock a vector called v * vect_unlock(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 - * c_vector as a dynamic stack. + * vector as a dynamic stack. * * int i = 3; * 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 * Stack. */ @@ -235,25 +253,25 @@ void vect_push(c_vector const v, const void *item); /* * 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 * an element at the top of a * stack. Remember when you use * vect_pop the element you * receive is also removed from - * the c_vector! + * the vector! */ void *vect_pop(c_vector const v); #define vect_pop_back(x) vect_pop(x) /* - * vect_add adds a new item into the c_vector and, - * if required, will also reorganize the c_vector. + * vect_add adds a new item into the vector and, + * if required, will also reorganize the vector. * * int i = 3; * vect_add(v, &i) will add the new item 3 in - * the c_vector v at the end - * (or back) of the c_vector v. + * the vector v at the end + * (or back) of the vector v. */ void vect_add(c_vector const v, const void *item); #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; * 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 * from the original 2nd onward * 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; * 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 * move all the existing * 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 - * of c_vector v. + * of vector v. */ void vect_add_front(c_vector const v, const void *item); #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 - * the v c_vector (but will not remove + * the v vector (but will not remove * the element as it happens in * 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 - * 3 in the c_vector v. + * 3 in the vector v. */ void *vect_get_at(c_vector const v, const zvect_index i); #define vect_at(v, x) vect_get_at(v, x) /* * 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); #define vect_front(v) vect_get_front(v) /* *vect_put allows you to REPLACE an item - * in the c_vector. + * in the vector. * * int i = 3; * 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); @@ -323,7 +341,7 @@ void vect_put(c_vector const v, const void *item); * * int i = 4; * 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 * item 4. */ @@ -333,54 +351,54 @@ void vect_put_at(c_vector const v, const void *item, const zvect_index i); * * int i = 5; * vect_put_front(v, &i) will replace the 1st element - * of the c_vector with the item + * of the vector with the item * 5. */ void vect_put_front(c_vector const v, const void *item); /* - * vect_remove removes an item from the c_vector - * and reorganise the c_vector. It also returns - * the item remove from the c_vector, so you can + * vect_remove removes an item from the vector + * and reorganise the vector. It also returns + * the item remove from the vector, so you can * use it to simulate a stack behaviour as well. * * 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); /* * 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); /* * 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); /* - * vect_delete deletes an item from the c_vector - * and reorganise the c_vector. It does not return + * vect_delete deletes an item from the vector + * and reorganise the vector. It does not return * the item like remove. * * vect_delete(v) will delete and the last - * item in the c_vector. + * item in the vector. */ void vect_delete(c_vector const v); /* * 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); /* * vect_delete_range(v, 20, 30) * will delete items from item - * 20 to item 30 in the c_vector + * 20 to item 30 in the vector * v. */ 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 - * the c_vector. + * the vector. */ 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 - * items in the same c_vector. - * You just pass the c_vector and the index of both the + * items in the same vector. + * You just pass the vector and the index of both the * 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: * 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 - * a range of items in the same c_vector. - * You just pass the c_vector, the index of the first item + * a range of items in the same vector. + * You just pass the vector, the index of the first item * to swap, the index of the last item to swap and the * index of the first item to swap with. * * 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); */ 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 - * 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"). * - * 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: * 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 - * 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"). * - * 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: * vect_rotate_right(v, 5); */ void vect_rotate_right(c_vector const v, const zvect_index i); /* - * vect_qsort allows you to sort a given c_vector. - * The algorithm used to sort a c_vector is Quicksort with + * vect_qsort allows you to sort a given vector. + * The algorithm used to sort a vector is Quicksort with * 3 ways partitioning which is generally much faster than * 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 - * 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 * 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 *)); /* * 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 * "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 * 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" * use: * int i = 5; * 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); -#ifdef __cplusplus -} -#endif + /* * vect_add_ordered allows the insertion of new items in * an ordered fashion. Please note that for this to work * 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! * * As for any other ordered function you must provide * your own compare function (syntax is the usual one, * 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), * 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 - * 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 - * 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 - * 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 * not necessary if you receive the pointer to the item. * You can simply update the content of the memory pointed * by the item passed and that is much faster than having * 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 *)); /* * 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 * 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 @@ -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_range(c_vector const v, void (*f)(void *), const zvect_index x, const zvect_index y); + // Operations with multiple vectors: /* * 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 * parameter we pass during the creation of both vectors) * can be copied into the other! * * 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 - * c_vector items start from 0) in - * the c_vector v1. So at the end + * vector items start from 0) in + * the vector v1. So at the end * of the process you'll have such * 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 - * set of elements from a c_vector to another and "insert" - * them from a specified position in the destination c_vector. + * set of elements from a vector to another and "insert" + * them from a specified position in the destination vector. * Please note: only vectors with the same data size (the * parameter we pass during the creation of both vectors) * can be copied into the other! * * 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 - * c_vector items start from 0) in - * the c_vector v1 from position 7. + * vector items start from 0) in + * the vector v1 from position 7. * So at the end of the process * you'll have such items "inserted" * inside v1. @@ -601,9 +616,9 @@ void vect_insert(c_vector const v1, /* * vect_move is a function that allows to move a specified - * set of items from one c_vector to another. - * It will also re-organise the source c_vector and (obviously) - * expand the destination c_vector if needed. + * set of items from one vector to another. + * It will also re-organise the source vector and (obviously) + * expand the destination vector if needed. * Please note: only vectors of the same data size can be moved * 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 - * 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 * is true. - * It will also re-organise the source c_vector and (obviously) - * expand the destination c_vector if needed. + * It will also re-organise the source vector and (obviously) + * expand the destination vector if needed. * Please note: only vectors of the same data size can be moved * 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 * 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 * v1 will contain the old v1 items + * all v2 items. diff --git a/srcs/libs/misc/zvector.c b/srcs/libs/misc/zvector.c index 9cc7e5b..e713496 100644 --- a/srcs/libs/misc/zvector.c +++ b/srcs/libs/misc/zvector.c @@ -17,18 +17,20 @@ /* * 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 #include #include #include -// Include vector.h header +/* Include vector.h header */ #include "zvector/zvector.h" +#include "misc.h" #if (OS_TYPE == 1) #if (!defined(macOS)) @@ -53,7 +55,7 @@ #include #endif #if (CPU_TYPE == x86_64) -//# include +// # include #endif #endif // OS_TYPE #if (ZVECT_THREAD_SAFE == 1) @@ -74,16 +76,16 @@ // Declare Vector status flags: enum { - ZVS_NONE = 0, // - Set or Reset vector's status - // register. + ZVS_NONE = 0, // - Set or Reset vector's status + // register. ZVS_CUST_WIPE_ON = 1 << 0, // - Set the bit to indicate a custom - // secure wipe - // function has been set. + // secure wipe + // function has been set. ZVS_USR1_FLAG = 1 << 1, // - This is a "user" available flag, - // a user code can set it to 1 or - // 0 for its own need. - // Can be useful when signaling - // between threads. + // a user code can set it to 1 or + // 0 for its own need. + // Can be useful when signaling + // between threads. ZVS_USR2_FLAG = 1 << 2 }; @@ -103,32 +105,35 @@ enum { /*---------------------------------------------------------------------------*/ // 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)) +#ifndef UNUSED #define UNUSED(x) (void)x - +#endif /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -// Define the vector data structure: - -// This is ZVector core data structure, it is the structure of a ZVector vector :) -// Please note: fields order is based on "most used fields" to help a bit with cache - +/* Define the vector data structure: + * + * This is ZVector core data structure, it is the structure of a ZVector + * vector :) + * Please note: fields order is based on "most used fields" to help a bit + * with cache + */ struct ZVECT_PACKING p_vector { - zvect_index cap_left; // - Max capacity allocated on the - // left. + zvect_index cap_left; // - Max capacity allocated on the + // left. zvect_index cap_right; // - Max capacity allocated on the - // right. - zvect_index begin; // - First vector's Element Pointer - zvect_index end; // - Current Array size. size - 1 gives - // us the pointer to the last element - // in the vector. - uint32_t flags; // - This flag set is used to store all - // Vector's properties. - // It contains bits that set Secure - // Wipe, Auto Shrink, Pass Items By - // Ref etc. + // right. + zvect_index begin; // - First vector's Element Pointer + zvect_index end; // - Current Array size. size - 1 gives + // us the pointer to the last element + // in the vector. + uint32_t flags; // - This flag set is used to store all + // Vector's properties. + // It contains bits that set Secure + // Wipe, Auto Shrink, Pass Items By + // Ref etc. size_t data_size; // - User DataType size. // This should be 2 bytes size on a // 16-bit system, 4 bytes on a 32 @@ -139,11 +144,11 @@ struct ZVECT_PACKING p_vector { #if (ZVECT_THREAD_SAFE == 1) #if MUTEX_TYPE == 0 void *lock ZVECT_DATAALIGN; // - Vector's mutex for thread safe - // micro-transactions or user locks. - // This should be 2 bytes size on a - // 16 bit machine, 4 bytes on a 32 - // bit 4 bytes on a 64 bit. - void *cond; // - Vector's mutex condition variable + // micro-transactions or user locks. + // This should be 2 bytes size on a + // 16 bit machine, 4 bytes on a 32 + // bit 4 bytes on a 64 bit. + void *cond; // - Vector's mutex condition variable #elif MUTEX_TYPE == 1 pthread_mutex_t lock ZVECT_DATAALIGN; // - Vector's mutex for thread safe @@ -163,17 +168,17 @@ struct ZVECT_PACKING p_vector { #endif // ZVECT_THREAD_SAFE void **data ZVECT_DATAALIGN; // - Vector's storage. zvect_index init_capacity; // - Initial Capacity (this is set at - // creation time). - // For the size of zvect_index check - // zvector_config.h. + // creation time). + // For the size of zvect_index check + // zvector_config.h. void (*SfWpFunc)(const void *item, size_t size); // - Pointer to a CUSTOM Safe Wipe // function (optional) needed only // for Secure Wiping special // structures. #ifdef ZVECT_DMF_EXTENSIONS - zvect_index balance; // - Used by the Adaptive Binary Search - // to improve performance. + zvect_index balance; // - Used by the Adaptive Binary Search + // to improve performance. zvect_index bottom; // - Used to optimise Adaptive Binary // Search. #endif // ZVECT_DMF_EXTENSIONS @@ -189,6 +194,9 @@ struct ZVECT_PACKING p_vector { #endif // ZVECT_THREAD_SAFE } ZVECT_DATAALIGN; +// Internal representation of a vector +typedef struct p_vector *const ivector; + // Initialisation state: 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); #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: -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_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)); 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 { - strncpy((char *)str_dst, tmp_dst, sizeof(char) * max_len); + strncpy((char *)str_dst, tmp_dst, max_len); } return str_dst; } @@ -274,9 +286,9 @@ __attribute__((noreturn)) #endif static void p_throw_error(const zvect_retval error_code, const char *error_message) { - int32_t locally_allocated = 0; - char *message = NULL; - unsigned long msg_len = 0; + int32_t locally_allocated = 0; + char *message = NULL; + size_t msg_len = 0; if (error_message == NULL) { msg_len = sizeof(char *) * 255; @@ -288,13 +300,13 @@ p_throw_error(const zvect_retval error_code, const char *error_message) { if (locally_allocated) { switch (error_code) { 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; case ZVERR_IDXOUTOFBOUND: message = (char *)safe_strncpy("Index out of bound.\n\0", msg_len); break; 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; case ZVERR_VECTCORRUPTED: 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); break; 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; case ZVERR_VECTDATASIZE: 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); break; 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); } - 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) { free((void *)message); } @@ -374,9 +387,9 @@ static inline ZVECT_ALWAYSINLINE static inline void *p_vect_memmove(const void *__restrict dst, const void *__restrict src, size_t size) { #ifdef DEBUG - LOG_MOD(ZVLP_INFO, "p_vect_memmove: dst %*p\n", 14, dst); - LOG_MOD(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: dst %*p\n", 14, dst); + log_msg(ZVLP_INFO, "p_vect_memmove: src %*p\n", 14, src); + log_msg(ZVLP_INFO, "p_vect_memmove: size %*u\n", 14, size); #endif return memmove((void *)dst, src, size); } @@ -437,10 +450,14 @@ static inline void mutex_destroy(pthread_mutex_t *lock) { static inline int semaphore_init #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); #else - (dispatch_semaphore_t *sem, int value) { *sem = dispatch_semaphore_create(value); return 0; #endif @@ -448,10 +465,14 @@ static inline int semaphore_init static inline int semaphore_destroy #if !defined(macOS) - (sem_t *sem) { + (sem_t *sem) +#else + (dispatch_semaphore_t *sem) +#endif +{ +#if !defined(macOS) return sem_destroy(sem); #else - (dispatch_semaphore_t *sem) { return 0; // dispatch_semaphore_destroy(sem); (void)sem; #endif @@ -511,11 +532,11 @@ static inline zvect_retval check_mutex_trylock(const c_vector v, const int32_t l static inline zvect_retval lock_after_signal(const c_vector v, const int32_t lock_type) { if (lock_type >= v->lock_type) { - //if (!mutex_trylock(&(v->lock))) { + // if (!mutex_trylock(&(v->lock))) { while (!pthread_cond_wait(&(v->cond), &(v->lock))) { // wait until we get a signal } - //mutex_lock(&(v->lock)); + // mutex_lock(&(v->lock)); v->lock_type = lock_type; return 1; //} @@ -526,17 +547,17 @@ 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: -static inline zvect_retval wait_for_signal(const vector v, const int32_t lock_type, bool (*f1)(const vector v), ) { - if (lock_type >= v->lock_type) { - //if (!mutex_trylock(&(v->lock))) { - while(!(*f1)(v)) { - // wait until we get a signal - pthread_cond_wait(&(v->cond), &(v->lock)) - } - return 1; - //} - } - return 0; +static inline zvect_retval wait_for_signal(const c_vector v, const int32_t +lock_type, bool (*f1)(const c_vector v), ) { if (lock_type >= v->lock_type) { + //if (!mutex_trylock(&(v->lock))) { + while(!(*f1)(v)) { + // wait until we get a signal + pthread_cond_wait(&(v->cond), &(v->lock)) + } + return 1; + //} + } + return 0; } */ @@ -569,7 +590,7 @@ static inline zvect_retval get_mutex_unlock(const c_vector v, const int32_t lock void p_init_zvect(void) { #if (OS_TYPE == 1) #if (!defined(macOS)) - //mallopt(M_MXFAST, 196*sizeof(size_t)/4); + // mallopt(M_MXFAST, 196*sizeof(size_t)/4); #endif #endif // OS_TYPE == 1 @@ -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); } -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 (!(v->status & ZVS_CUST_WIPE_ON)) { 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); if (!rval) { - v->status |= 1UL << flag_id; + v->status |= 1 << flag_id; } 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); if (!rval) { - v->status &= ~(1UL << flag_id); + v->status &= ~(1 << flag_id); } 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); if (!rval) { - v->status ^= (1UL << flag_id); + v->status ^= (1 << flag_id); } 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) { 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 */ -static zvect_retval p_vect_set_capacity(c_vector const v, - const zvect_index direction, - const zvect_index new_capacity_) { +static zvect_retval p_vect_set_capacity(ivector v, const zvect_index direction, const zvect_index new_capacity_) { zvect_index new_capacity = new_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. */ -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; 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. */ -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 if (p_vect_capacity(v) <= v->init_capacity) { 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 * 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) { v->init_capacity = 2; } @@ -867,8 +886,8 @@ static zvect_retval p_vect_shrink(c_vector const v) { } // shrink the vector: - // Given that zvector supports vectors that can grow on the left and on the right - // I cannot use realloc here. + // Given that zvector supports vectors that can grow on the left and on the + // right I cannot use realloc here. void **new_data = (void **)malloc(sizeof(void *) * new_capacity); if (new_data == NULL) { return ZVERR_OUTOFMEM; @@ -900,7 +919,7 @@ static zvect_retval p_vect_shrink(c_vector const v) { /*---------------------------------------------------------------------------*/ // Creation and destruction primitives: -zvect_retval p_vect_clear(c_vector const v) { +zvect_retval p_vect_clear(ivector v) { // Clear the vector: if (!vect_is_empty(v)) { 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; // 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; } @@ -973,7 +993,7 @@ static zvect_retval p_vect_destroy(c_vector v, uint32_t flags) { // Vector data storage primitives: // 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: zvect_index idx = i; 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): -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; // 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 -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; // Get the vector size: @@ -1168,8 +1188,8 @@ static inline zvect_retval p_vect_remove_at(c_vector const v, const zvect_index p_item_safewipe(v, v->data[base + idx]); } } /* else { - memset(item, 0, v->data_size - 1); - } */ + memset(item, 0, v->data_size - 1); + } */ } // "shift" left the array of one position: @@ -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 -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 offset, uint32_t flags) { @@ -1260,22 +1280,23 @@ static inline zvect_retval p_vect_delete_at(c_vector const v, zvect_index tot_items = start + offset; #ifdef DEBUG /* - LOG_MOD(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_MOD(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_MOD(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_MOD(ZVLP_INFO, "p_vect_delete_at: data %*p\n", 14, v->data); - */ + log_msg(ZVLP_INFO, "p_vect_delete_at: start %*u\n", 14, start); + log_msg(ZVLP_INFO, "p_vect_delete_at: offset %*u\n", 14, offset); + log_msg(ZVLP_INFO, "p_vect_delete_at: tot_items %*u\n", 14, tot_items); + log_msg(ZVLP_INFO, "p_vect_delete_at: v->begin %*u\n", 14, v->begin); + log_msg(ZVLP_INFO, "p_vect_delete_at: v->end %*u\n", 14, v->end); + log_msg(ZVLP_INFO, "p_vect_delete_at: vsize %*u\n", 14, vsize); + log_msg(ZVLP_INFO, "p_vect_delete_at: data %*p\n", 14, v->data); + */ #endif if ((vsize > 1) && (start < (vsize - 1)) && (tot_items < vsize) && (v->data != NULL)) { array_changed = 1; #ifdef DEBUG /* 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 // Safe erase items? if (flags & 1) { @@ -1343,7 +1364,7 @@ static inline zvect_retval p_vect_delete_at(c_vector const v, * Public method to request ZVector to * shrink a vector. */ -void vect_shrink(c_vector const v) { +void vect_shrink(ivector v) { #if (ZVECT_THREAD_SAFE == 1) zvect_retval lock_owner = get_mutex_lock(v, 1); #endif @@ -1365,23 +1386,24 @@ void vect_shrink(c_vector const v) { /*---------------------------------------------------------------------------*/ // Vector Structural Information report: -bool vect_is_empty(c_vector const v) { - return !p_vect_check(v) ? (p_vect_size(v) == 0) : (bool)ZVERR_VECTUNDEF; +int vect_is_empty(ivector v) { + 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; } -zvect_index vect_max_size(c_vector const v) { - return !p_vect_check(v) ? zvect_index_max : 0; +zvect_index vect_max_size(ivector v) { + 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; } -void *vect_end(c_vector const v) { +void *vect_end(ivector v) { return !p_vect_check(v) ? v->data[v->end] : NULL; } @@ -1490,27 +1512,27 @@ void vect_lock_disable(void) { 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); } -zvect_retval vect_lock(c_vector const v) { +zvect_retval vect_lock(ivector 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); } -zvect_retval vect_unlock(c_vector const v) { +zvect_retval vect_unlock(ivector 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); } -zvect_retval vect_trylock(c_vector const v) { +zvect_retval vect_trylock(ivector v) { return p_vect_trylock(v); } @@ -1531,12 +1553,13 @@ zvect_retval vect_sem_post(const c_vector v) { } /* -static inline zvect_retval p_vect_wait_for_signal(const vector v) { - return (locking_disabled || (v->flags & ZV_NOLOCKING)) ? 1 : wait_for_signal(v, 3); +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); } -inline zvect_retval vect_wait_for_signal(const vector v) { - return p_vect_wait_for_signal(v); +inline zvect_retval vect_wait_for_signal(const c_vector 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: -void vect_clear(c_vector const v) { +void vect_clear(ivector v) { // check if the vector exists: zvect_retval rval = p_vect_check(v); if (rval) { @@ -1576,7 +1599,7 @@ void vect_clear(c_vector const v) { rval = p_vect_clear(v); -//DONE_PROCESSING: +// DONE_PROCESSING: #if (ZVECT_THREAD_SAFE == 1) if (lock_owner) { get_mutex_unlock(v, 1); @@ -1590,10 +1613,9 @@ JOB_DONE: } void vect_set_wipefunct(const c_vector v, void (*f1)(const void *, size_t)) { - v->SfWpFunc = (void *)malloc(sizeof(void *)); - if (v->SfWpFunc == NULL) { - p_throw_error(ZVERR_OUTOFMEM, NULL); - } + // v->SfWpFunc = (void *)malloc(sizeof(void *)); + // if (v->SfWpFunc == NULL) + // p_throw_error(ZVERR_OUTOFMEM, NULL); // Set custom Safe Wipe function: v->SfWpFunc = f1; @@ -1602,8 +1624,9 @@ void vect_set_wipefunct(const c_vector v, void (*f1)(const void *, size_t)) { } // Add an item at the END (top) of the vector -inline void vect_push(const c_vector v, const void *value) { - zvect_retval rval = p_vect_check(v); +void vect_push(const c_vector v, const void *value) { + zvect_index vsize = 0; + zvect_retval rval = p_vect_check(v); if (rval) { 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 // when we use index 0 we may need to expand on the // 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: 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 -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); if (rval) { goto JOB_DONE; @@ -1741,7 +1764,7 @@ JOB_DONE: } // 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: if (i >= p_vect_size(v)) { 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]; } -void *vect_get(c_vector const v) { +void *vect_get(ivector v) { // check if the vector exists: zvect_retval rval = p_vect_check(v); if (!rval) { @@ -1763,7 +1786,7 @@ void *vect_get(c_vector const v) { 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: zvect_retval rval = p_vect_check(v); if (!rval) { @@ -1775,7 +1798,7 @@ void *vect_get_at(c_vector const v, const zvect_index i) { return NULL; } -void *vect_get_front(c_vector const v) { +void *vect_get_front(ivector v) { // check if the vector exists: zvect_retval rval = p_vect_check(v); if (!rval) { @@ -1787,7 +1810,7 @@ void *vect_get_front(c_vector const v) { 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); if (rval) { 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); if (rval) { 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); if (rval) { 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; zvect_retval rval = p_vect_check(v); if (rval) { @@ -1889,7 +1912,7 @@ JOB_DONE: return item; } -void *vect_remove(c_vector const v) { +void *vect_remove(ivector v) { void *item = NULL; zvect_retval rval = p_vect_check(v); if (rval) { @@ -1919,7 +1942,7 @@ JOB_DONE: 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; zvect_retval rval = p_vect_check(v); if (rval) { @@ -1948,7 +1971,7 @@ JOB_DONE: return item; } -void *vect_remove_front(c_vector const v) { +void *vect_remove_front(ivector v) { void *item = NULL; zvect_retval rval = p_vect_check(v); if (rval) { @@ -1978,7 +2001,7 @@ JOB_DONE: } // 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); if (rval) { goto JOB_DONE; @@ -2027,8 +2050,9 @@ JOB_DONE: } } -// Delete a range of items from "first_element" to "last_element" on the vector v -void vect_delete_range(c_vector const v, const zvect_index first_element, const zvect_index last_element) { +// Delete a range of items from "first_element" to "last_element" on the vector +// v +void vect_delete_range(ivector v, const zvect_index first_element, const zvect_index last_element) { zvect_retval rval = p_vect_check(v); if (rval) { goto JOB_DONE; @@ -2054,7 +2078,7 @@ JOB_DONE: } // 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); if (rval) { goto JOB_DONE; @@ -2084,7 +2108,7 @@ JOB_DONE: // Vector Data Manipulation functions #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: if (i1 == i2) { 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: if (s1 == s2) { 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: 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: zvect_retval rval = p_vect_check(v); if (rval) { @@ -2287,7 +2311,7 @@ JOB_DONE: } #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 high, int (*compare_func)(const void *, const void *)) { @@ -2309,7 +2333,10 @@ static inline zvect_index p_partition(vector v, 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) { zvect_index pi = p_partition(v, low, high, compare_func); p_vect_qsort(v, low, pi - 1, compare_func); @@ -2423,7 +2450,7 @@ JOB_DONE: } #ifdef TRADITIONAL_BINARY_SEARCH -static bool p_standard_binary_search(vector v, +static bool p_standard_binary_search(c_vector v, const void *key, zvect_index *item_index, int (*f1)(const void *, const void *)) { @@ -2461,9 +2488,9 @@ static bool p_standard_binary_search(vector v, // original design, most notably the use of custom compare // function that makes it suitable also to search through strings // and other types of vectors. -static bool p_adaptive_binary_search(c_vector const v, - const void *key, - zvect_index *item_index, +static bool p_adaptive_binary_search(ivector v, + const void *key, + zvect_index *item_index, int (*f1)(const void *, const void *)) { zvect_index bot; zvect_index top; @@ -2540,7 +2567,7 @@ MONOBOUND: } #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: if ((key == NULL) || (f1 == NULL) || (p_vect_size(v) == 0)) { return false; @@ -2588,7 +2615,7 @@ JOB_DONE: * functions, the vect_add_ordered is an exception because it * 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: if (value == NULL) { return; @@ -2658,7 +2685,7 @@ JOB_DONE: #ifdef ZVECT_SFMD_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: if (f == NULL) { return; @@ -2678,7 +2705,7 @@ void vect_apply(c_vector const v, void (*f)(void *)) { (*f)(v->data[v->begin + i]); } -//DONE_PROCESSING: +// DONE_PROCESSING: #if (ZVECT_THREAD_SAFE == 1) if (lock_owner) { get_mutex_unlock(v, 1); @@ -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: if (f == NULL) { 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: if (f1 == NULL || f2 == NULL) { 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: zvect_retval rval = p_vect_check(v1) | p_vect_check(v2); if (rval) { @@ -2846,11 +2873,7 @@ JOB_DONE: * position s1). * */ -void vect_insert(c_vector const v1, - c_vector const v2, - const zvect_index s2, - const zvect_index e2, - const zvect_index s1) { +void vect_insert(ivector v1, ivector v2, const zvect_index s2, const zvect_index e2, const zvect_index s1) { // check if the vectors v1 and v2 exist: zvect_retval rval = p_vect_check(v1) | p_vect_check(v2); if (rval) { @@ -2949,11 +2972,11 @@ JOB_DONE: * 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; #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 // We can only copy vectors with the same 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 - LOG_MOD(ZVLP_INFO, - "p_vect_move: v2 capacity = %*u, begin = %*u, end = %*u, size = %*u, s2 = %*u, ee2 = %*u\n", + log_msg(ZVLP_INFO, + "p_vect_move: v2 capacity = %*u, begin = %*u, end = %*u, size = %*u, " + "s2 = %*u, ee2 = %*u\n", 10, p_vect_capacity(v2), 10, @@ -2992,7 +3016,7 @@ static inline zvect_retval p_vect_move(c_vector const v1, c_vector v2, const zve 10, ee2); - LOG_MOD(ZVLP_INFO, + log_msg(ZVLP_INFO, "p_vect_move: v1 capacity = %*u, begin = %*u, end = %*u, size = %*u\n", 10, 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 - LOG_MOD(ZVLP_INFO, + log_msg(ZVLP_INFO, "p_vect_move: v1 capacity = %*u, begin = %*u, end = %*u, size = %*u\n", 10, 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, 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 // Move v2 (from s2) in v1 at the end of v1: const void *rptr = NULL; @@ -3044,15 +3068,15 @@ static inline zvect_retval p_vect_move(c_vector const v1, c_vector v2, const zve v1->end += ee2; #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 // Clean up v2 memory slots that no longer belong to v2: - //rval = p_vect_delete_at(v2, s2, ee2 - 1, 0); + // rval = p_vect_delete_at(v2, s2, ee2 - 1, 0); DONE_PROCESSING: #ifdef DEBUG - LOG_MOD(ZVLP_INFO, + log_msg(ZVLP_INFO, "p_vect_move: v1 capacity = %*u, begin = %*u, end = %*u, size = %*u\n", 10, p_vect_capacity(v1), @@ -3062,7 +3086,7 @@ DONE_PROCESSING: v1->end, 10, 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", 10, p_vect_capacity(v2), @@ -3082,7 +3106,7 @@ DONE_PROCESSING: ////////////////////////////////////////////////////////////////// // 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: zvect_retval rval = p_vect_check(v1) | p_vect_check(v2); 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); #endif #ifdef DEBUG - LOG_MOD(ZVLP_INFO, "vect_move: --- begin ---\n"); + log_msg(ZVLP_INFO, "vect_move: --- begin ---\n"); #if (ZVECT_THREAD_SAFE == 1) - LOG_MOD(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_owner1 for vector v1: %*u\n", 10, lock_owner1); + log_msg(ZVLP_INFO, "vect_move: lock_owner2 for vector v2: %*u\n", 10, lock_owner2); #endif // ZVECT_THREAD_SAFE #endif @@ -3123,7 +3147,7 @@ DONE_PROCESSING: } #endif #ifdef DEBUG - LOG_MOD(ZVLP_INFO, "vect_move: --- end ---\n"); + log_msg(ZVLP_INFO, "vect_move: --- end ---\n"); #endif 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: -zvect_retval vect_move_if(c_vector const v1, +// vect_move_if moves a portion of a vector (v2) into another (v1) if f2 is +// true: +zvect_retval vect_move_if(ivector v1, c_vector v2, const zvect_index s2, 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); #endif #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) - LOG_MOD(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_owner1 for vector v1: %*u\n", 10, lock_owner1); + log_msg(ZVLP_INFO, "vect_move_if: lock_owner2 for vector v2: %*u\n", 10, lock_owner2); #endif // ZVECT_THREAD_SAFE #endif @@ -3181,7 +3206,7 @@ DONE_PROCESSING: } #endif #ifdef DEBUG - LOG_MOD(ZVLP_INFO, "vect_move_if: --- end ---\n"); + log_msg(ZVLP_INFO, "vect_move_if: --- end ---\n"); #endif JOB_DONE: @@ -3198,7 +3223,7 @@ JOB_DONE: ///////////////////////////////////////////////////////////////// // 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, const zvect_index s2, 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); #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 // 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)); } v2->status &= ~(ZVS_USR1_FLAG); - //v2->status |= ZVS_USR_FLAG; + // v2->status |= ZVS_USR_FLAG; #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 // Proceed with move items: rval = p_vect_move(v1, v2, s2, e2); #ifdef DEBUG - LOG_MOD(ZVLP_MEDIUM, "vect_move_on_signal: --- end ---\n"); + log_msg(ZVLP_MEDIUM, "vect_move_on_signal: --- end ---\n"); #endif v2->status &= ~(ZVS_USR1_FLAG); #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 -//DONE_PROCESSING: +// DONE_PROCESSING: #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 if (lock_owner1) { get_mutex_unlock(v1, 1); } #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 rval = p_vect_delete_at(v2, s2, e2 - 1, 0); if (lock_owner2) { @@ -3271,7 +3296,7 @@ JOB_DONE: ///////////////////////////////////////////////////////////////// // 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: zvect_retval rval = p_vect_check(v1) | p_vect_check(v2); if (rval) { @@ -3284,10 +3309,10 @@ void vect_merge(c_vector const v1, c_vector v2) { #endif #ifdef DEBUG - LOG_MOD(ZVLP_INFO, "vect_merge: --- begin ---\n"); + log_msg(ZVLP_INFO, "vect_merge: --- begin ---\n"); #if (ZVECT_THREAD_SAFE == 1) - LOG_MOD(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_owner1 for vector v1: %*u\n", 10, lock_owner1); + log_msg(ZVLP_INFO, "vect_merge: lock_owner2 for vector v2: %*u\n", 10, lock_owner2); #endif // ZVECT_THREAD_SAFE #endif // DEBUG @@ -3304,7 +3329,7 @@ void vect_merge(c_vector const v1, c_vector v2) { } #ifdef DEBUG - LOG_MOD(ZVLP_INFO, + log_msg(ZVLP_INFO, "vect_merge: v2 capacity = %*u, begin = %*u, end: %*u, size = %*u\n", 10, p_vect_capacity(v2), @@ -3314,7 +3339,7 @@ void vect_merge(c_vector const v1, c_vector v2) { v2->end, 10, p_vect_size(v2)); - LOG_MOD(ZVLP_INFO, + log_msg(ZVLP_INFO, "vect_merge: v1 capacity = %*u, begin = %*u, end: %*u, size = %*u\n", 10, p_vect_capacity(v1), @@ -3332,7 +3357,7 @@ void vect_merge(c_vector const v1, c_vector v2) { } #ifdef DEBUG - LOG_MOD(ZVLP_INFO, + log_msg(ZVLP_INFO, "vect_merge: v1 capacity = %*u, begin = %*u, end: %*u, size = %*u\n", 10, p_vect_capacity(v1), @@ -3351,7 +3376,7 @@ void vect_merge(c_vector const v1, c_vector v2) { v1->end += p_vect_size(v2); #ifdef DEBUG - LOG_MOD(ZVLP_INFO, + log_msg(ZVLP_INFO, "vect_merge: v1 capacity = %*u, begin = %*u, end: %*u, size = %*u\n", 10, p_vect_capacity(v1), @@ -3384,7 +3409,7 @@ DONE_PROCESSING: // free memory correctly. #endif #ifdef DEBUG - LOG_MOD(ZVLP_INFO, "vect_merge: --- end ---\n"); + log_msg(ZVLP_INFO, "vect_merge: --- end ---\n"); #endif JOB_DONE: