[am] fixed tests

This commit is contained in:
Kevin Jahns
2025-04-12 16:12:00 +02:00
parent a6ae65d32c
commit 8908bd21dc
5 changed files with 23 additions and 14 deletions

8
package-lock.json generated
View File

@@ -9,7 +9,7 @@
"version": "13.6.27", "version": "13.6.27",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"lib0": "^0.2.103", "lib0": "^0.2.104",
"y-protocols": "^1.0.5" "y-protocols": "^1.0.5"
}, },
"devDependencies": { "devDependencies": {
@@ -2773,9 +2773,9 @@
} }
}, },
"node_modules/lib0": { "node_modules/lib0": {
"version": "0.2.103", "version": "0.2.104",
"resolved": "https://registry.npmjs.org/lib0/-/lib0-0.2.103.tgz", "resolved": "https://registry.npmjs.org/lib0/-/lib0-0.2.104.tgz",
"integrity": "sha512-1zT9KqSh54uEQZksnm8ONj0bclW3PrisT59nhgY2eOV4PaCZ5Pt9MV4y4KGkNIE/5vp6yNzpYX/+5/aGvfZS5Q==", "integrity": "sha512-1tqKRANSPTcjs/yjPoKh52oRM2u5AYdd8jie8sDiN8/5kpWWiQSHUGgtB4VEXLw1chVL3QPSPp8q9RWqzSn2FA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"isomorphic.js": "^0.2.4" "isomorphic.js": "^0.2.4"

View File

@@ -86,7 +86,7 @@
}, },
"homepage": "https://docs.yjs.dev", "homepage": "https://docs.yjs.dev",
"dependencies": { "dependencies": {
"lib0": "^0.2.103", "lib0": "^0.2.104",
"y-protocols": "^1.0.5" "y-protocols": "^1.0.5"
}, },
"devDependencies": { "devDependencies": {

View File

@@ -102,7 +102,7 @@ class AttrRanges {
* Split them if necessary. After split, i must insert the retainer at a valid position. * Split them if necessary. After split, i must insert the retainer at a valid position.
* - merge items if neighbor has same attributes * - merge items if neighbor has same attributes
*/ */
for (let i = 0; i < ids.length - 1; i++) { for (let i = 0; i < ids.length - 1;) {
const range = ids[i] const range = ids[i]
const nextRange = ids[i+1] const nextRange = ids[i+1]
// find out how to split range. it must match with next range. // find out how to split range. it must match with next range.
@@ -116,6 +116,7 @@ class AttrRanges {
ids[i] = new AttrRange(range.clock, diff, range.attrs) ids[i] = new AttrRange(range.clock, diff, range.attrs)
ids.splice(i + 1, 0, new AttrRange(nextRange.clock, range.len - diff, range.attrs)) ids.splice(i + 1, 0, new AttrRange(nextRange.clock, range.len - diff, range.attrs))
} }
i++
continue continue
} }
// now we know that range.clock === nextRange.clock // now we know that range.clock === nextRange.clock
@@ -125,13 +126,15 @@ class AttrRanges {
ids[i] = new AttrRange(range.clock, smallerLen, amAttrRangeJoin(range.attrs, nextRange.attrs)) ids[i] = new AttrRange(range.clock, smallerLen, amAttrRangeJoin(range.attrs, nextRange.attrs))
if (range.len === nextRange.len) { if (range.len === nextRange.len) {
ids.splice(i + 1, 1) ids.splice(i + 1, 1)
i--
} else { } else {
ids[i + 1] = new AttrRange(range.clock + smallerLen, largerRange.len - smallerLen, largerRange.attrs) ids[i + 1] = new AttrRange(range.clock + smallerLen, largerRange.len - smallerLen, largerRange.attrs)
array.bubblesortItem(ids, i + 1, (a, b) => a.clock - b.clock) array.bubblesortItem(ids, i + 1, (a, b) => a.clock - b.clock)
} }
if (smallerLen === 0) i++
}
while (ids.length > 0 && ids[0].len === 0) {
ids.splice(0, 1)
} }
// merge items without filtering or splicing the array. // merge items without filtering or splicing the array.
// i is the current pointer // i is the current pointer
// j refers to the current insert position for the pointed item // j refers to the current insert position for the pointed item
@@ -149,7 +152,7 @@ class AttrRanges {
j++ j++
} }
} }
ids.length = ids[j - 1].len === 0 ? j - 1 : j ids.length = ids.length === 0 ? 0 : (ids[j - 1].len === 0 ? j - 1 : j)
} }
return ids return ids
} }
@@ -219,7 +222,7 @@ export class AttributionManager {
let index = findIndexInIdRanges(ranges, id.clock) let index = findIndexInIdRanges(ranges, id.clock)
if (index !== null) { if (index !== null) {
const res = [] const res = []
while (true) { while (index < ranges.length) {
let r = ranges[index] let r = ranges[index]
if (r.clock < id.clock) { if (r.clock < id.clock) {
r = new AttrRange(id.clock, r.len - (id.clock - r.clock), r.attrs) r = new AttrRange(id.clock, r.len - (id.clock - r.clock), r.attrs)

View File

@@ -33,8 +33,12 @@ const createRandomAttributionManager = (gen, clients, clockRange, attrChoices) =
const clockStart = prng.uint32(gen, 0, clockRange) const clockStart = prng.uint32(gen, 0, clockRange)
const len = prng.uint32(gen, 0, clockRange - clockStart) const len = prng.uint32(gen, 0, clockRange - clockStart)
const attrs = [prng.oneOf(gen, attrChoices)] const attrs = [prng.oneOf(gen, attrChoices)]
// maybe add another attr
if (prng.bool(gen)) { if (prng.bool(gen)) {
attrs.push(prng.oneOf(gen, attrChoices)) const a = prng.oneOf(gen, attrChoices)
if (attrs.find((attr => attr === a)) == null) {
attrs.push(a)
}
} }
attrMngr.add(client, clockStart, len, attrs) attrMngr.add(client, clockStart, len, attrs)
} }
@@ -91,7 +95,7 @@ export const testAmMerge = _tc => {
t.group('no merge of overlapping id ranges with different attributes', () => { t.group('no merge of overlapping id ranges with different attributes', () => {
compareAttributionManagers( compareAttributionManagers(
simpleConstructAttrs([[0, 1, 2, [1]], [0, 0, 2, [2]]]), simpleConstructAttrs([[0, 1, 2, [1]], [0, 0, 2, [2]]]),
simpleConstructAttrs([[0, 0, 1, [2]], [0, 1, 1, [1, 2]], [0, 2, 1, [2]]]) simpleConstructAttrs([[0, 0, 1, [2]], [0, 1, 1, [1, 2]], [0, 2, 1, [1]]])
) )
}) })
} }
@@ -101,7 +105,7 @@ export const testAmMerge = _tc => {
*/ */
export const testRepeatMergingMultipleAttrManagers = tc => { export const testRepeatMergingMultipleAttrManagers = tc => {
const clients = 4 const clients = 4
const clockRange = 100 const clockRange = 5
/** /**
* @type {Array<am.AttributionManager<number>>} * @type {Array<am.AttributionManager<number>>}
*/ */

View File

@@ -198,7 +198,9 @@ export const testRepeatMergingMultipleIdsets = tc => {
const mergedHas = merged.has(new ID(iclient, iclock)) const mergedHas = merged.has(new ID(iclient, iclock))
const oneHas = idss.some(ids => ids.has(new ID(iclient, iclock))) const oneHas = idss.some(ids => ids.has(new ID(iclient, iclock)))
t.assert(mergedHas === oneHas) t.assert(mergedHas === oneHas)
d.addToIdSet(composed, iclient, iclock, 1) if (oneHas) {
d.addToIdSet(composed, iclient, iclock, 1)
}
} }
} }
compareIdSets(merged, composed) compareIdSets(merged, composed)