C/C++教程

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

本文主要是介绍OpenHarmony轻量系统服务管理--Simplevector实现,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

前言

  之前说过鸿蒙实现了自己的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轻量系统服务管理--Simplevector实现的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!