• 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 */
15declare function requireNapi(s: string): any;
16interface ArkPrivate {
17  TreeSet: number;
18  Load(key: number): Object;
19}
20let flag: boolean = false;
21let fastTreeSet: Object = undefined;
22let arkPritvate: ArkPrivate = globalThis['ArkPrivate'] || undefined;
23if (arkPritvate !== undefined) {
24  fastTreeSet = arkPritvate.Load(arkPritvate.TreeSet);
25} else {
26  flag = true;
27}
28if (flag || fastTreeSet === undefined) {
29  const RBTreeAbility = requireNapi('util.struct');
30  const ErrorUtil = RBTreeAbility.ErrorUtil;
31  interface IterableIterator<T> {
32    next: () => {
33      value: T | undefined;
34      done: boolean;
35    };
36  }
37  class HandlerTreeSet<T> {
38    set(target: TreeSet<T>, p: any, value: any): boolean {
39      if (p in target) {
40        target[p] = value;
41        return true;
42      }
43      return false;
44    }
45    defineProperty(): boolean {
46      throw new Error(`Can't define Property on TreeSet Object`);
47    }
48    deleteProperty(): boolean {
49      throw new Error(`Can't delete Property on TreeSet Object`);
50    }
51    setPrototypeOf(): boolean {
52      throw new Error(`Can't set Prototype on TreeSet Object`);
53    }
54  }
55  class TreeSet<T> {
56    private constitute: any;
57    constructor(comparator?: (firstValue: T, secondValue: T) => boolean) {
58      ErrorUtil.checkNewTargetIsNullError("TreeSet", !new.target);
59      if (comparator) {
60        ErrorUtil.checkTypeError("comparator", "callable", comparator);
61      }
62      this.constitute = new RBTreeAbility.RBTreeClass(comparator);
63      return new Proxy(this, new HandlerTreeSet());
64    }
65    get length(): number {
66      return this.constitute.memberNumber;
67    }
68    isEmpty(): boolean {
69      ErrorUtil.checkBindError("isEmpty", TreeSet, this);
70      return this.constitute.isEmpty();
71    }
72    has(value: T): boolean {
73      ErrorUtil.checkBindError("has", TreeSet, this);
74      return this.constitute.getNode(value) !== undefined;
75    }
76    add(value: T): boolean {
77      ErrorUtil.checkBindError("add", TreeSet, this);
78      this.constitute.addNode(value);
79      return true;
80    }
81    remove(value: T): boolean {
82      ErrorUtil.checkBindError("remove", TreeSet, this);
83      let result: T = undefined;
84      result = this.constitute.removeNode(value);
85      return result !== undefined;
86    }
87    clear() {
88      ErrorUtil.checkBindError("clear", TreeSet, this);
89      this.constitute.clearTree();
90    }
91    getFirstValue(): T {
92      ErrorUtil.checkBindError("getFirstValue", TreeSet, this);
93      let tempNode: any = undefined;
94      tempNode = this.constitute.firstNode();
95      if (tempNode === undefined) {
96        return tempNode;
97      }
98      return tempNode.key;
99    }
100    getLastValue(): T {
101      ErrorUtil.checkBindError("getLastValue", TreeSet, this);
102      let tempNode: any = undefined;
103      tempNode = this.constitute.lastNode();
104      if (tempNode === undefined) {
105        return tempNode;
106      }
107      return tempNode.key;
108    }
109    getLowerValue(key: T): T {
110      ErrorUtil.checkBindError("getLowerValue", TreeSet, this);
111      let tempNode: any = undefined;
112      tempNode = this.constitute.getNode(key);
113      if (tempNode === undefined) {
114        return tempNode;
115      }
116      if (tempNode.left !== undefined) {
117        return tempNode.left.key;
118      }
119      let node: any = tempNode;
120      while (node.parent !== undefined) {
121        if (node.parent.right === node) {
122          return node.parent.key;
123        }
124        node = node.parent; // node.parent.left === node is true;
125      }
126      return undefined;
127    }
128    getHigherValue(key: T): T {
129      ErrorUtil.checkBindError("getHigherValue", TreeSet, this);
130      let tempNode: any = undefined;
131      tempNode = this.constitute.getNode(key);
132      if (tempNode === undefined) {
133        return tempNode;
134      }
135      if (tempNode.right !== undefined) {
136        return tempNode.right.key;
137      }
138      let node: any = tempNode;
139      while (node.parent !== undefined) {
140        if (node.parent.left === node) {
141          return node.parent.key;
142        }
143        node = node.parent; // node.parent.right === node is true;
144      }
145      undefined;
146    }
147    popFirst(): T {
148      ErrorUtil.checkBindError("popFirst", TreeSet, this);
149      let firstNode: any = undefined;
150      firstNode = this.constitute.firstNode();
151      if (firstNode === undefined) {
152        return firstNode;
153      }
154      let value: T = firstNode.value;
155      this.constitute.removeNodeProcess(firstNode);
156      return value;
157    }
158    popLast(): T {
159      ErrorUtil.checkBindError("popLast", TreeSet, this);
160      let lastNode: any = undefined;
161      lastNode = this.constitute.lastNode();
162      if (lastNode === undefined) {
163        return lastNode;
164      }
165      let value: T = lastNode.value;
166      this.constitute.removeNodeProcess(lastNode);
167      return value;
168    }
169    values(): IterableIterator<T> {
170      ErrorUtil.checkBindError("values", TreeSet, this);
171      let data: any = this.constitute;
172      let count: number = 0;
173      return {
174        next: function () {
175          let done: boolean = false;
176          let value: T = undefined;
177          done = count >= data.memberNumber;
178          value = done ? undefined : data.keyValueArray[count].value as T;
179          count++;
180          return {
181            done: done,
182            value: value,
183          };
184        },
185      };
186    }
187    forEach(callbackfn: (value?: T, key?: T, set?: TreeSet<T>) => void,
188      thisArg?: Object): void {
189      ErrorUtil.checkBindError("forEach", TreeSet, this);
190      ErrorUtil.checkTypeError("callbackfn", "callable", callbackfn);
191      let data: any = this.constitute;
192      let tagetArray: Array<any> = data.keyValueArray;
193      for (let i: number = 0; i < data.memberNumber; i++) {
194        callbackfn.call(thisArg, tagetArray[i].value as T, tagetArray[i].key);
195      }
196    }
197    entries(): IterableIterator<[T, T]> {
198      ErrorUtil.checkBindError("entries", TreeSet, this);
199      let data: any = this.constitute;
200      let count: number = 0;
201      return {
202        next: function () {
203          let done: boolean = false;
204          let value: [T, T] = undefined;
205          done = count >= data.memberNumber;
206          value = done ? undefined : data.keyValueArray[count].entry();
207          count++;
208          return {
209            done: done,
210            value: value,
211          };
212        },
213      };
214    }
215    [Symbol.iterator](): IterableIterator<T> {
216      ErrorUtil.checkBindError("Symbol.iterator", TreeSet, this);
217      return this.values();
218    }
219  }
220  Object.freeze(TreeSet);
221  fastTreeSet = TreeSet;
222}
223export default fastTreeSet;
224