分布式系统架构-samgr/source系统服务开发框架基础代码common.c讲解

本篇概述

本篇主要讲解文件common.h 和 common.c,它们:

  • 提供了Samgr和外部模块的常用对象和函数。
  • 提供了简化的矢量容器和向下转换函数。

common.h

宏定义部分

typedef void *MQueueId;
typedef void *MutexId;
typedef void *ThreadId;

// 计算T类型成员的偏移量
# define GET_OFFSIZE(T, member) (long)((char *)&(((T *)(0))->member))
 //将指针向下转换为T类型
#define GET_OBJECT(Ptr, T, member) (T *)(((char *)(Ptr)) - GET_OFFSIZE(T, member))
//代表无效的向量索引,值为-1
#define INVALID_INDEX (-1)

typedef void *(*VECTOR_Key)(const void *);
typedef int (*VECTOR_Compare)(const void *, const void *);

 //定义了由4个元素扩展而成的简化向量类
typedef struct SimpleVector {
    /** Maximum number of data records that can be stored. The initial value is <b>0</b>. */
    int16 max; //可存储的数据记录的最大数量,初始值为0
    /** Peak value of the number of stored data records. The initial value is <b>0</b>. */
    int16 top;//存储的数据记录数量的峰值,初始值为0
    /** Number of data records that have been released. The initial value is <b>0</b>. */
    int16 free;//没有被提交的最大数据记录数,初始值为0
    /** Data storage pointer */
    void **data;//数据存储指针
    /**
     * Converts a data element into a key for comparison. The key is provided by users, and the
     * default value is <b>NULL</b>.
     * 将数据元素转化成密钥加以比较,这个密钥由用户提供,默认值为空
     */
    VECTOR_Key key;
    /**
     * Compares the sizes of key1 and key2, which are provided by users. The value <b>1</b>
     * indicates that key1 is greater than key2, the value <b>0</b> indicates that key1 is equal
     * to key2, and the value <b>-1</b> indicates that key1 is less than key2. The default value
     * is <b>NULL</b>.
     * 对比由用户提供的两个密钥的大小,1代表key1比key2要大,0代表二者一样大,-1代表key1小于key2,默认值为空
     */
    VECTOR_Compare compare;
} Vector;

其中,关于简化向量类型的定义十分重要,它是函数功能与定义的基础,其中主要包括了:

  • 数据存储记录的位置信息:max、top、free
  • 存储数据指针:**data
  • 向量密钥类型VECTOR_Key: key
  • 向量比较类型VECTOR_Compare: compare

函数声明部分

/**
 * @brief Creates or initializes a vector object.
 * 概述:创建或初始化一个向量类
 * This function is used to create or initialize a vector object. \n
 *
 * @param key Indicates the pointer to the function provided by users for converting data elements
 * into key values. If this function is not provided, set it to <b>NULL</b>.
 * key代表有用户提供的函数指针用于转化数据元素为密钥值,如果功能函数没有给定,key先设为null
 * @param compare Indicates the pointer to the function for comparing the sizes of two elements.
 * If this function is not provided, set it to <b>NULL</b>.
 * compare代表对比两个元素大小的函数指针,如果功能函数没有给定,compare先设为null
 * @return Returns the vector right value object.
 * @since 1.0
 * @version 1.0
 */
Vector VECTOR_Make(VECTOR_Key key, VECTOR_Compare compare);

/**
 * @brief Destruct a vector object.
 *
 * This function is used to clear the memory applied by the vector after the temporary vector in
 * the stack is used. \n
 *
 * @param vector Indicates the pointer to the vector to clear.
 * @since 1.0
 * @version 1.0
 */
void VECTOR_Clear(Vector *vector);

/**
 * @brief Adds an element to the vector.
 *
 * This function is used to add an element to the vector. \n
 *
 * @param vector Indicates the <b>this</b> pointer to the vector.
 * @param element Indicates the element to add.
 * @return Returns the location of the element to be added if the operation is successful; returns
 * {@link INVALID_INDEX} if the operation fails.
 * @since 1.0
 * @version 1.0 */
int16 VECTOR_Add(Vector *vector, void *element);

/**
 * @brief Obtains the number of elements in the vector, including elements that have been set to
 * <b>NULL</b>.
 *
 * This function is used for full traversal. \n
 *
 * @param vector Indicates the <b>this</b> pointer to the vector.
 * @return Returns the top value of the vector, which indicates the number of elements.
 * @since 1.0
 * @version 1.0
 */
int16 VECTOR_Size(Vector *vector);

/**
 * @brief Obtains the number of valid elements in the vector, excluding elements that have been set
 * to <b>NULL</b>.
 *
 * This function is used to check whether the number of elements reaches the upper limit. \n
 *
 * @param vector Indicates the <b>this</b> pointer to the vector.
 * @return Returns the top - free value of the vector, which indicates the number of non-null
 * elements.
 * @since 1.0
 * @version 1.0
 */
int16 VECTOR_Num(Vector *vector);

/**
 * @brief Obtains the element at a specified position.
 *
 * This function is used to obtain the element at a specified position.
 *
 * @param vector Indicates the <b>this</b> pointer to the vector.
 * @param index Indicates the subscript to be obtained.
 * @return Returns the element if obtained; returns <b>NULL</b> otherwise.
 * @since 1.0
 * @version 1.0
 */
void *VECTOR_At(Vector *vector, int16 index);

/**
 * @brief Swaps the element at a specified position in a vector with another element.
 *
 * This function is used to clear, sort, or update elements in the vector. \n
 *
 * @param vector Indicates the <b>this</b> pointer to the vector.
 * @param index Indicates the position of the element to be swapped.
 * @param element Indicates the pointer to the new element.
 * @attention Before using this function, ensure that the index is valid. You can use
 * <b>VECTOR_Size</b> to obtain the upper limit of the index.
 * @return Returns the original element if the swapping is successful; returns <b>NULL</b>
 * if the swapping fails.
 * @see VECTOR_Size
 * @since 1.0
 * @version 1.0
 */
void *VECTOR_Swap(Vector *vector, int16 index, void *element);

/**
 * @brief Checks the position of an element.
 *
 * This function is used to check whether a vector has a specified element. \n
 *
 * @param vector Indicates the <b>this</b> pointer to the vector.
 * @param element Indicates the element to be checked.
 * @return Returns the index of the element that is not less than 0 if the check is successful;
 * returns {@link INVALID_INDEX} if the check fails.
 * @since 1.0
 * @version 1.0
 */
int16 VECTOR_Find(Vector *vector, const void *element);

/**
 * @brief Checks the position of the element with a specified key.
 *
 * This function is used to check an element based on its key value. \n
 *
 * @param vector Indicates the <b>this</b> pointer to the vector.
 * @param key Indicates the pointer to the key value of the element to check.
 * @return Returns the index of the key element that is not less than 0 if the check is successful;
 * returns {@link INVALID_INDEX} if the check fails.
 * @since 1.0
 * @version 1.0
 */
int16 VECTOR_FindByKey(Vector *vector, const void *key);

common.c

函数框架

common.c
├── 向量的初始化操作
│ └── VECTOR_Make
│ └── VECTOR_Clear
│ └── VECTOR_Add
├── 向量位置定位操作
│ └── VECTOR_At
│ └── VECTOR_Find
│ └── VECTOR_FindByKey
├── 向量功能性函数
│ └── VECTOR_Swap
│ └── VECTOR_Size
│ └── VECTOR_Num

向量的初始化操作

//构建向量类
Vector VECTOR_Make(VECTOR_Key key, VECTOR_Compare compare)
{
    //定义向量类,并做初始化
    Vector vector = {0, 0, 0, NULL, key, compare};
    return vector;
}

//清除向量类
void VECTOR_Clear(Vector *vector)
{
    if (vector == NULL) {
        return;
    }
    if (vector->data == NULL) {
        return;
    }
    //向量数据清除,调用的是posix和cmsis接口内存释放函数
    SAMGR_Free(vector->data);
    vector->max = 0;
    vector->top = 0;
    vector->free = 0;
    vector->data = NULL;
}

//增加向量类
int16 VECTOR_Add(Vector *vector, void *element)
{
    //检查向量类和元素内容是否为空
    if (vector == NULL || element == NULL) {
        return INVALID_INDEX;
    }

    //如果存储的数据记录数量的峰值>最大可被存储下的数据记录
    if (vector->top >= vector->max) {
        int16 i;
        // use released data elements preferentially
        //优先使用已发布的数据元素
        for (i = vector->top - (int16)1; i >= 0; --i) {
            //从后往前进行空间的寻找,默认发布数据在向量类的开头
            if (vector->data[i] == NULL) {
                vector->data[i] = element;
                vector->free--; //插入时要让有被提交的数据记录数-1
                return i;//成功插入后函数返回存入数据的位置i
            }
        }
        //如果可存储的数据记录的最大数量+4<0
        if (vector->max + GROW_STEP < 0) {
            return INVALID_INDEX;//返回无效索引
        }

        //数据存储指针扩容
        void **data = (void **)SAMGR_Malloc(sizeof(void *) * (vector->max + GROW_STEP));
        if (data == NULL) {
            return INVALID_INDEX;
        }

        if (vector->data != NULL) {
            // data's length is bigger than vector->data's length and only copy vector->data's length's memory;
            // no need to check return value
            //数据长度大于vector->数据长度,只复制vector->数据长度的内存,存入data中,不需要检查返回值
            (void)memcpy_s(data, sizeof(void *) * (vector->max + GROW_STEP),
                           vector->data, sizeof(void *) * vector->max);
            SAMGR_Free(vector->data);
        }
        vector->data = data;
        vector->max += GROW_STEP;
    }
    //将元素赋值进入向量类存储数据的顶部,返回存入数据后向量顶的位置
    vector->data[vector->top] = element;
    return vector->top++;
}

向量位置定位操作

//确定向量类给定索引的数据地址
void *VECTOR_At(Vector *vector, int16 index)
{
    if (vector == NULL || vector->top <= index || index < 0) {
        return NULL;
    }

    return vector->data[index];
}

//向量查找指定元素
int16 VECTOR_Find(Vector *vector, const void *element)
{
    if (vector == NULL || element == NULL) {
        return INVALID_INDEX;
    }
    return VECTOR_FindByKey(vector, (vector->key == NULL) ? element : vector->key(element));
}

//通过密钥进行指定元素查找
int16 VECTOR_FindByKey(Vector *vector, const void *key)
{
    //根据VECTOR_Find返回值可知,key可能是数据元素或者数据元素对应的密钥
    if (vector == NULL || key == NULL) {
        return INVALID_INDEX;
    }

    int16 i;
    //从第0位开始寻找
    for (i = 0; i < vector->top; ++i) {
        //如果密钥数据为空则直接i++
        if (vector->data[i] == NULL) {
            continue;
        }

        //如果向量对应的密钥为空则first为第i个位置的数据元素,否则first为第 i个向量数据元素的密钥
        void *first = (vector->key != NULL) ? vector->key(vector->data[i]) : vector->data[i];
        //如果刚好找到则返回i
        if (first == key) {
            return i;
        }

        if (vector->compare == NULL || first == NULL) {
            continue;
        }

        //经过对比发现first和key大小相等则返回i
        if (vector->compare(first, key) == 0) {
            return i;
        }
    }
    //未找到则返回无效索引
    return INVALID_INDEX;
}

向量功能性函数

//指定向量索引位置交换数据元素
void *VECTOR_Swap(Vector *vector, int16 index, void *element)
{
    if (vector == NULL || vector->top <= index || index < 0) {
        return NULL;
    }
    if (element == NULL) {
        vector->free++;
    }
    void *oldElement = vector->data[index];
    vector->data[index] = element;
    return oldElement; //返回旧元素地址(当前存放的是新元素)
}

//向量的大小
int16 VECTOR_Size(Vector *vector)
{
    if (vector == NULL) {
        return INVALID_INDEX;
    }
    //返回向量存储的数据记录数量的峰值
    return vector->top;
}

//返回已提交的向量元素存储的数据记录的数量
int16 VECTOR_Num(Vector *vector)
{
    if (vector == NULL) {
        return INVALID_INDEX;
    }
    return vector->top - vector->free;
}

小结

本部分向量相关内容是服务增删改查进阶功能的基础部分,顶层服务通过调接细节的服务接口,服务接口通过一系列的地址传输,数据检索存储来完成服务系统的底层逻辑功能,因此了解本部分代码十分重要。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值