• 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  Deque: number;
17  Load(key: number): Object;
18}
19let flag: boolean = false;
20let fastDeque: Object = undefined;
21let arkPritvate: ArkPrivate = globalThis.ArkPrivate || undefined;
22if (arkPritvate !== undefined) {
23  fastDeque = arkPritvate.Load(arkPritvate.Deque);
24} else {
25  flag = true;
26}
27declare function requireNapi(s: string): any;
28if (flag || fastDeque === undefined) {
29  const { errorUtil } = requireNapi('util.struct');
30  class HandlerDeque<T> {
31    private isOutBounds(prop: string): void {
32      let index: number = Number.parseInt(prop);
33      if (Number.isInteger(index)) {
34        errorUtil.checkRangeError('index', index, 0);
35      }
36    }
37    get(obj: Deque<T>, prop: string): T {
38      if (typeof prop === 'symbol') {
39        return obj[prop];
40      }
41      this.isOutBounds(prop);
42      return obj[prop];
43    }
44    set(obj: Deque<T>, prop: any, value: T): boolean {
45      if (prop === 'front' || prop === 'capacity' || prop === 'rear') {
46        obj[prop] = value;
47        return true;
48      }
49      let index: number = Number(prop);
50      if (Number.isInteger(index)) {
51        errorUtil.checkRangeError('index', index, 0);
52        obj[index] = value;
53        return true;
54      }
55      return false;
56    }
57    has(obj: Deque<T>, prop: T): boolean {
58      return obj.has(prop);
59    }
60    ownKeys(obj: Deque<T>): Array<string> {
61      let keys: Array<string> = [];
62      for (let i: number = 0; i < obj.length; i++) {
63        keys.push(i.toString());
64      }
65      return keys;
66    }
67    defineProperty(): boolean {
68      return true;
69    }
70    getOwnPropertyDescriptor(obj: Deque<T>, prop: string): Object {
71      this.isOutBounds(prop);
72      let index: number = Number.parseInt(prop);
73      if (index >= 0 && Number.isInteger(index)) {
74        return Object.getOwnPropertyDescriptor(obj, prop);
75      }
76      return Object;
77    }
78    setPrototypeOf(): T {
79      throw new Error(`Can't setPrototype on Deque Object`);
80    }
81  }
82  interface IterableIterator<T> {
83    next: () => {
84      value: T;
85      done: boolean;
86    };
87  }
88  class Deque<T> {
89    private front: number;
90    private capacity: number;
91    private rear: number;
92    constructor() {
93      errorUtil.checkNewTargetIsNullError('Deque', !new.target);
94      this.front = 0;
95      this.capacity = 8;
96      this.rear = 0;
97      return new Proxy(this, new HandlerDeque());
98    }
99    get length(): number {
100      let result: number = 0;
101      result = (this.rear - this.front + this.capacity) % this.capacity;
102      return result;
103    }
104    insertFront(element: T): void {
105      errorUtil.checkBindError('insertFront', Deque, this);
106      if (this.isFull()) {
107        this.increaseCapacity();
108      }
109      this.front = (this.front - 1 + this.capacity) % this.capacity;
110      this[this.front] = element;
111    }
112    insertEnd(element: T): void {
113      errorUtil.checkBindError('insertEnd', Deque, this);
114      if (this.isFull()) {
115        this.increaseCapacity();
116      }
117      this[this.rear] = element;
118      this.rear = (this.rear + 1) % (this.capacity + 1);
119    }
120    getFirst(): T {
121      errorUtil.checkBindError('getFirst', Deque, this);
122      if (this.isEmpty()) {
123        return undefined;
124      }
125      return this[this.front];
126    }
127    getLast(): T {
128      errorUtil.checkBindError('getLast', Deque, this);
129      if (this.isEmpty()) {
130        return undefined;
131      }
132      return this[this.rear - 1];
133    }
134    has(element: T): boolean {
135      errorUtil.checkBindError('has', Deque, this);
136      let result: boolean = false;
137      this.forEach(function (value) {
138        if (value === element) {
139          result = true;
140        }
141      });
142      return result;
143    }
144    popFirst(): T {
145      errorUtil.checkBindError('popFirst', Deque, this);
146      if (this.isEmpty()) {
147        return undefined;
148      }
149      let result: T = undefined;
150      result = this[this.front];
151      this.front = (this.front + 1) % (this.capacity + 1);
152      return result;
153    }
154    popLast(): T {
155      errorUtil.checkBindError('popLast', Deque, this);
156      if (this.isEmpty()) {
157        return undefined;
158      }
159      let result: T = undefined;
160      result = this[this.rear - 1];
161      this.rear = (this.rear + this.capacity) % (this.capacity + 1);
162      return result;
163    }
164    forEach(callbackfn: (value: T, index?: number, deque?: Deque<T>) => void,
165      thisArg?: Object): void {
166      errorUtil.checkBindError('forEach', Deque, this);
167      errorUtil.checkTypeError('callbackfn', 'callable', callbackfn);
168      let k: number = 0;
169      let i: number = this.front;
170      while (true) {
171        callbackfn.call(thisArg, this[i], k, this);
172        i = (i + 1) % this.capacity;
173        k++;
174        if (i === this.rear) {
175          break;
176        }
177      }
178    }
179    private increaseCapacity(): void {
180      let count: number = 0;
181      let arr: Array<T> = [];
182      let length: number = this.length;
183      while (true) {
184        arr[count++] = this[this.front];
185        this.front = (this.front + 1) % this.capacity;
186        if (this.front === this.rear) {
187          break;
188        }
189      }
190      for (let i: number = 0; i < length; i++) {
191        this[i] = arr[i];
192      }
193      this.capacity = 2 * this.capacity; // 2 : means number
194      this.front = 0;
195      this.rear = length;
196    }
197    private isFull(): boolean {
198      return (this.rear + 1) % this.capacity === this.front;
199    }
200    private isEmpty(): boolean {
201      return this.length === 0;
202    }
203    [Symbol.iterator](): IterableIterator<T> {
204      errorUtil.checkBindError('Symbol.iterator', Deque, this);
205      let deque: Deque<T> = this;
206      let count: number = deque.front;
207      return {
208        next: function (): { done: boolean, value: T } {
209          let done: boolean = false;
210          let value: T = undefined;
211          done = count === deque.rear;
212          value = done ? undefined : deque[count];
213          count = (count + 1) % deque.capacity;
214          return {
215            done: done,
216            value: value,
217          };
218        },
219      };
220    }
221  }
222  Object.freeze(Deque);
223  fastDeque = Deque;
224}
225export default fastDeque;
226