Index stable history trees during normalization
This commit is contained in:
@@ -37,6 +37,7 @@ func (builder *historyBuilder) observeResolutionEvidence(snapshots []resolutionS
|
||||
replayGroups: coalescedResolutionSnapshots(snapshots),
|
||||
}
|
||||
attributions := make([]historyAttributionRef, len(snapshots))
|
||||
lookup := buildDocumentLookup(builder.scratch)
|
||||
for recordID, snapshot := range snapshots {
|
||||
snapshot.change = cloneChange(snapshot.change)
|
||||
payload.snapshots[recordID] = snapshot
|
||||
@@ -47,7 +48,7 @@ func (builder *historyBuilder) observeResolutionEvidence(snapshots []resolutionS
|
||||
}
|
||||
attribution := builder.addAttribution(snapshot.change.Origin, snapshot.change.Reasons, snapshot.change.Dependencies)
|
||||
attributions[recordID] = attribution
|
||||
beforePath, beforeFound := historyConcretePathAt(builder.scratch, snapshot.change.Path)
|
||||
beforePath, beforeFound := historyConcretePathAt(builder.scratch, snapshot.change.Path, lookup)
|
||||
if beforeFound {
|
||||
observeResolutionSubtree(builder, snapshot.before, beforePath, snapshot.change.Path, ref, attribution, true, false)
|
||||
}
|
||||
@@ -59,9 +60,10 @@ func (builder *historyBuilder) observeResolutionEvidence(snapshots []resolutionS
|
||||
covering := payload.snapshots[group.coveringRecordID]
|
||||
replaceHistoryPath(&builder.scratch, group.change.Path, covering.after)
|
||||
}
|
||||
lookup = buildDocumentLookup(builder.scratch)
|
||||
for recordID, snapshot := range payload.snapshots {
|
||||
ref := historyPayloadRef{phase: historyPhaseResolution, id: recordID}
|
||||
afterPath, afterFound := historyConcretePathAt(builder.scratch, snapshot.change.Path)
|
||||
afterPath, afterFound := historyConcretePathAt(builder.scratch, snapshot.change.Path, lookup)
|
||||
if afterFound {
|
||||
observeResolutionSubtree(builder, snapshot.after, afterPath, snapshot.change.Path, ref, attributions[recordID], false, true)
|
||||
}
|
||||
@@ -85,7 +87,7 @@ func observeResolutionSubtree(builder *historyBuilder, root *document.Node, path
|
||||
})
|
||||
}
|
||||
|
||||
func historyConcretePathAt(root *document.Node, path Path) (Path, bool) {
|
||||
func historyConcretePathAt(root *document.Node, path Path, lookup *documentLookup) (Path, bool) {
|
||||
if root == nil || !path.valid() {
|
||||
return Path{}, false
|
||||
}
|
||||
@@ -97,17 +99,11 @@ func historyConcretePathAt(root *document.Node, path Path) (Path, bool) {
|
||||
if segment.kind == pathSegmentIndex {
|
||||
return Path{}, false
|
||||
}
|
||||
found := false
|
||||
for _, entry := range current.Mapping {
|
||||
if entry.Key == segment.key {
|
||||
current = entry.Value
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
position := lookup.find(current, segment.key)
|
||||
if position < 0 {
|
||||
return Path{}, false
|
||||
}
|
||||
current = current.Mapping[position].Value
|
||||
concrete = concrete.Key(segment.key)
|
||||
case document.Sequence:
|
||||
index, ok := schemaIndex(segment)
|
||||
|
||||
Reference in New Issue
Block a user