refactor(surface): use nodeBySeq map for lookup in _replace, drop dead params
This commit is contained in:
@@ -55,7 +55,7 @@ export interface SurfaceNode {
|
||||
export class SurfaceManager {
|
||||
/** Surface nodes in linked-list order (head to tail). Empty until first access. */
|
||||
private _nodes: SurfaceNode[] = []
|
||||
/** Map from event seq → node for O(1) lookup during replacements. */
|
||||
/** Map from event seq → node. */
|
||||
private _nodeBySeq = new Map<number, SurfaceNode>()
|
||||
/** The last processed seq. -1 forces a full rebuild on first access. */
|
||||
private _lastProcessedSeq = -1
|
||||
@@ -100,7 +100,7 @@ export class SurfaceManager {
|
||||
this._nodes.push(node)
|
||||
this._nodeBySeq.set(event.seq, node)
|
||||
} else {
|
||||
this._replace(this._nodes, this._nodeBySeq, event.seq, event.surfaceOp)
|
||||
this._replace(event.seq, event.surfaceOp)
|
||||
}
|
||||
}
|
||||
this._lastProcessedSeq = this.log.length - 1
|
||||
@@ -108,31 +108,31 @@ export class SurfaceManager {
|
||||
|
||||
/** Apply a replace operation to the in-progress surface. */
|
||||
private _replace(
|
||||
nodes: SurfaceNode[],
|
||||
nodeBySeq: Map<number, SurfaceNode>,
|
||||
newSeq: number,
|
||||
op: Extract<SurfaceOp, { op: 'replace' }>,
|
||||
): void {
|
||||
const startIdx = nodes.findIndex(n => n.seq === op.start)
|
||||
if (startIdx === -1) {
|
||||
const startNode = this._nodeBySeq.get(op.start)
|
||||
if (!startNode) {
|
||||
throw new Error(`surface replace: start seq ${op.start} not found in surface`)
|
||||
}
|
||||
const endIdx = nodes.findIndex(n => n.seq === op.end)
|
||||
if (endIdx === -1) {
|
||||
const endNode = this._nodeBySeq.get(op.end)
|
||||
if (!endNode) {
|
||||
throw new Error(`surface replace: end seq ${op.end} not found in surface`)
|
||||
}
|
||||
const startIdx = this._nodes.indexOf(startNode)
|
||||
const endIdx = this._nodes.indexOf(endNode)
|
||||
if (startIdx > endIdx) {
|
||||
throw new Error(`surface replace: start seq ${op.start} (index ${startIdx}) is after end seq ${op.end} (index ${endIdx})`)
|
||||
}
|
||||
|
||||
// Remove shadowed nodes from `[startIdx, endIdx]` inclusive.
|
||||
const count = endIdx - startIdx + 1
|
||||
const removed = nodes.splice(startIdx, count)
|
||||
for (const r of removed) nodeBySeq.delete(r.seq)
|
||||
const removed = this._nodes.splice(startIdx, count)
|
||||
for (const r of removed) this._nodeBySeq.delete(r.seq)
|
||||
|
||||
// Insert the new node where the removed range was.
|
||||
const prevNode = startIdx > 0 ? nodes[startIdx - 1] : undefined
|
||||
const nextNode = startIdx < nodes.length ? nodes[startIdx] : undefined
|
||||
const prevNode = startIdx > 0 ? this._nodes[startIdx - 1] : undefined
|
||||
const nextNode = startIdx < this._nodes.length ? this._nodes[startIdx] : undefined
|
||||
|
||||
const newNode: SurfaceNode = {
|
||||
seq: newSeq,
|
||||
@@ -141,7 +141,7 @@ export class SurfaceManager {
|
||||
}
|
||||
if (prevNode) prevNode.next = newSeq
|
||||
if (nextNode) nextNode.prev = newSeq
|
||||
nodes.splice(startIdx, 0, newNode)
|
||||
nodeBySeq.set(newSeq, newNode)
|
||||
this._nodes.splice(startIdx, 0, newNode)
|
||||
this._nodeBySeq.set(newSeq, newNode)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user