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 RBTreeAbility = requireNapi('util.struct'); 30 const ErrorUtil = RBTreeAbility.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: any, value: any): 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 RBTreeAbility.RBTreeClass(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 return tempNode.key; 105 } 106 setAll(map: TreeMap<K, V>) { 107 ErrorUtil.checkBindError("setAll", TreeMap, this); 108 ErrorUtil.checkTypeError("map", "TreeMap", map); 109 this.constitute.setAll(map.constitute); 110 } 111 set(key: K, value: V): Object { 112 ErrorUtil.checkBindError("set", TreeMap, this); 113 return this.constitute.addNode(key, value); 114 } 115 remove(key: K): V { 116 ErrorUtil.checkBindError("remove", TreeMap, this); 117 return this.constitute.removeNode(key); 118 } 119 clear() { 120 ErrorUtil.checkBindError("clear", TreeMap, this); 121 this.constitute.clearTree(); 122 } 123 getLowerKey(key: K): K { 124 ErrorUtil.checkBindError("getLowerKey", TreeMap, this); 125 let result: K | undefined = undefined; 126 let tempNode: any = undefined; 127 tempNode = this.constitute.getNode(key); 128 if (tempNode === undefined) { 129 return tempNode; 130 } 131 if (tempNode.left !== undefined) { 132 return tempNode.left.key; 133 } 134 let node: any = tempNode; 135 while (node.parent !== undefined) { 136 if (node.parent.right === node) { 137 return node.parent.key; 138 } 139 node = node.parent; 140 } 141 return result; 142 } 143 getHigherKey(key: K): K { 144 ErrorUtil.checkBindError("getHigherKey", TreeMap, this); 145 let result: K | undefined = undefined; 146 let tempNode: any = undefined; 147 tempNode = this.constitute.getNode(key); 148 if (tempNode === undefined) { 149 return tempNode; 150 } 151 if (tempNode.right !== undefined) { 152 return tempNode.right.key; 153 } 154 let node: any = tempNode; 155 while (node.parent !== undefined) { 156 if (node.parent.left === node) { 157 return node.parent.key; 158 } 159 node = node.parent; 160 } 161 return result; 162 } 163 keys(): IterableIterator<K> { 164 ErrorUtil.checkBindError("keys", TreeMap, this); 165 let data: any = this.constitute; 166 let count: number = 0; 167 return { 168 next: function () { 169 let done: boolean = false; 170 let value: K = undefined; 171 done = count >= data.memberNumber; 172 value = done ? undefined : data.keyValueArray[count].key; 173 count++; 174 return { 175 done: done, 176 value: value, 177 }; 178 }, 179 }; 180 } 181 values(): IterableIterator<V> { 182 ErrorUtil.checkBindError("values", TreeMap, this); 183 let data: any = this.constitute; 184 let count: number = 0; 185 return { 186 next: function () { 187 let done: boolean = false; 188 let value: V = undefined; 189 done = count >= data.memberNumber; 190 value = done ? undefined : data.keyValueArray[count].value; 191 count++; 192 return { 193 done: done, 194 value: value, 195 }; 196 }, 197 }; 198 } 199 replace(key: K, newValue: V): boolean { 200 ErrorUtil.checkBindError("replace", TreeMap, this); 201 let targetNode: any = this.constitute.getNode(key); 202 if (targetNode === undefined) { 203 return false; 204 } 205 targetNode.value = newValue; 206 return true; 207 } 208 forEach(callbackfn: (value?: V, key?: K, map?: TreeMap<K, V>) => void, 209 thisArg?: Object): void { 210 ErrorUtil.checkBindError("forEach", TreeMap, this); 211 ErrorUtil.checkTypeError("callbackfn", "callable", callbackfn); 212 let data: any = this.constitute; 213 let tagetArray: Array<any> = []; 214 tagetArray = data.keyValueArray; 215 for (let i: number = 0; i < data.memberNumber; i++) { 216 callbackfn.call(thisArg, tagetArray[i].value as V, tagetArray[i].key); 217 } 218 } 219 entries(): IterableIterator<[K, V]> { 220 ErrorUtil.checkBindError("entries", TreeMap, this); 221 let data: any = this.constitute; 222 let count: number = 0; 223 return { 224 next: function () { 225 let done: boolean = false; 226 let value: [K, V] = undefined; 227 done = count >= data.memberNumber; 228 value = done ? undefined : data.keyValueArray[count].entry(); 229 count++; 230 return { 231 done: done, 232 value: value, 233 }; 234 }, 235 }; 236 } 237 [Symbol.iterator](): IterableIterator<[K, V]> { 238 ErrorUtil.checkBindError("Symbol.iterator", TreeMap, this); 239 return this.entries(); 240 } 241 } 242 Object.freeze(TreeMap); 243 fastTreeMap = TreeMap; 244} 245export default fastTreeMap; 246