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  HashSet: number;
184d6c458bSopenharmony_ci  Load(key: number): Object;
194d6c458bSopenharmony_ci}
204d6c458bSopenharmony_cilet flag: boolean = false;
214d6c458bSopenharmony_cilet fastHashSet: Object = undefined;
224d6c458bSopenharmony_cilet arkPritvate: ArkPrivate = globalThis.ArkPrivate || undefined;
234d6c458bSopenharmony_ciif (arkPritvate !== undefined) {
244d6c458bSopenharmony_ci  fastHashSet = arkPritvate.Load(arkPritvate.HashSet);
254d6c458bSopenharmony_ci} else {
264d6c458bSopenharmony_ci  flag = true;
274d6c458bSopenharmony_ci}
284d6c458bSopenharmony_ciif (flag || fastHashSet === undefined) {
294d6c458bSopenharmony_ci  let hashSetAbility: any = requireNapi('util.struct');
304d6c458bSopenharmony_ci  const errorUtil = hashSetAbility.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 HandlerHashSet<T> {
384d6c458bSopenharmony_ci    set(target: HashSet<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 HashSet Object`);
474d6c458bSopenharmony_ci    }
484d6c458bSopenharmony_ci    deleteProperty(): boolean {
494d6c458bSopenharmony_ci      throw new Error(`Can't delete Property on HashSet Object`);
504d6c458bSopenharmony_ci    }
514d6c458bSopenharmony_ci    setPrototypeOf(): boolean {
524d6c458bSopenharmony_ci      throw new Error(`Can't set Prototype on HashSet Object`);
534d6c458bSopenharmony_ci    }
544d6c458bSopenharmony_ci  }
554d6c458bSopenharmony_ci  class HashSet<T> extends hashSetAbility.DictionaryClass<T, T> {
564d6c458bSopenharmony_ci    constructor() {
574d6c458bSopenharmony_ci      errorUtil.checkNewTargetIsNullError('HashSet', !new.target);
584d6c458bSopenharmony_ci      super();
594d6c458bSopenharmony_ci      return new Proxy(this, new HandlerHashSet());
604d6c458bSopenharmony_ci    }
614d6c458bSopenharmony_ci    get length(): number {
624d6c458bSopenharmony_ci      return this.memberNumber;
634d6c458bSopenharmony_ci    }
644d6c458bSopenharmony_ci    isEmpty(): boolean {
654d6c458bSopenharmony_ci      errorUtil.checkBindError('isEmpty', HashSet, this);
664d6c458bSopenharmony_ci      return this.memberNumber === 0;
674d6c458bSopenharmony_ci    }
684d6c458bSopenharmony_ci    has(value: T): boolean {
694d6c458bSopenharmony_ci      errorUtil.checkBindError('has', HashSet, this);
704d6c458bSopenharmony_ci      return this.hasKey(value);
714d6c458bSopenharmony_ci    }
724d6c458bSopenharmony_ci    add(value: T): boolean {
734d6c458bSopenharmony_ci      errorUtil.checkBindError('add', HashSet, this);
744d6c458bSopenharmony_ci      if (this.has(value)) {
754d6c458bSopenharmony_ci        return false;
764d6c458bSopenharmony_ci      }
774d6c458bSopenharmony_ci      return this.put(value);
784d6c458bSopenharmony_ci    }
794d6c458bSopenharmony_ci    remove(value: T): boolean {
804d6c458bSopenharmony_ci      errorUtil.checkBindError('remove', HashSet, this);
814d6c458bSopenharmony_ci      if (this.removeMember(value) !== undefined) {
824d6c458bSopenharmony_ci        return true;
834d6c458bSopenharmony_ci      }
844d6c458bSopenharmony_ci      return false;
854d6c458bSopenharmony_ci    }
864d6c458bSopenharmony_ci    clear(): void {
874d6c458bSopenharmony_ci      errorUtil.checkBindError('clear', HashSet, this);
884d6c458bSopenharmony_ci      super.clear();
894d6c458bSopenharmony_ci    }
904d6c458bSopenharmony_ci    forEach(callbackfn: (value?: T, key?: T, set?: HashSet<T>) => void,
914d6c458bSopenharmony_ci      thisArg?: Object): void {
924d6c458bSopenharmony_ci      errorUtil.checkBindError('forEach', HashSet, this);
934d6c458bSopenharmony_ci      errorUtil.checkTypeError('callbackfn', 'callable', callbackfn);
944d6c458bSopenharmony_ci      let tagetArray: Array<HashSet<T>> = [];
954d6c458bSopenharmony_ci      tagetArray = this.keyValueArray;
964d6c458bSopenharmony_ci      for (let i: number = 0; i < tagetArray.length; i++) {
974d6c458bSopenharmony_ci        callbackfn.call(thisArg, tagetArray[i].key, tagetArray[i].key, this);
984d6c458bSopenharmony_ci      }
994d6c458bSopenharmony_ci    }
1004d6c458bSopenharmony_ci    values(): IterableIterator<T> {
1014d6c458bSopenharmony_ci      errorUtil.checkBindError('values', HashSet, this);
1024d6c458bSopenharmony_ci      let count: number = 0;
1034d6c458bSopenharmony_ci      return {
1044d6c458bSopenharmony_ci        next: function (): { done: boolean, value: T } {
1054d6c458bSopenharmony_ci          let done: boolean = false;
1064d6c458bSopenharmony_ci          let value: T = undefined;
1074d6c458bSopenharmony_ci          done = count >= this.memberNumber;
1084d6c458bSopenharmony_ci          value = done ? undefined : this.keyValueArray[count].key;
1094d6c458bSopenharmony_ci          count++;
1104d6c458bSopenharmony_ci          return {
1114d6c458bSopenharmony_ci            done: done,
1124d6c458bSopenharmony_ci            value: value,
1134d6c458bSopenharmony_ci          };
1144d6c458bSopenharmony_ci        },
1154d6c458bSopenharmony_ci      };
1164d6c458bSopenharmony_ci    }
1174d6c458bSopenharmony_ci    entries(): IterableIterator<[T, T]> {
1184d6c458bSopenharmony_ci      errorUtil.checkBindError('entries', HashSet, this);
1194d6c458bSopenharmony_ci      let count: number = 0;
1204d6c458bSopenharmony_ci      return {
1214d6c458bSopenharmony_ci        next: function (): { done: boolean, value: [T, T] } {
1224d6c458bSopenharmony_ci          let done: boolean = false;
1234d6c458bSopenharmony_ci          let value: [T, T] = undefined;
1244d6c458bSopenharmony_ci          done = count >= this.memberNumber;
1254d6c458bSopenharmony_ci          value = done ? undefined : this.keyValueArray[count].entry();
1264d6c458bSopenharmony_ci          count++;
1274d6c458bSopenharmony_ci          return {
1284d6c458bSopenharmony_ci            done: done,
1294d6c458bSopenharmony_ci            value: value,
1304d6c458bSopenharmony_ci          };
1314d6c458bSopenharmony_ci        },
1324d6c458bSopenharmony_ci      };
1334d6c458bSopenharmony_ci    }
1344d6c458bSopenharmony_ci    [Symbol.iterator](): IterableIterator<T> {
1354d6c458bSopenharmony_ci      errorUtil.checkBindError('Symbol.iterator', HashSet, this);
1364d6c458bSopenharmony_ci      return this.values();
1374d6c458bSopenharmony_ci    }
1384d6c458bSopenharmony_ci  }
1394d6c458bSopenharmony_ci  Object.freeze(HashSet);
1404d6c458bSopenharmony_ci  fastHashSet = HashSet;
1414d6c458bSopenharmony_ci}
1424d6c458bSopenharmony_ciexport default fastHashSet;