Skip to content

Commit e951ee4

Browse files
committed
chore: fix hashmap modify
1 parent c958ba2 commit e951ee4

File tree

4 files changed

+35
-16
lines changed

4 files changed

+35
-16
lines changed

.changeset/angry-trainers-remember.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@tsplus/stdlib": patch
3+
---
4+
5+
Fix HashMap Modify

packages/stdlib/_src/collections/HashMap/_internal/node.ts

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -214,15 +214,23 @@ export class IndexedNode<K, V> {
214214
const bit = toBitmap(frag)
215215
const indx = fromBitmap(mask, bit)
216216
const exists = mask & bit
217-
const current = exists ? children[indx]! : new EmptyNode<K, V>()
217+
const canEdit = canEditNode(this, edit)
218+
219+
if (!exists) {
220+
const _newChild = new EmptyNode<K, V>().modify(edit, shift + SIZE, f, hash, key, size)
221+
if (!_newChild) return this
222+
return children.length >= MAX_INDEX_NODE ?
223+
expand(edit, frag, _newChild, mask, children) :
224+
new IndexedNode(edit, mask | bit, arraySpliceIn(canEdit, indx, _newChild, children))
225+
}
226+
227+
const current = children[indx]!
218228
const child = current.modify(edit, shift + SIZE, f, hash, key, size)
219229

220230
if (current === child) return this
221-
222-
const canEdit = canEditNode(this, edit)
223231
let bitmap = mask
224232
let newChildren
225-
if (exists && isEmptyNode(child)) {
233+
if (isEmptyNode(child)) {
226234
// remove
227235
bitmap &= ~bit
228236
if (!bitmap) return new EmptyNode()
@@ -231,14 +239,6 @@ export class IndexedNode<K, V> {
231239
}
232240

233241
newChildren = arraySpliceOut(canEdit, indx, children)
234-
} else if (!exists && !isEmptyNode(child)) {
235-
// add
236-
if (children.length >= MAX_INDEX_NODE) {
237-
return expand(edit, frag, child, mask, children)
238-
}
239-
240-
bitmap |= bit
241-
newChildren = arraySpliceIn(canEdit, indx, child, children)
242242
} else {
243243
// modify
244244
newChildren = arrayUpdate(canEdit, indx, child, children)
@@ -249,6 +249,7 @@ export class IndexedNode<K, V> {
249249
this.children = newChildren
250250
return this
251251
}
252+
252253
return new IndexedNode(edit, bitmap, newChildren)
253254
}
254255
}

packages/stdlib/_test/Differ.test.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
1+
import { it as it_ } from "vitest"
2+
13
function diffLaws<Value, Patch>(
24
differ: Differ<Value, Patch>,
35
gen: () => Value,
46
equal: (a: Value, b: Value) => boolean
57
): void {
8+
const it = (name: string, f: () => void) =>
9+
it_(name, () => {
10+
for (let i = 0; i < 100; i++) {
11+
f()
12+
}
13+
})
614
describe.concurrent("differ laws", () => {
715
it("combining patches is associative", () => {
816
const value1 = gen()
@@ -57,9 +65,9 @@ function randomChunk(): Chunk<number> {
5765
return Chunk.fill(20, smallInt)
5866
}
5967

60-
// function randomHashMap(): HashMap<number, number> {
61-
// return HashMap.from(Chunk.fill(20, smallInt).zip(Chunk.fill(20, smallInt)))
62-
// }
68+
function randomHashMap(): HashMap<number, number> {
69+
return HashMap.from(Chunk.fill(2, smallInt).zip(Chunk.fill(2, smallInt)))
70+
}
6371

6472
function randomHashSet(): HashSet<number> {
6573
return HashSet.from(Chunk.fill(20, smallInt))
@@ -93,7 +101,7 @@ describe.concurrent("Differ", () => {
93101
describe.concurrent("hashMap", () => {
94102
diffLaws(
95103
Differ.hashMap<number, number, (n: number) => number>(Differ.update<number>()),
96-
() => HashMap(Tuple(1, 2), Tuple(3, 4), Tuple(5, 6)),
104+
randomHashMap,
97105
Equals.equals
98106
)
99107
})

packages/stdlib/_test/HashMap.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,11 @@ describe.concurrent("HashMap", () => {
287287
assert.isTrue(result[key(1)] == Maybe.some(value("b")))
288288
})
289289

290+
it("remove non existing key doesn't change the array", () => {
291+
const map = HashMap(Tuple(13, 95), Tuple(90, 4))
292+
assert.deepEqual(map.remove(75).keySet.toArray, map.keySet.toArray)
293+
})
294+
290295
it("removeMany", () => {
291296
const hashMap = HashMap(Tuple(key(0), value("a")), Tuple(key(1), value("b")))
292297

0 commit comments

Comments
 (0)