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  HashSet: number;
18  Load(key: number): Object;
19}
20let flag: boolean = false;
21let fastHashSet: Object = undefined;
22let arkPritvate: ArkPrivate = globalThis.ArkPrivate || undefined;
23if (arkPritvate !== undefined) {
24  fastHashSet = arkPritvate.Load(arkPritvate.HashSet);
25} else {
26  flag = true;
27}
28if (flag || fastHashSet === undefined) {
29  let hashSetAbility: any = requireNapi('util.struct');
30  const errorUtil = hashSetAbility.errorUtil;
31  interface IterableIterator<T> {
32    next: () => {
33      value: T | undefined;
34      done: boolean;
35    };
36  }
37  class HandlerHashSet<T> {
38    set(target: HashSet<T>, p: string, value: string): 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 HashSet Object`);
47    }
48    deleteProperty(): boolean {
49      throw new Error(`Can't delete Property on HashSet Object`);
50    }
51    setPrototypeOf(): boolean {
52      throw new Error(`Can't set Prototype on HashSet Object`);
53    }
54  }
55  class HashSet<T> extends hashSetAbility.DictionaryClass<T, T> {
56    constructor() {
57      errorUtil.checkNewTargetIsNullError('HashSet', !new.target);
58      super();
59      return new Proxy(this, new HandlerHashSet());
60    }
61    get length(): number {
62      return this.memberNumber;
63    }
64    isEmpty(): boolean {
65      errorUtil.checkBindError('isEmpty', HashSet, this);
66      return this.memberNumber === 0;
67    }
68    has(value: T): boolean {
69      errorUtil.checkBindError('has', HashSet, this);
70      return this.hasKey(value);
71    }
72    add(value: T): boolean {
73      errorUtil.checkBindError('add', HashSet, this);
74      if (this.has(value)) {
75        return false;
76      }
77      return this.put(value);
78    }
79    remove(value: T): boolean {
80      errorUtil.checkBindError('remove', HashSet, this);
81      if (this.removeMember(value) !== undefined) {
82        return true;
83      }
84      return false;
85    }
86    clear(): void {
87      errorUtil.checkBindError('clear', HashSet, this);
88      super.clear();
89    }
90    forEach(callbackfn: (value?: T, key?: T, set?: HashSet<T>) => void,
91      thisArg?: Object): void {
92      errorUtil.checkBindError('forEach', HashSet, this);
93      errorUtil.checkTypeError('callbackfn', 'callable', callbackfn);
94      let tagetArray: Array<HashSet<T>> = [];
95      tagetArray = this.keyValueArray;
96      for (let i: number = 0; i < tagetArray.length; i++) {
97        callbackfn.call(thisArg, tagetArray[i].key, tagetArray[i].key, this);
98      }
99    }
100    values(): IterableIterator<T> {
101      errorUtil.checkBindError('values', HashSet, this);
102      let count: number = 0;
103      return {
104        next: function (): { done: boolean, value: T } {
105          let done: boolean = false;
106          let value: T = undefined;
107          done = count >= this.memberNumber;
108          value = done ? undefined : this.keyValueArray[count].key;
109          count++;
110          return {
111            done: done,
112            value: value,
113          };
114        },
115      };
116    }
117    entries(): IterableIterator<[T, T]> {
118      errorUtil.checkBindError('entries', HashSet, this);
119      let count: number = 0;
120      return {
121        next: function (): { done: boolean, value: [T, T] } {
122          let done: boolean = false;
123          let value: [T, T] = undefined;
124          done = count >= this.memberNumber;
125          value = done ? undefined : this.keyValueArray[count].entry();
126          count++;
127          return {
128            done: done,
129            value: value,
130          };
131        },
132      };
133    }
134    [Symbol.iterator](): IterableIterator<T> {
135      errorUtil.checkBindError('Symbol.iterator', HashSet, this);
136      return this.values();
137    }
138  }
139  Object.freeze(HashSet);
140  fastHashSet = HashSet;
141}
142export default fastHashSet;