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