1/* 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15interface ArkPrivate { 16 Vector: number; 17 Load(key: number): Object; 18} 19let flag: boolean = false; 20let fastVector: object = undefined; 21let arkPritvate: ArkPrivate = globalThis.ArkPrivate || undefined; 22if (arkPritvate !== undefined) { 23 fastVector = arkPritvate.Load(arkPritvate.Vector); 24} else { 25 flag = true; 26} 27if (flag || fastVector === undefined) { 28 class HandlerVector<T> { 29 private isOutBounds(obj: Vector<T>, prop: string): void { 30 let index: number = Number.parseInt(prop); 31 if (Number.isInteger(index)) { 32 if (index < 0 || index >= obj.length) { 33 throw new RangeError('the index is out-of-bounds'); 34 } 35 } 36 } 37 get(obj: Vector<T>, prop: string): T { 38 if (typeof prop === 'symbol') { 39 return obj[prop]; 40 } 41 this.isOutBounds(obj, prop); 42 return obj[prop]; 43 } 44 set(obj: Vector<T>, prop: any, value: T): boolean { 45 if (prop === 'elementNum' || prop === 'capacity') { 46 obj[prop] = value; 47 return true; 48 } 49 let index: number = Number.parseInt(prop); 50 if (Number.isInteger(index)) { 51 if (index < 0 || index > obj.length) { 52 throw new RangeError('the index is out-of-bounds'); 53 } else { 54 obj[index] = value; 55 return true; 56 } 57 } 58 return false; 59 } 60 deleteProperty(obj: Vector<T>, prop: string): boolean { 61 this.isOutBounds(obj, prop); 62 let index: number = Number.parseInt(prop); 63 if (index >= 0 && index < obj.length && Number.isInteger(index)) { 64 obj.removeByIndex(index); 65 return true; 66 } 67 return false; 68 } 69 has(obj: Vector<T>, prop: T): boolean { 70 return obj.has(prop); 71 } 72 ownKeys(obj: Vector<T>): Array<string> { 73 let keys: string[] = []; 74 for (let i: number = 0; i < obj.length; i++) { 75 keys.push(i.toString()); 76 } 77 return keys; 78 } 79 defineProperty(): boolean { 80 return true; 81 } 82 getOwnPropertyDescriptor(obj: Vector<T>, prop: string): Object { 83 this.isOutBounds(obj, prop); 84 let index: number = Number.parseInt(prop); 85 if (index >= 0 && index < obj.length && Number.isInteger(index)) { 86 return Object.getOwnPropertyDescriptor(obj, prop); 87 } 88 return Object; 89 } 90 setPrototypeOf(): T { 91 throw new Error(`Can't setPrototype on Vector Object`); 92 } 93 } 94 interface IterableIterator<T> { 95 next: () => { 96 value: T; 97 done: boolean; 98 }; 99 } 100 class Vector<T> { 101 private elementNum: number = 0; 102 private capacity: number = 10; // 10 : means number 103 constructor() { 104 return new Proxy(this, new HandlerVector()); 105 } 106 get length(): number { 107 return this.elementNum; 108 } 109 add(element: T): boolean { 110 if (this.isFull()) { 111 this.resize(); 112 } 113 this[this.elementNum++] = element; 114 return true; 115 } 116 insert(element: T, index: number): void { 117 if (index < 0 || index >= this.elementNum) { 118 throw new RangeError('the index is out-of-bounds'); 119 } 120 if (this.isFull()) { 121 this.resize(); 122 } 123 for (let i: number = this.elementNum; i > index; i--) { 124 this[i] = this[i - 1]; 125 } 126 this[index] = element; 127 this.elementNum++; 128 } 129 has(element: T): boolean { 130 for (let i: number = 0; i < this.elementNum; i++) { 131 if (this[i] === element) { 132 return true; 133 } 134 } 135 return false; 136 } 137 get(index: number): T { 138 return this[index]; 139 } 140 getIndexOf(element: T): number { 141 for (let i: number = 0; i < this.elementNum; i++) { 142 if (element === this[i]) { 143 return i; 144 } 145 } 146 return -1; 147 } 148 getFirstElement(): T { 149 if (this.isEmpty()) { 150 return undefined; 151 } 152 return this[0]; 153 } 154 set(index: number, element: T): T { 155 if (index < 0 || index >= this.elementNum) { 156 throw new RangeError('the index is out-of-bounds'); 157 } 158 this[index] = element; 159 return this[index]; 160 } 161 removeByIndex(index: number): T { 162 if (index < 0 || index >= this.elementNum) { 163 throw new RangeError('the index is out-of-bounds'); 164 } 165 let result: T = this[index]; 166 for (let i: number = index; i < this.elementNum - 1; i++) { 167 this[i] = this[i + 1]; 168 } 169 this.elementNum--; 170 return result; 171 } 172 remove(element: T): boolean { 173 if (this.has(element)) { 174 let index: number = this.getIndexOf(element); 175 for (let i: number = index; i < this.elementNum - 1; i++) { 176 this[i] = this[i + 1]; 177 } 178 this.elementNum--; 179 return true; 180 } 181 return false; 182 } 183 getLastElement(): T { 184 if (this.isEmpty()) { 185 return undefined; 186 } 187 return this[this.elementNum - 1]; 188 } 189 getLastIndexOf(element: T): number { 190 for (let i: number = this.elementNum - 1; i >= 0; i--) { 191 if (element === this[i]) { 192 return i; 193 } 194 } 195 return -1; 196 } 197 getLastIndexFrom(element: T, index: number): number { 198 if (this.has(element)) { 199 for (let i: number = index; i >= 0; i--) { 200 if (this[i] === element) { 201 return i; 202 } 203 } 204 } 205 return -1; 206 } 207 getIndexFrom(element: T, index: number): number { 208 if (this.has(element)) { 209 for (let i: number = index; i < this.elementNum; i++) { 210 if (this[i] === element) { 211 return i; 212 } 213 } 214 } 215 return -1; 216 } 217 clear(): void { 218 this.elementNum = 0; 219 } 220 removeByRange(fromIndex: number, toIndex: number): void { 221 if (fromIndex >= toIndex) { 222 throw new RangeError('the fromIndex cannot be less than or equal to toIndex'); 223 } 224 if (fromIndex >= this.elementNum || fromIndex < 0 || toIndex < 0) { 225 throw new RangeError('the fromIndex or the toIndex is out-of-bounds'); 226 } 227 toIndex = toIndex >= this.elementNum ? this.elementNum : toIndex; 228 let i: number = fromIndex; 229 for (let j = toIndex; j < this.elementNum; j++) { 230 this[i] = this[j]; 231 i++; 232 } 233 this.elementNum -= toIndex - fromIndex; 234 } 235 setLength(newSize: number): void { 236 if (newSize < 0) { 237 throw new RangeError('An incorrect size was set'); 238 } 239 this.elementNum = newSize; 240 } 241 replaceAllElements(callbackfn: (value: T, index?: number, vector?: Vector<T>) => T, 242 thisArg?: Object): void { 243 for (let i: number = 0; i < this.elementNum; i++) { 244 this[i] = callbackfn.call(thisArg, this[i], i, this); 245 } 246 } 247 forEach(callbackfn: (value: T, index?: number, vector?: Vector<T>) => void, 248 thisArg?: Object): void { 249 for (let i: number = 0; i < this.elementNum; i++) { 250 callbackfn.call(thisArg, this[i], i, this); 251 } 252 } 253 sort(comparator?: (firstValue: T, secondValue: T) => number): void { 254 let isSort: boolean = true; 255 if (comparator) { 256 for (let i: number = 0; i < this.elementNum; i++) { 257 for (let j: number = 0; j < this.elementNum - 1 - i; j++) { 258 if (comparator(this[j], this[j + 1]) > 0) { 259 isSort = false; 260 let temp: T = this[j]; 261 this[j] = this[j + 1]; 262 this[j + 1] = temp; 263 } 264 } 265 } 266 } else { 267 for (let i: number = 0; i < this.elementNum - 1; i++) { 268 for (let j: number = 0; j < this.elementNum - 1 - i; j++) { 269 if (this.asciSort(this[j], this[j + 1])) { 270 isSort = false; 271 let temp: T = this[j]; 272 this[j] = this[j + 1]; 273 this[j + 1] = temp; 274 } 275 } 276 if (isSort) { 277 break; 278 } 279 } 280 } 281 } 282 private asciSort(curElement: string, nextElement: string): boolean { 283 if ((Object.prototype.toString.call(curElement) === '[object String]' || 284 Object.prototype.toString.call(curElement) === '[object Number]') && 285 (Object.prototype.toString.call(nextElement) === '[object String]' || 286 Object.prototype.toString.call(nextElement) === '[object Number]')) { 287 curElement = curElement.toString(); 288 nextElement = nextElement.toString(); 289 if (curElement > nextElement) { 290 return true; 291 } 292 return false; 293 } 294 return false; 295 } 296 subVector(fromIndex: number, toIndex: number): Vector<T> { 297 if (fromIndex >= toIndex) { 298 throw new RangeError('the fromIndex cannot be less than or equal to toIndex'); 299 } 300 if (fromIndex >= this.elementNum || fromIndex < 0 || toIndex < 0) { 301 throw new RangeError('the fromIndex or the toIndex is out-of-bounds'); 302 } 303 toIndex = toIndex >= this.elementNum - 1 ? this.elementNum - 1 : toIndex; 304 let vector: Vector<T> = new Vector<T>(); 305 for (let i: number = fromIndex; i < toIndex; i++) { 306 vector.add(this[i]); 307 } 308 return vector; 309 } 310 convertToArray(): Array<T> { 311 let arr: Array<T> = []; 312 for (let i: number = 0; i < this.elementNum; i++) { 313 arr[i] = this[i]; 314 } 315 return arr; 316 } 317 copyToArray(array: Array<T>): void { 318 let arr: Array<T> = this.convertToArray(); 319 let len = array.length; 320 for (let i: number = 0, arrLen = arr.length; i < arrLen; i++) { 321 array[i + len] = arr[i]; 322 } 323 } 324 toString(): string { 325 let str: string = ''; 326 str = `${this[0]}`; 327 for (let i: number = 1; i < this.elementNum; i++) { 328 str = `${str},${this[i]}`; 329 } 330 return str; 331 } 332 clone(): Vector<T> { 333 let clone: Vector<T> = new Vector<T>(); 334 for (let i: number = 0; i < this.elementNum; i++) { 335 clone.add(this[i]); 336 } 337 return clone; 338 } 339 getCapacity(): number { 340 return this.capacity; 341 } 342 private isFull(): boolean { 343 return this.elementNum === this.capacity; 344 } 345 private resize(): void { 346 this.capacity = 2 * this.capacity; // 2 : means number 347 } 348 increaseCapacityTo(newCapacity: number): void { 349 if (newCapacity >= this.elementNum) { 350 this.capacity = newCapacity; 351 } 352 } 353 trimToCurrentLength(): void { 354 this.capacity = this.elementNum; 355 } 356 isEmpty(): boolean { 357 return this.elementNum === 0; 358 } 359 [Symbol.iterator](): IterableIterator<T> { 360 let count: number = 0; 361 let vector: Vector<T> = this; 362 return { 363 next: function (): { done: boolean, value: T } { 364 let done: boolean = false; 365 let value: T = undefined; 366 done = count >= vector.elementNum; 367 value = done ? undefined : vector[count++]; 368 return { 369 done: done, 370 value: value, 371 }; 372 }, 373 }; 374 } 375 } 376 Object.freeze(Vector); 377 fastVector = Vector; 378} 379export default fastVector; 380