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; 16 17let flag = false; 18let fastLightWeightSet = undefined; 19let arkPritvate = globalThis["ArkPrivate"] || undefined; 20if (arkPritvate !== undefined) { 21 fastLightWeightSet = arkPritvate.Load(arkPritvate.LightWeightSet); 22} else { 23 flag = true; 24} 25 26if (flag || fastLightWeightSet === undefined) { 27 const LightWeightAbility = requireNapi("util.struct"); 28 interface IterableIterator<T> { 29 next: () => { 30 value: T | undefined; 31 done: boolean; 32 }; 33 } 34 class HandlerLightWeightSet<T> { 35 set(target: LightWeightSet<T>, p: any, value: any): boolean { 36 if (p in target) { 37 target[p] = value; 38 return true; 39 } 40 return false; 41 } 42 defineProperty(target: LightWeightSet<T>, p: any): boolean { 43 throw new Error("Can't define Property on LightWeightSet Object"); 44 } 45 deleteProperty(target: LightWeightSet<T>, p: any): boolean { 46 throw new Error("Can't delete Property on LightWeightSet Object"); 47 } 48 setPrototypeOf(target: LightWeightSet<T>, p: any): boolean { 49 throw new Error("Can't set Prototype on LightWeightSet Object"); 50 } 51 } 52 class LightWeightSet<T> extends LightWeightAbility.LightWeightClass<T, T> { 53 constructor() { 54 super(); 55 return new Proxy(this, new HandlerLightWeightSet()); 56 } 57 get length() { 58 return this.memberNumber; 59 } 60 add(obj: T): boolean { 61 if (this.members.keys.indexOf(obj) > 0) return false; 62 this.addmember(obj); 63 return true; 64 } 65 addAll(set: LightWeightSet<T>): boolean { 66 if(!(set instanceof LightWeightSet)) { 67 throw new TypeError("Incoming object is not JSAPILightWeightSet"); 68 } 69 let change = false; 70 if (set.memberNumber == 0) { 71 change = false; 72 } else { 73 for (let i = 0; i < set.memberNumber; i++) { 74 change = this.add(set.members.keys[i]) || change; 75 } 76 } 77 return change; 78 } 79 hasAll(set: LightWeightSet<T>): boolean { 80 if (set.memberNumber > this.memberNumber) return false; 81 if (LightWeightAbility.isIncludeToArray(this.members.keys, set.members.keys)) { 82 return true; 83 } 84 return false; 85 } 86 has(key: T): boolean { 87 return this.members.keys.indexOf(key) > -1; 88 } 89 equal(obj: Object): boolean { 90 if (this.memberNumber === 0) return false; 91 if(obj instanceof LightWeightSet) 92 return JSON.stringify(obj.members.keys) === JSON.stringify(this.members.keys); 93 if (JSON.stringify(obj) === JSON.stringify(this.members.keys)) return true; 94 return false; 95 } 96 increaseCapacityTo(minimumCapacity: number): void { 97 super.ensureCapacity(minimumCapacity); 98 } 99 getIndexOf(key: T): number { 100 return super.getIndexByKey(key); 101 } 102 isEmpty(): boolean { 103 return this.memberNumber === 0; 104 } 105 remove(key: T): T { 106 return super.deletemember(key); 107 } 108 removeAt(index: number): boolean { 109 if (index > this.memberNumber--) return false; 110 this.members.hashs.splice(index, 1); 111 this.members.values.splice(index, 1); 112 this.members.keys.splice(index, 1); 113 this.memberNumber--; 114 return true; 115 } 116 clear(): void { 117 if (this.memberNumber != 0 || this.capacity > 8) { 118 this.members.hashs = []; 119 this.members.keys = []; 120 this.members.values = []; 121 this.memberNumber = 0; 122 this.capacity = 8; 123 } 124 } 125 forEach(callbackfn: (value?: T, key?: T, set?: LightWeightSet<T>) => void, 126 thisArg?: Object): void { 127 let data = this; 128 for (let i = 0; i < data.memberNumber; i++) { 129 callbackfn.call(thisArg, data.members.keys[i], data.members.keys[i], data); 130 } 131 } 132 [Symbol.iterator](): IterableIterator<T> { 133 let data = this; 134 let count = 0; 135 return { 136 next: function () { 137 let done = count >= data.memberNumber; 138 let value = !done ? data.members.keys[count] : undefined; 139 count++; 140 return { 141 done: done, 142 value: value, 143 }; 144 }, 145 }; 146 } 147 toString(): string { 148 return this.members.keys.join(","); 149 } 150 toArray(): Array<T> { 151 return this.members.keys.slice(); 152 } 153 getValueAt(index: number): T { 154 return this.members.keys[index]; 155 } 156 values(): IterableIterator<T> { 157 return this.members.keys.values() as IterableIterator<T>; 158 } 159 entries(): IterableIterator<[T, T]> { 160 let data = this; 161 let count = 0; 162 return { 163 next: function () { 164 let done = count >= data.memberNumber; 165 let tempValue = data.members.keys[count]; 166 let value = !done ? ([tempValue, tempValue] as [T, T]) : undefined; 167 count++; 168 return { 169 done: done, 170 value: value, 171 }; 172 }, 173 }; 174 } 175 } 176 Object.freeze(LightWeightSet); 177 fastLightWeightSet = LightWeightSet; 178} 179export default fastLightWeightSet; 180