• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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