(
edit: number,
shift: number,
f: HashMap.UpdateFn<V>,
hash: number,
key: K,
size: SizeRef
)
| 190 | ) {} |
| 191 | |
| 192 | modify( |
| 193 | edit: number, |
| 194 | shift: number, |
| 195 | f: HashMap.UpdateFn<V>, |
| 196 | hash: number, |
| 197 | key: K, |
| 198 | size: SizeRef |
| 199 | ): Node<K, V> { |
| 200 | const mask = this.mask |
| 201 | const children = this.children |
| 202 | const frag = hashFragment(shift, hash) |
| 203 | const bit = toBitmap(frag) |
| 204 | const indx = fromBitmap(mask, bit) |
| 205 | const exists = mask & bit |
| 206 | const canEdit = canEditNode(this, edit) |
| 207 | |
| 208 | if (!exists) { |
| 209 | const _newChild = new EmptyNode<K, V>().modify(edit, shift + SIZE, f, hash, key, size) |
| 210 | if (!_newChild) return this |
| 211 | return children.length >= MAX_INDEX_NODE ? |
| 212 | expand(edit, frag, _newChild, mask, children) : |
| 213 | new IndexedNode(edit, mask | bit, arraySpliceIn(canEdit, indx, _newChild, children)) |
| 214 | } |
| 215 | |
| 216 | const current = children[indx]! |
| 217 | const child = current.modify(edit, shift + SIZE, f, hash, key, size) |
| 218 | |
| 219 | if (current === child) return this |
| 220 | let bitmap = mask |
| 221 | let newChildren |
| 222 | if (isEmptyNode(child)) { |
| 223 | // remove |
| 224 | bitmap &= ~bit |
| 225 | if (!bitmap) return new EmptyNode() |
| 226 | if (children.length <= 2 && isLeafNode(children[indx ^ 1]!)) { |
| 227 | return children[indx ^ 1]! // collapse |
| 228 | } |
| 229 | |
| 230 | newChildren = arraySpliceOut(canEdit, indx, children) |
| 231 | } else { |
| 232 | // modify |
| 233 | newChildren = arrayUpdate(canEdit, indx, child, children) |
| 234 | } |
| 235 | |
| 236 | if (canEdit) { |
| 237 | this.mask = bitmap |
| 238 | this.children = newChildren |
| 239 | return this |
| 240 | } |
| 241 | |
| 242 | return new IndexedNode(edit, bitmap, newChildren) |
| 243 | } |
| 244 | } |
| 245 | |
| 246 | /** @internal */ |
nothing calls this directly
no test coverage detected