• 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  Queue: number;
17  Load(key: number): Object;
18}
19let flag: boolean = false;
20let fastQueue: Object = undefined;
21let arkPritvate: ArkPrivate = globalThis.ArkPrivate || undefined;
22if (arkPritvate !== undefined) {
23  fastQueue = arkPritvate.Load(arkPritvate.Queue);
24} else {
25  flag = true;
26}
27declare function requireNapi(s: string): any;
28if (flag || fastQueue === undefined) {
29  const { errorUtil } = requireNapi('util.struct');
30  class HandlerQueue<T> {
31    private isOutBounds(obj: Queue<T>, prop: string): void {
32      let index: number = Number.parseInt(prop);
33      if (Number.isInteger(index)) {
34        errorUtil.checkRangeError('index', index, 0, obj.length);
35      }
36    }
37    get(obj: Queue<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: Queue<T>, prop: any, value: T): boolean {
45      if (prop === 'front' || prop === 'capacity' || prop === 'rear') {
46        obj[prop] = value;
47        return true;
48      }
49      this.isOutBounds(obj, prop);
50      let index: number = Number(prop);
51      if (index >= 0 && index <= obj.length && Number.isInteger(index)) {
52        obj[index] = value;
53        return true;
54      }
55      return false;
56    }
57    ownKeys(obj: Queue<T>): Array<string> {
58      let keys: string[] = [];
59      for (let i: number = 0; i < obj.length; i++) {
60        keys.push(i.toString());
61      }
62      return keys;
63    }
64    defineProperty(): boolean {
65      return true;
66    }
67    getOwnPropertyDescriptor(obj: Queue<T>, prop: string): Object {
68      this.isOutBounds(obj, prop);
69      let index: number = Number.parseInt(prop);
70      if (index >= 0 && index < obj.length && Number.isInteger(index)) {
71        return Object.getOwnPropertyDescriptor(obj, prop);
72      }
73      return Object;
74    }
75    setPrototypeOf(): T {
76      throw new Error(`Can't setPrototype on Queue Object`);
77    }
78  }
79  interface IterableIterator<T> {
80    next: () => {
81      value: T;
82      done: boolean;
83    };
84  }
85  class Queue<T> {
86    private front: number;
87    private capacity: number;
88    private rear: number;
89    constructor() {
90      errorUtil.checkNewTargetIsNullError('Queue', !new.target);
91      this.front = 0;
92      this.capacity = 8;
93      this.rear = 0;
94      return new Proxy(this, new HandlerQueue());
95    }
96    get length(): number {
97      return this.rear - this.front;
98    }
99    add(element: T): boolean {
100      errorUtil.checkBindError('add', Queue, this);
101      if (this.isFull()) {
102        this.increaseCapacity();
103      }
104      this[this.rear] = element;
105      this.rear = (this.rear + 1) % (this.capacity + 1);
106      return true;
107    }
108    getFirst(): T {
109      errorUtil.checkBindError('getFirst', Queue, this);
110      if (this.isEmpty()) {
111        return undefined;
112      }
113      return this[this.front];
114    }
115    pop(): T {
116      errorUtil.checkBindError('pop', Queue, this);
117      if (this.isEmpty()) {
118        return undefined;
119      }
120      let result: T = undefined;
121      result = this[this.front];
122      this.front = (this.front + 1) % (this.capacity + 1);
123      return result;
124    }
125    forEach(callbackfn: (value: T, index?: number, queue?: Queue<T>) => void,
126      thisArg?: Object): void {
127      errorUtil.checkBindError('forEach', Queue, this);
128      errorUtil.checkTypeError('callbackfn', 'callable', callbackfn);
129      let k: number = 0;
130      let i: number = this.front;
131      if (this.isEmpty()) {
132        return;
133      } else {
134        while (true) {
135          callbackfn.call(thisArg, this[i], k, this);
136          i = (i + 1) % this.capacity;
137          k++;
138          if (i === this.rear) {
139            break;
140          }
141        }
142      }
143    }
144    private isFull(): boolean {
145      return this.length === this.capacity;
146    }
147    private isEmpty(): boolean {
148      return this.length === 0;
149    }
150    [Symbol.iterator](): IterableIterator<T> {
151      errorUtil.checkBindError('Symbol.iterator', Queue, this);
152      let count: number = this.front;
153      let queue: Queue<T> = this;
154      return {
155        next: function (): { done: boolean, value: T } {
156          let done: boolean = false;
157          let value: T = undefined;
158          done = count === queue.rear;
159          value = done ? undefined : queue[count];
160          count = (count + 1) % queue.capacity;
161          return {
162            done: done,
163            value: value,
164          };
165        },
166      };
167    }
168    private increaseCapacity(): void {
169      this.capacity = 2 * this.capacity; // 2 : means number
170    }
171  }
172  Object.freeze(Queue);
173  fastQueue = Queue;
174}
175export default fastQueue;
176