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 TreeMap: number; 18 Load(key: number): Object; 19} 20let flag: boolean = false; 21let fastTreeMap: Object = undefined; 22let arkPritvate: ArkPrivate = globalThis['ArkPrivate'] || undefined; 23if (arkPritvate !== undefined) { 24 fastTreeMap = arkPritvate.Load(arkPritvate.TreeMap); 25} else { 26 flag = true; 27} 28if (flag || fastTreeMap === undefined) { 29 let treeAbility = requireNapi('util.struct'); 30 const errorUtil = treeAbility.errorUtil; 31 interface IterableIterator<T> { 32 next: () => { 33 value: T | undefined; 34 done: boolean; 35 }; 36 } 37 class HandlerTreeMap<K, V> { 38 set(target: TreeMap<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 TreeMap Object`); 47 } 48 deleteProperty(): boolean { 49 throw new Error(`Can't delete Property on TreeMap Object`); 50 } 51 setPrototypeOf(): boolean { 52 throw new Error(`Can't set Prototype on TreeMap Object`); 53 } 54 } 55 class TreeMap<K, V> { 56 private constitute: any; 57 constructor(comparator?: (firstValue: K, secondValue: K) => boolean) { 58 errorUtil.checkNewTargetIsNullError('TreeMap', !new.target); 59 if (comparator) { 60 errorUtil.checkTypeError('comparator', 'callable', comparator); 61 } 62 this.constitute = new treeAbility.TreeClass(comparator); 63 return new Proxy(this, new HandlerTreeMap()); 64 } 65 get length(): number { 66 return this.constitute.memberNumber; 67 } 68 isEmpty(): boolean { 69 errorUtil.checkBindError('isEmpty', TreeMap, this); 70 return this.constitute.memberNumber === 0; 71 } 72 hasKey(key: K): boolean { 73 errorUtil.checkBindError('hasKey', TreeMap, this); 74 return this.constitute.getNode(key) !== undefined; 75 } 76 hasValue(value: V): boolean { 77 errorUtil.checkBindError('hasValue', TreeMap, this); 78 return this.constitute.findNode(value) !== undefined; 79 } 80 get(key: K): V { 81 errorUtil.checkBindError('get', TreeMap, this); 82 let tempNode: any = undefined; 83 tempNode = this.constitute.getNode(key); 84 if (tempNode === undefined) { 85 return tempNode; 86 } 87 return tempNode.value; 88 } 89 getFirstKey(): K { 90 errorUtil.checkBindError('getFirstKey', TreeMap, this); 91 let tempNode: any = undefined; 92 tempNode = this.constitute.firstNode(); 93 if (tempNode === undefined) { 94 return tempNode; 95 } 96 return tempNode.key; 97 } 98 getLastKey(): K { 99 errorUtil.checkBindError('getLastKey', TreeMap, this); 100 let tempNode: any = undefined; 101 tempNode = this.constitute.lastNode(); 102 if (tempNode === undefined) { 103 return tempNode; 104 } 105 return tempNode.key; 106 } 107 setAll(map: TreeMap<K, V>): void { 108 errorUtil.checkBindError('setAll', TreeMap, this); 109 errorUtil.checkTypeError('map', 'TreeMap', map); 110 this.constitute.setAll(map.constitute); 111 } 112 set(key: K, value: V): Object { 113 errorUtil.checkBindError('set', TreeMap, this); 114 return this.constitute.addNode(key, value); 115 } 116 remove(key: K): V { 117 errorUtil.checkBindError('remove', TreeMap, this); 118 return this.constitute.removeNode(key); 119 } 120 clear(): void { 121 errorUtil.checkBindError('clear', TreeMap, this); 122 this.constitute.clearTree(); 123 } 124 getLowerKey(key: K): K { 125 errorUtil.checkBindError('getLowerKey', TreeMap, this); 126 let result: K | undefined = undefined; 127 let tempNode: any = undefined; 128 tempNode = this.constitute.getNode(key); 129 if (tempNode === undefined) { 130 return tempNode; 131 } 132 if (tempNode.left !== undefined) { 133 return tempNode.left.key; 134 } 135 let node: any = tempNode; 136 while (node.parent !== undefined) { 137 if (node.parent.right === node) { 138 return node.parent.key; 139 } 140 node = node.parent; 141 } 142 return result; 143 } 144 getHigherKey(key: K): K { 145 errorUtil.checkBindError('getHigherKey', TreeMap, this); 146 let result: K | undefined = undefined; 147 let tempNode: any = undefined; 148 tempNode = this.constitute.getNode(key); 149 if (tempNode === undefined) { 150 return tempNode; 151 } 152 if (tempNode.right !== undefined) { 153 return tempNode.right.key; 154 } 155 let node: any = tempNode; 156 while (node.parent !== undefined) { 157 if (node.parent.left === node) { 158 return node.parent.key; 159 } 160 node = node.parent; 161 } 162 return result; 163 } 164 keys(): IterableIterator<K> { 165 errorUtil.checkBindError('keys', TreeMap, this); 166 let data: any = this.constitute; 167 let count: number = 0; 168 return { 169 next: function (): { done: boolean, value: K } { 170 let done: boolean = false; 171 let value: K = undefined; 172 done = count >= data.memberNumber; 173 value = done ? undefined : data.keyValueArray[count].key; 174 count++; 175 return { 176 done: done, 177 value: value, 178 }; 179 }, 180 }; 181 } 182 values(): IterableIterator<V> { 183 errorUtil.checkBindError('values', TreeMap, this); 184 let data: any = this.constitute; 185 let count: number = 0; 186 return { 187 next: function (): { done: boolean, value: V } { 188 let done: boolean = false; 189 let value: V = undefined; 190 done = count >= data.memberNumber; 191 value = done ? undefined : data.keyValueArray[count].value; 192 count++; 193 return { 194 done: done, 195 value: value, 196 }; 197 }, 198 }; 199 } 200 replace(key: K, newValue: V): boolean { 201 errorUtil.checkBindError('replace', TreeMap, this); 202 let targetNode: any = this.constitute.getNode(key); 203 if (targetNode === undefined) { 204 return false; 205 } 206 targetNode.value = newValue; 207 return true; 208 } 209 forEach(callbackfn: (value?: V, key?: K, map?: TreeMap<K, V>) => void, 210 thisArg?: Object): void { 211 errorUtil.checkBindError('forEach', TreeMap, this); 212 errorUtil.checkTypeError('callbackfn', 'callable', callbackfn); 213 let data: any = this.constitute; 214 let tagetArray: Array<any> = []; 215 tagetArray = data.keyValueArray; 216 for (let i: number = 0; i < data.memberNumber; i++) { 217 callbackfn.call(thisArg, tagetArray[i].value as V, tagetArray[i].key); 218 } 219 } 220 entries(): IterableIterator<[K, V]> { 221 errorUtil.checkBindError('entries', TreeMap, this); 222 let data: any = this.constitute; 223 let count: number = 0; 224 return { 225 next: function (): { done: boolean, value: [K, V] } { 226 let done: boolean = false; 227 let value: [K, V] = undefined; 228 done = count >= data.memberNumber; 229 value = done ? undefined : data.keyValueArray[count].entry(); 230 count++; 231 return { 232 done: done, 233 value: value, 234 }; 235 }, 236 }; 237 } 238 [Symbol.iterator](): IterableIterator<[K, V]> { 239 errorUtil.checkBindError('Symbol.iterator', TreeMap, this); 240 return this.entries(); 241 } 242 } 243 Object.freeze(TreeMap); 244 fastTreeMap = TreeMap; 245} 246export default fastTreeMap; 247