| 212 | } |
| 213 | |
| 214 | set( |
| 215 | edit: number, |
| 216 | shift: number, |
| 217 | hash: number, |
| 218 | key: K, |
| 219 | value: V, |
| 220 | added: { value: boolean } |
| 221 | ): Node<K, V> { |
| 222 | if (this.hash === hash && Equal_.equals(this.key, key)) { |
| 223 | if (Equal_.equals(this.value, value)) { |
| 224 | return this |
| 225 | } |
| 226 | // Can mutate in-place if edit matches |
| 227 | if (this.canEdit(edit)) { |
| 228 | this.value = value |
| 229 | return this |
| 230 | } |
| 231 | return new LeafNode(edit, hash, key, value) |
| 232 | } |
| 233 | |
| 234 | added.value = true |
| 235 | |
| 236 | if (this.hash === hash) { |
| 237 | return new CollisionNode(edit, hash, [[this.key, this.value], [key, value]]) |
| 238 | } |
| 239 | |
| 240 | const newBit = bitpos(hash, shift) |
| 241 | const existingBit = bitpos(this.hash, shift) |
| 242 | |
| 243 | if (newBit === existingBit) { |
| 244 | return new IndexedNode( |
| 245 | edit, |
| 246 | newBit, |
| 247 | [this.set(edit, shift + SHIFT, hash, key, value, added)] |
| 248 | ) |
| 249 | } |
| 250 | |
| 251 | const bitmap = newBit | existingBit |
| 252 | const nodes: Array<Node<K, V>> = (newBit >>> 0) < (existingBit >>> 0) |
| 253 | ? [new LeafNode(edit, hash, key, value), this] |
| 254 | : [this, new LeafNode(edit, hash, key, value)] |
| 255 | |
| 256 | return new IndexedNode(edit, bitmap, nodes) |
| 257 | } |
| 258 | |
| 259 | remove( |
| 260 | _edit: number, |