ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

OpenHarmony轻量系统服务管理--Simplevector实现

2022-04-22 22:32:28  阅读:157  来源: 互联网

标签:OpenHarmony -- data void 元素 element vector NULL 轻量


前言

  之前说过鸿蒙实现了自己的vector容器,叫做SimpleVector,其代码位于distributedschedule_samgr_lite\interfaces\kits\samgr\common.h,现在来分析下其代码。

 

头文件分析

 1 typedef struct SimpleVector {
 2     int16 max;  //可存储的最大数据记录数。
 3     int16 top;  //存储的数据记录数量的峰值。
 4     int16 free; //已释放的数据记录数。
 5     void **data;//数据段指针
 6     VECTOR_Key key;//函数指针,将数据元素转换为用于比较的键,默认值为NULL
 7      //1 表示key1大于key2
 8      //0 表示key1等于key2
 9      //-1 表示key1小于key2
10      //默认值为NULL
11     VECTOR_Compare compare;//函数指针,指向相应的键值比较函数
12 } Vector;

宏定义

 1 //对于T类型的对象,获取它的member成员相较于起始地址的偏移量
 2 #define GET_OFFSIZE(T, member) (long)((char *)&(((T *)(0))->member))
 3 /*
 4     1.首先获取member对于T的起始地址的偏移量
 5     2.获取ptr-偏移量的地址值,然后转化为T类型
 6 */
 7     @Ptr:成员变量的地址
 8     @T:目标类型
 9     @member:将@Ptr的名称指定为T成员变量
10 #define GET_OBJECT(Ptr, T, member) (T *)(((char *)(Ptr)) - GET_OFFSIZE(T, member))

  这里的宏定义非常重要,在后续的代码中频繁的出现,有的小伙伴可能对于文字注释不太理解,所以我以下面一张图来进一步的说明。

 

  首先拟定一个T类型的结构体,包含三个成员a,b和member。一般情况下,它的存储方式如图上半部分,a的地址即结构体的起始地址,并且与0地址间有不定长的距离。而GET_OFFSIZE的作用就是获取member成员相较于结构体起始地址a的偏移量,这里用的巧妙的地方就是直接将0地址转换为T类型,然后member的地址值就是要求的偏移量,如图的下半部分,这样可以避免做减法操作。

  而GET_OBJECT的作用就显而易见了,即根据member在结构体中的偏移量来获取这个结构体的首地址。实际使用中ptr所指向的对象就是member类型的,所以通过ptr-偏移量就可以得到结构体的首地址。这样我们就可以推断出结构体的全貌。

主要函数实现分析

  针对common.h中的函数声明,对它们相应的实现进行分析。实现在模块2-distributedschedule_samgr_lite\samgr\source\common.c文件中。

 1 /*
 2     函数功能:创建vector对象
 3     函数参数:@key:函数指针,指向将数据元素转换为键值的函数
 4             @compare:函数指针,指向比较两个元素的函数
 5     函数返回:返回一个vector对象
 6     详细描述:初始化vector的成员,并给函数指针赋值
 7 */
 8 Vector VECTOR_Make(VECTOR_Key key, VECTOR_Compare compare)
 9 {
10     //初始化vector成员,并给函数指针赋值
11     Vector vector = {0, 0, 0, NULL, key, compare};
12     return vector;
13 }
14 /*
15     函数功能:清空vector的内容
16     函数参数:@vector:vector对象
17     详细描述:释放vector的data指向的内存,并将vector对象的各个成员置为初始值。
18 */
19 void VECTOR_Clear(Vector *vector)
20 {
21     //参数检查
22     if (vector == NULL) {
23         return;
24     }
25     if (vector->data == NULL) {
26         return;
27     }
28     //释放data指向的内存空间
29     SAMGR_Free(vector->data);
30     //标记值全部归0
31     vector->max = 0;
32     vector->top = 0;
33     vector->free = 0;
34     vector->data = NULL;
35 }

 

vector添加元素操作

 1 /*
 2     函数功能:在vector对象中添加新的元素
 3     函数参数:@vector: vector对象
 4             @element: 待添加的元素
 5     函数返回:成功返回新加入的元素的下标,失败返回INVALID_INDEX
 6     详细描述:
 7             1.将元素添加到vector中,首先做参数检查。
 8             2.判断vector中data是否有空闲空间,如果没有空闲空间,先遍历data中为NULL的元素,
 9              若找到便将element加入后返回,没找到就申请新的空间。
10             3.最后将element加入data中,返回下标。
11 */
12 int16 VECTOR_Add(Vector *vector, void *element)
13 {
14     //参数检查
15     if (vector == NULL || element == NULL) {
16         return INVALID_INDEX;
17     }
18     //无空闲空间
19     if (vector->top >= vector->max) {
20         int16 i;
21         //优先使用已释放的数据元素,从后往前遍历
22         for (i = vector->top - (int16)1; i >= 0; --i) {
23             if (vector->data[i] == NULL) {
24                 //若找到一个指向==NULL的位置,则将元素插入
25                 vector->data[i] = element;//data[i]指向element对应的内存空间
26                 //更新已释放数,减一。代表重用了一块被释放的区域
27                 vector->free--;
28                 //返回插入的下标
29                 return i;
30             }
31         }
32         //不存在可重用的位置,需申请新的空间
33         //max占用两个字节,判断增长是否会导致溢出
34         if (vector->max + GROW_STEP < 0) {
35             //容量达到上限,返回INVALID_INDEX
36             return INVALID_INDEX;
37         }
38         //重新申请新的空间,大小为当前容量max+增长步长GROW_STEP
39         void **data = (void **)SAMGR_Malloc(sizeof(void *) * (vector->max + GROW_STEP));
40         if (data == NULL) {
41             //内存分配失败
42             return INVALID_INDEX;
43         }
44         //若data指向一块内存,则需要拷贝
45         if (vector->data != NULL) {
46             //将源data中的数据拷贝到新的data中
47             (void)memcpy_s(data, sizeof(void *) * (vector->max + GROW_STEP),
48                            vector->data, sizeof(void *) * vector->max);
49             //释放旧的data
50             SAMGR_Free(vector->data);
51         }
52         vector->data = data;//更新数据段
53         vector->max += GROW_STEP;//更新最大容量
54     }
55     //有空闲空间,将element加入
56     vector->data[vector->top] = element;
57     return vector->top++;//先返回当前元素的下标,再自增
58 }

vector中的元素交换操作,当与NULL交换时可用于删除元素

 1 /*
 2     函数功能:交换指定下标的元素
 3     函数参数:@vector: vector对象
 4             @index: 指定索引
 5             @element: 指定元素
 6     函数返回:成功 返回被替换的元素,失败 返回NULL
 7     详细描述:
 8             1.函数调用传入三个参数,待操作的vector对象、元素索引下标、当前元素
 9             2.首先进行参数检查,若检查失败就返回NULL
10             3.判断当前元素是否为NULL,若为NULL 则free+1. 
11             4.当element指向NULL时,即当前替换操作变为删除指定元素的操作
12             5.在替换前先保存旧的元素指针,再替换,并返回旧元素指针。
13 */
14 void *VECTOR_Swap(Vector *vector, int16 index, void *element)
15 {
16     //参数检查
17     if (vector == NULL || vector->top <= index || index < 0) {
18         return NULL;
19     }
20     //若当前元素为NULL则free数+1
21     if (element == NULL) {
22         vector->free++;
23     }
24     //保存当前索引中对应的旧元素
25     void *oldElement = vector->data[index];
26     vector->data[index] = element;//交换
27     return oldElement;
28 }

 

标签:OpenHarmony,--,data,void,元素,element,vector,NULL,轻量
来源: https://www.cnblogs.com/zjra/p/16180798.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有