14d6c458bSopenharmony_ci/*
24d6c458bSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
34d6c458bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44d6c458bSopenharmony_ci * you may not use this file except in compliance with the License.
54d6c458bSopenharmony_ci * You may obtain a copy of the License at
64d6c458bSopenharmony_ci *
74d6c458bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84d6c458bSopenharmony_ci *
94d6c458bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104d6c458bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114d6c458bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124d6c458bSopenharmony_ci * See the License for the specific language governing permissions and
134d6c458bSopenharmony_ci * limitations under the License.
144d6c458bSopenharmony_ci */
154d6c458bSopenharmony_cideclare function requireNapi(s: string): any;
164d6c458bSopenharmony_ciinterface ArkPrivate {
174d6c458bSopenharmony_ci  TreeSet: number;
184d6c458bSopenharmony_ci  Load(key: number): Object;
194d6c458bSopenharmony_ci}
204d6c458bSopenharmony_cilet flag: boolean = false;
214d6c458bSopenharmony_cilet fastTreeSet: Object = undefined;
224d6c458bSopenharmony_cilet arkPritvate: ArkPrivate = globalThis.ArkPrivate || undefined;
234d6c458bSopenharmony_ciif (arkPritvate !== undefined) {
244d6c458bSopenharmony_ci  fastTreeSet = arkPritvate.Load(arkPritvate.TreeSet);
254d6c458bSopenharmony_ci} else {
264d6c458bSopenharmony_ci  flag = true;
274d6c458bSopenharmony_ci}
284d6c458bSopenharmony_ciif (flag || fastTreeSet === undefined) {
294d6c458bSopenharmony_ci  const treeAbility = requireNapi('util.struct');
304d6c458bSopenharmony_ci  const errorUtil = treeAbility.errorUtil;
314d6c458bSopenharmony_ci  interface IterableIterator<T> {
324d6c458bSopenharmony_ci    next: () => {
334d6c458bSopenharmony_ci      value: T | undefined;
344d6c458bSopenharmony_ci      done: boolean;
354d6c458bSopenharmony_ci    };
364d6c458bSopenharmony_ci  }
374d6c458bSopenharmony_ci  class HandlerTreeSet<T> {
384d6c458bSopenharmony_ci    set(target: TreeSet<T>, p: string, value: string): boolean {
394d6c458bSopenharmony_ci      if (p in target) {
404d6c458bSopenharmony_ci        target[p] = value;
414d6c458bSopenharmony_ci        return true;
424d6c458bSopenharmony_ci      }
434d6c458bSopenharmony_ci      return false;
444d6c458bSopenharmony_ci    }
454d6c458bSopenharmony_ci    defineProperty(): boolean {
464d6c458bSopenharmony_ci      throw new Error(`Can't define Property on TreeSet Object`);
474d6c458bSopenharmony_ci    }
484d6c458bSopenharmony_ci    deleteProperty(): boolean {
494d6c458bSopenharmony_ci      throw new Error(`Can't delete Property on TreeSet Object`);
504d6c458bSopenharmony_ci    }
514d6c458bSopenharmony_ci    setPrototypeOf(): boolean {
524d6c458bSopenharmony_ci      throw new Error(`Can't set Prototype on TreeSet Object`);
534d6c458bSopenharmony_ci    }
544d6c458bSopenharmony_ci  }
554d6c458bSopenharmony_ci  class TreeSet<T> {
564d6c458bSopenharmony_ci    private constitute: any;
574d6c458bSopenharmony_ci    constructor(comparator?: (firstValue: T, secondValue: T) => boolean) {
584d6c458bSopenharmony_ci      errorUtil.checkNewTargetIsNullError('TreeSet', !new.target);
594d6c458bSopenharmony_ci      if (comparator) {
604d6c458bSopenharmony_ci        errorUtil.checkTypeError('comparator', 'callable', comparator);
614d6c458bSopenharmony_ci      }
624d6c458bSopenharmony_ci      this.constitute = new treeAbility.TreeClass(comparator);
634d6c458bSopenharmony_ci      return new Proxy(this, new HandlerTreeSet());
644d6c458bSopenharmony_ci    }
654d6c458bSopenharmony_ci    get length(): number {
664d6c458bSopenharmony_ci      return this.constitute.memberNumber;
674d6c458bSopenharmony_ci    }
684d6c458bSopenharmony_ci    isEmpty(): boolean {
694d6c458bSopenharmony_ci      errorUtil.checkBindError('isEmpty', TreeSet, this);
704d6c458bSopenharmony_ci      return this.constitute.isEmpty();
714d6c458bSopenharmony_ci    }
724d6c458bSopenharmony_ci    has(value: T): boolean {
734d6c458bSopenharmony_ci      errorUtil.checkBindError('has', TreeSet, this);
744d6c458bSopenharmony_ci      return this.constitute.getNode(value) !== undefined;
754d6c458bSopenharmony_ci    }
764d6c458bSopenharmony_ci    add(value: T): boolean {
774d6c458bSopenharmony_ci      errorUtil.checkBindError('add', TreeSet, this);
784d6c458bSopenharmony_ci      this.constitute.addNode(value);
794d6c458bSopenharmony_ci      return true;
804d6c458bSopenharmony_ci    }
814d6c458bSopenharmony_ci    remove(value: T): boolean {
824d6c458bSopenharmony_ci      errorUtil.checkBindError('remove', TreeSet, this);
834d6c458bSopenharmony_ci      let result: T = undefined;
844d6c458bSopenharmony_ci      result = this.constitute.removeNode(value);
854d6c458bSopenharmony_ci      return result !== undefined;
864d6c458bSopenharmony_ci    }
874d6c458bSopenharmony_ci    clear(): void {
884d6c458bSopenharmony_ci      errorUtil.checkBindError('clear', TreeSet, this);
894d6c458bSopenharmony_ci      this.constitute.clearTree();
904d6c458bSopenharmony_ci    }
914d6c458bSopenharmony_ci    getFirstValue(): T {
924d6c458bSopenharmony_ci      errorUtil.checkBindError('getFirstValue', TreeSet, this);
934d6c458bSopenharmony_ci      if (this.constitute.firstNode() === undefined) {
944d6c458bSopenharmony_ci        return this.constitute.firstNode();
954d6c458bSopenharmony_ci      }
964d6c458bSopenharmony_ci      return this.constitute.firstNode().key;
974d6c458bSopenharmony_ci    }
984d6c458bSopenharmony_ci    getLastValue(): T {
994d6c458bSopenharmony_ci      errorUtil.checkBindError('getLastValue', TreeSet, this);
1004d6c458bSopenharmony_ci      if (this.constitute.lastNode() === undefined) {
1014d6c458bSopenharmony_ci        return this.constitute.lastNode();
1024d6c458bSopenharmony_ci      }
1034d6c458bSopenharmony_ci      return this.constitute.lastNode().key;
1044d6c458bSopenharmony_ci    }
1054d6c458bSopenharmony_ci    getLowerValue(key: T): T {
1064d6c458bSopenharmony_ci      errorUtil.checkBindError('getLowerValue', TreeSet, this);
1074d6c458bSopenharmony_ci      if (this.constitute.getNode(key) === undefined) {
1084d6c458bSopenharmony_ci        return this.constitute.getNode(key);
1094d6c458bSopenharmony_ci      }
1104d6c458bSopenharmony_ci      if (this.constitute.getNode(key).left !== undefined) {
1114d6c458bSopenharmony_ci        return this.constitute.getNode(key).left.key;
1124d6c458bSopenharmony_ci      }
1134d6c458bSopenharmony_ci      let node = this.constitute.getNode(key);
1144d6c458bSopenharmony_ci      while (node.parent !== undefined) {
1154d6c458bSopenharmony_ci        if (node.parent.right === node) {
1164d6c458bSopenharmony_ci          return node.parent.key;
1174d6c458bSopenharmony_ci        }
1184d6c458bSopenharmony_ci        node = node.parent; // node.parent.left === node is true;
1194d6c458bSopenharmony_ci      }
1204d6c458bSopenharmony_ci      return undefined;
1214d6c458bSopenharmony_ci    }
1224d6c458bSopenharmony_ci    getHigherValue(key: T): T {
1234d6c458bSopenharmony_ci      errorUtil.checkBindError('getHigherValue', TreeSet, this);
1244d6c458bSopenharmony_ci      if (this.constitute.getNode(key) === undefined) {
1254d6c458bSopenharmony_ci        return this.constitute.getNode(key);
1264d6c458bSopenharmony_ci      }
1274d6c458bSopenharmony_ci      if (this.constitute.getNode(key).right !== undefined) {
1284d6c458bSopenharmony_ci        return this.constitute.getNode(key).right.key;
1294d6c458bSopenharmony_ci      }
1304d6c458bSopenharmony_ci      let node = this.constitute.getNode(key);
1314d6c458bSopenharmony_ci      while (node.parent !== undefined) {
1324d6c458bSopenharmony_ci        if (node.parent.left === node) {
1334d6c458bSopenharmony_ci          return node.parent.key;
1344d6c458bSopenharmony_ci        }
1354d6c458bSopenharmony_ci        node = node.parent; // node.parent.right === node is true;
1364d6c458bSopenharmony_ci      }
1374d6c458bSopenharmony_ci      return undefined;
1384d6c458bSopenharmony_ci    }
1394d6c458bSopenharmony_ci    popFirst(): T {
1404d6c458bSopenharmony_ci      errorUtil.checkBindError('popFirst', TreeSet, this);
1414d6c458bSopenharmony_ci      let firstNode: any = undefined;
1424d6c458bSopenharmony_ci      firstNode = this.constitute.firstNode();
1434d6c458bSopenharmony_ci      if (firstNode === undefined) {
1444d6c458bSopenharmony_ci        return firstNode;
1454d6c458bSopenharmony_ci      }
1464d6c458bSopenharmony_ci      let value: T = firstNode.value;
1474d6c458bSopenharmony_ci      this.constitute.removeNodeProcess(firstNode);
1484d6c458bSopenharmony_ci      return value;
1494d6c458bSopenharmony_ci    }
1504d6c458bSopenharmony_ci    popLast(): T {
1514d6c458bSopenharmony_ci      errorUtil.checkBindError('popLast', TreeSet, this);
1524d6c458bSopenharmony_ci      let lastNode: any = undefined;
1534d6c458bSopenharmony_ci      lastNode = this.constitute.lastNode();
1544d6c458bSopenharmony_ci      if (lastNode === undefined) {
1554d6c458bSopenharmony_ci        return lastNode;
1564d6c458bSopenharmony_ci      }
1574d6c458bSopenharmony_ci      let value: T = lastNode.value;
1584d6c458bSopenharmony_ci      this.constitute.removeNodeProcess(lastNode);
1594d6c458bSopenharmony_ci      return value;
1604d6c458bSopenharmony_ci    }
1614d6c458bSopenharmony_ci    values(): IterableIterator<T> {
1624d6c458bSopenharmony_ci      errorUtil.checkBindError('values', TreeSet, this);
1634d6c458bSopenharmony_ci      let count: number = 0;
1644d6c458bSopenharmony_ci      return {
1654d6c458bSopenharmony_ci        next: function (): { done: boolean, value: T } {
1664d6c458bSopenharmony_ci          let done: boolean = false;
1674d6c458bSopenharmony_ci          let value: T = undefined;
1684d6c458bSopenharmony_ci          done = count >= this.memberNumber;
1694d6c458bSopenharmony_ci          value = done ? undefined : this.keyValueArray[count].value as T;
1704d6c458bSopenharmony_ci          count++;
1714d6c458bSopenharmony_ci          return {
1724d6c458bSopenharmony_ci            done: done,
1734d6c458bSopenharmony_ci            value: value,
1744d6c458bSopenharmony_ci          };
1754d6c458bSopenharmony_ci        },
1764d6c458bSopenharmony_ci      };
1774d6c458bSopenharmony_ci    }
1784d6c458bSopenharmony_ci    forEach(callbackfn: (value?: T, key?: T, set?: TreeSet<T>) => void,
1794d6c458bSopenharmony_ci      thisArg?: Object): void {
1804d6c458bSopenharmony_ci      errorUtil.checkBindError('forEach', TreeSet, this);
1814d6c458bSopenharmony_ci      errorUtil.checkTypeError('callbackfn', 'callable', callbackfn);
1824d6c458bSopenharmony_ci      let tagetArray: Array<any> = this.constitute.keyValueArray;
1834d6c458bSopenharmony_ci      for (let i: number = 0; i < this.constitute.memberNumber; i++) {
1844d6c458bSopenharmony_ci        callbackfn.call(thisArg, tagetArray[i].value as T, tagetArray[i].key);
1854d6c458bSopenharmony_ci      }
1864d6c458bSopenharmony_ci    }
1874d6c458bSopenharmony_ci    entries(): IterableIterator<[T, T]> {
1884d6c458bSopenharmony_ci      errorUtil.checkBindError('entries', TreeSet, this);
1894d6c458bSopenharmony_ci      let count: number = 0;
1904d6c458bSopenharmony_ci      return {
1914d6c458bSopenharmony_ci        next: function (): { done: boolean, value: [T, T] } {
1924d6c458bSopenharmony_ci          let done: boolean = false;
1934d6c458bSopenharmony_ci          let value: [T, T] = undefined;
1944d6c458bSopenharmony_ci          done = count >= this.constitute.memberNumber;
1954d6c458bSopenharmony_ci          value = done ? undefined : this.constitute.keyValueArray[count].entry();
1964d6c458bSopenharmony_ci          count++;
1974d6c458bSopenharmony_ci          return {
1984d6c458bSopenharmony_ci            done: done,
1994d6c458bSopenharmony_ci            value: value,
2004d6c458bSopenharmony_ci          };
2014d6c458bSopenharmony_ci        },
2024d6c458bSopenharmony_ci      };
2034d6c458bSopenharmony_ci    }
2044d6c458bSopenharmony_ci    [Symbol.iterator](): IterableIterator<T> {
2054d6c458bSopenharmony_ci      errorUtil.checkBindError('Symbol.iterator', TreeSet, this);
2064d6c458bSopenharmony_ci      return this.values();
2074d6c458bSopenharmony_ci    }
2084d6c458bSopenharmony_ci  }
2094d6c458bSopenharmony_ci  Object.freeze(TreeSet);
2104d6c458bSopenharmony_ci  fastTreeSet = TreeSet;
2114d6c458bSopenharmony_ci}
2124d6c458bSopenharmony_ciexport default fastTreeSet;
213