Line data Source code
1 : /**
2 : * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 : #include "securec.h"
11 : #include "mmpa_api.h"
12 : #include "vector.h"
13 : #ifdef __cplusplus
14 : extern "C" {
15 : #endif
16 : #define VECTOR_BASIC_SIZE 0
17 : #define VECTOR_BASIC_STEP 8
18 : #define VECTOR_MAX_AREA 0x80000000U
19 :
20 1 : void InitVector(Vector* vector, size_t itemSize)
21 : {
22 1 : vector->itemSize = itemSize;
23 1 : vector->size = 0;
24 1 : vector->capacity = 0;
25 1 : vector->data = NULL;
26 1 : vector->pfnDestroyItem = NULL;
27 1 : }
28 :
29 1 : void ClearVector(Vector* vector)
30 : {
31 1 : if (vector->pfnDestroyItem != NULL) {
32 2 : for (size_t i = 0; i < vector->size; i++) {
33 1 : vector->pfnDestroyItem(VectorAt(vector, i));
34 : }
35 : }
36 1 : vector->size = 0;
37 1 : }
38 :
39 0 : void DeInitVector(Vector* vector)
40 : {
41 0 : ClearVector(vector);
42 0 : if (vector->data != NULL) {
43 0 : mmFree(vector->data);
44 : }
45 0 : InitVector(vector, 0);
46 0 : }
47 :
48 0 : Vector* CreateVector(size_t itemSize)
49 : {
50 0 : Vector* vector = (Vector*)mmMalloc(sizeof(Vector));
51 0 : if (vector == NULL) {
52 0 : return NULL;
53 : }
54 0 : InitVector(vector, itemSize);
55 0 : return vector;
56 : }
57 :
58 0 : void DestroyVector(Vector* vector)
59 : {
60 0 : DeInitVector(vector);
61 0 : mmFree(vector);
62 0 : }
63 :
64 0 : void MoveVector(Vector* src, Vector* desc)
65 : {
66 0 : desc->capacity = src->capacity;
67 0 : desc->data = src->data;
68 0 : desc->itemSize = src->itemSize;
69 0 : desc->pfnDestroyItem = src->pfnDestroyItem;
70 0 : desc->size = src->size;
71 0 : InitVector(src, 0);
72 0 : }
73 :
74 1 : size_t CapacityVector(Vector* vector, size_t capacity)
75 : {
76 1 : if (vector->capacity >= capacity) {
77 0 : return vector->capacity;
78 : }
79 :
80 1 : size_t maxCapacity = VECTOR_MAX_AREA / vector->itemSize;
81 1 : if (vector->capacity >= maxCapacity) {
82 0 : return vector->capacity;
83 : }
84 :
85 1 : size_t validCapacity = (capacity >= maxCapacity) ? maxCapacity : capacity;
86 1 : size_t areaSize = validCapacity * vector->itemSize;
87 1 : uint8_t* data = (uint8_t*)mmMalloc(areaSize);
88 1 : if (data == NULL) {
89 0 : return vector->capacity;
90 : }
91 :
92 1 : if ((vector->data != NULL) && (vector->size != 0) && (vector->itemSize != 0)) {
93 0 : errno_t ret = memcpy_s(data, areaSize, vector->data, vector->itemSize * vector->size);
94 0 : if (ret != 0) {
95 0 : mmFree(data);
96 0 : return vector->capacity;
97 : }
98 0 : mmFree(vector->data);
99 : }
100 :
101 1 : vector->data = data;
102 1 : vector->capacity = validCapacity;
103 1 : return validCapacity;
104 : }
105 :
106 0 : size_t ReSizeVector(Vector* vector, size_t size)
107 : {
108 0 : if (size > vector->capacity) {
109 0 : (void)CapacityVector(vector, size);
110 0 : if (size > vector->capacity) {
111 0 : return vector->size;
112 : }
113 : }
114 :
115 0 : if (size > vector->size) {
116 0 : vector->size = size;
117 : }
118 0 : return vector->size;
119 : }
120 :
121 1 : void* EmplaceVector(Vector* vector, size_t index, void* data)
122 : {
123 1 : if (vector->size == vector->capacity) {
124 : size_t capacity =
125 1 : CapacityVector(vector, ((vector->capacity + VECTOR_BASIC_STEP) / VECTOR_BASIC_STEP) * VECTOR_BASIC_STEP);
126 1 : if (capacity <= vector->size) {
127 0 : return NULL;
128 : }
129 : }
130 :
131 1 : if (index > vector->size) {
132 0 : return NULL;
133 : }
134 :
135 1 : uint8_t* itemData = vector->data + (index * vector->itemSize);
136 : errno_t ret;
137 1 : if (index < vector->size) {
138 0 : size_t mvArea = (vector->size - index) * vector->itemSize;
139 0 : ret = memmove_s(itemData + vector->itemSize, mvArea, itemData, mvArea);
140 0 : if (ret != 0) {
141 0 : return NULL;
142 : }
143 : }
144 1 : ret = memcpy_s(itemData, vector->itemSize, data, vector->itemSize);
145 1 : if (ret != 0) {
146 0 : return NULL;
147 : }
148 1 : vector->size++;
149 1 : return itemData;
150 : }
151 :
152 1 : void* EmplaceBackVector(Vector* vector, void* data) { return EmplaceVector(vector, vector->size, data); }
153 :
154 0 : void* EmplaceHeadVector(Vector* vector, void* data) { return EmplaceVector(vector, 0, data); }
155 :
156 0 : void RemoveVector(Vector* vector, size_t index)
157 : {
158 0 : if (index >= vector->size) {
159 0 : return;
160 : }
161 :
162 0 : uint8_t* itemData = vector->data + (index * vector->itemSize);
163 0 : if (vector->pfnDestroyItem != NULL) {
164 0 : vector->pfnDestroyItem(itemData);
165 : }
166 :
167 0 : if ((index + 1) < vector->size) {
168 0 : size_t mvArea = (vector->size - index - 1) * vector->itemSize;
169 0 : errno_t ret = memmove_s(itemData, mvArea, itemData + vector->itemSize, mvArea);
170 0 : if (ret != 0) {
171 0 : return;
172 : }
173 : }
174 :
175 0 : vector->size--;
176 : // free memory when no data
177 0 : if ((vector->size == 0) && (vector->capacity != 0)) {
178 0 : mmFree(vector->data);
179 0 : vector->data = NULL;
180 0 : vector->capacity = 0;
181 : }
182 0 : return;
183 : }
184 :
185 4 : void* VectorAt(Vector* vector, size_t index)
186 : {
187 4 : if (index >= vector->size) {
188 0 : return NULL;
189 : }
190 4 : return vector->data + (index * vector->itemSize);
191 : }
192 :
193 0 : const void* ConstVectorAt(const Vector* vector, size_t index)
194 : {
195 0 : if (index >= vector->size) {
196 0 : return NULL;
197 : }
198 0 : return vector->data + (index * vector->itemSize);
199 : }
200 :
201 : #ifdef __cplusplus
202 : }
203 : #endif
|