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 HashMap: number; 18 Load(key: number): Object; 19} 20let flag: boolean = false; 21let fastHashMap: Object = undefined; 22let arkPritvate: ArkPrivate = globalThis['ArkPrivate'] || undefined; 23if (arkPritvate !== undefined) { 24 fastHashMap = arkPritvate.Load(arkPritvate.HashMap); 25} else { 26 flag = true; 27} 28if (flag || fastHashMap === undefined) { 29 let hashMapAbility: any = requireNapi('util.struct'); 30 const errorUtil = hashMapAbility.errorUtil; 31 interface IterableIterator<T> { 32 next: () => { 33 value: T | undefined; 34 done: boolean; 35 }; 36 } 37 class HandlerHashMap<K, V> { 38 set(target: HashMap<K, V>, 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 HashMap Object`); 47 } 48 deleteProperty(): boolean { 49 throw new Error(`Can't delete Property on HashMap Object`); 50 } 51 setPrototypeOf(): boolean { 52 throw new Error(`Can't set Prototype on HashMap Object`); 53 } 54 } 55 class HashMap<K, V> extends hashMapAbility.DictionaryClass<K, V> { 56 constructor() { 57 errorUtil.checkNewTargetIsNullError('HashMap', !new.target); 58 super(); 59 return new Proxy(this, new HandlerHashMap()); 60 } 61 get length(): number { 62 return this.memberNumber; 63 } 64 isEmpty(): boolean { 65 errorUtil.checkBindError('isEmpty', HashMap, this); 66 return this.memberNumber === 0; 67 } 68 hasKey(key: K): boolean { 69 errorUtil.checkBindError('hasKey', HashMap, this); 70 return super.hasKey(key); 71 } 72 hasValue(value: V): boolean { 73 errorUtil.checkBindError('hasValue', HashMap, this); 74 return super.values().indexOf(value) > -1; 75 } 76 get(key: K): V { 77 errorUtil.checkBindError('get', HashMap, this); 78 return this.getValueByKey(key); 79 } 80 setAll(map: HashMap<K, V>): void { 81 errorUtil.checkBindError('setAll', HashMap, this); 82 errorUtil.checkTypeError('map', 'HashMap', map); 83 let memebers: Array<HashMap<K, V>> = []; 84 memebers = map.keyValueArray; 85 for (let i: number = 0; i < memebers.length; i++) { 86 this.put(memebers[i].key, memebers[i].value); 87 } 88 } 89 set(key: K, value: V): Object { 90 errorUtil.checkBindError('set', HashMap, this); 91 return super.put(key, value); 92 } 93 remove(key: K): V { 94 errorUtil.checkBindError('remove', HashMap, this); 95 let result: V = this.removeMember(key); 96 return result; 97 } 98 clear(): void { 99 errorUtil.checkBindError('clear', HashMap, this); 100 super.clear(); 101 } 102 keys(): IterableIterator<K> { 103 errorUtil.checkBindError('keys', HashMap, this); 104 let data: HashMap<K, V> = this; 105 let count: number = 0; 106 return { 107 next: function (): { done: boolean, value: K } { 108 let done: boolean = false; 109 let value: K = undefined; 110 done = count >= data.memberNumber; 111 value = done ? undefined : data.keyValueArray[count].key; 112 count++; 113 return { 114 done: done, 115 value: value, 116 }; 117 }, 118 }; 119 } 120 values(): IterableIterator<V> { 121 errorUtil.checkBindError('values', HashMap, this); 122 let data: HashMap<K, V> = this; 123 let count: number = 0; 124 return { 125 next: function (): { done: boolean, value: V } { 126 let done: boolean = false; 127 let value: V = undefined; 128 done = count >= data.memberNumber; 129 value = done ? undefined : data.keyValueArray[count].value; 130 count++; 131 return { 132 done: done, 133 value: value, 134 }; 135 }, 136 }; 137 } 138 replace(key: K, newValue: V): boolean { 139 errorUtil.checkBindError('replace', HashMap, this); 140 return super.replaceMember(key, newValue); 141 } 142 forEach(callbackfn: (value?: V, key?: K, map?: HashMap<K, V>) => void, 143 thisArg?: Object): void { 144 errorUtil.checkBindError('forEach', HashMap, this); 145 errorUtil.checkTypeError('callbackfn', 'callable', callbackfn); 146 let tagetArray: Array<HashMap<K, V>> = []; 147 tagetArray = this.keyValueArray; 148 for (let i: number = 0; i < tagetArray.length; i++) { 149 callbackfn.call(thisArg, tagetArray[i].value, tagetArray[i].key, this); 150 } 151 } 152 entries(): IterableIterator<[K, V]> { 153 errorUtil.checkBindError('entries', HashMap, this); 154 let data: HashMap<K, V> = this; 155 let count: number = 0; 156 return { 157 next: function (): { done: boolean, value: [K, V] } { 158 let done: boolean = false; 159 let value: [K, V] = undefined; 160 done = count >= data.memberNumber; 161 value = done ? undefined : data.keyValueArray[count].entry(); 162 count++; 163 return { 164 done: done, 165 value: value, 166 }; 167 }, 168 }; 169 } 170 [Symbol.iterator](): IterableIterator<[K, V]> { 171 errorUtil.checkBindError('Symbol.iterator', HashMap, this); 172 return this.entries(); 173 } 174 } 175 Object.freeze(HashMap); 176 fastHashMap = HashMap; 177} 178export default fastHashMap; 179