Skip to content

Commit cf28c79

Browse files
committed
Fix merging large doc with small doc.
1 parent 143a1c6 commit cf28c79

File tree

1 file changed

+47
-36
lines changed

1 file changed

+47
-36
lines changed

go/store/prolly/tree/indexed_json_diff.go

Lines changed: 47 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -44,61 +44,72 @@ func NewIndexedJsonDiffer(ctx context.Context, from, to IndexedJsonDocument) (*I
4444
differ.fromStop = differ.fromStop.parent
4545
differ.toStop = differ.toStop.parent
4646

47-
if differ.from == nil || differ.to == nil {
47+
var currentFromCursor, currentToCursor *JsonCursor
48+
if differ.from == nil {
4849
// This can happen when either document fits in a single chunk.
4950
// We don't use the chunk differ in this case, and instead we create the cursors without it.
5051
diffKey := []byte{byte(startOfValue)}
51-
currentFromCursor, err := newJsonCursorAtStartOfChunk(ctx, from.m.NodeStore, from.m.Root, diffKey)
52+
currentFromCursor, err = newJsonCursorAtStartOfChunk(ctx, from.m.NodeStore, from.m.Root, diffKey)
5253
if err != nil {
5354
return nil, err
5455
}
55-
currentToCursor, err := newJsonCursorAtStartOfChunk(ctx, to.m.NodeStore, to.m.Root, diffKey)
56+
err = advanceCursor(ctx, &currentFromCursor)
57+
if err != nil {
58+
return nil, err
59+
}
60+
}
61+
62+
if differ.to == nil {
63+
// This can happen when either document fits in a single chunk.
64+
// We don't use the chunk differ in this case, and instead we create the cursors without it.
65+
diffKey := []byte{byte(startOfValue)}
66+
currentToCursor, err = newJsonCursorAtStartOfChunk(ctx, to.m.NodeStore, to.m.Root, diffKey)
67+
if err != nil {
68+
return nil, err
69+
}
70+
err = advanceCursor(ctx, &currentToCursor)
5671
if err != nil {
5772
return nil, err
5873
}
59-
return &IndexedJsonDiffer{
60-
differ: differ,
61-
from: from,
62-
to: to,
63-
currentFromCursor: currentFromCursor,
64-
currentToCursor: currentToCursor,
65-
}, nil
6674
}
6775

6876
return &IndexedJsonDiffer{
69-
differ: differ,
70-
from: from,
71-
to: to,
77+
differ: differ,
78+
from: from,
79+
to: to,
80+
currentFromCursor: currentFromCursor,
81+
currentToCursor: currentToCursor,
7282
}, nil
7383
}
7484

85+
func advanceCursor(ctx context.Context, jCur **JsonCursor) (err error) {
86+
if (*jCur).jsonScanner.atEndOfChunk() {
87+
err = (*jCur).cur.advance(ctx)
88+
if err != nil {
89+
return err
90+
}
91+
*jCur = nil
92+
} else {
93+
err = (*jCur).jsonScanner.AdvanceToNextLocation()
94+
if err != nil {
95+
return err
96+
}
97+
}
98+
return nil
99+
}
100+
75101
// Next computes the next diff between the two JSON documents.
76102
// To accomplish this, it uses the underlying Differ to find chunks that have changed, and uses a pair of JsonCursors
77103
// to walk corresponding chunks.
78104
func (jd *IndexedJsonDiffer) Next(ctx context.Context) (diff JsonDiff, err error) {
79105
// helper function to advance a JsonCursor and set it to nil if it reaches the end of a chunk
80-
advanceCursor := func(jCur **JsonCursor) (err error) {
81-
if (*jCur).jsonScanner.atEndOfChunk() {
82-
err = (*jCur).cur.advance(ctx)
83-
if err != nil {
84-
return err
85-
}
86-
*jCur = nil
87-
} else {
88-
err = (*jCur).jsonScanner.AdvanceToNextLocation()
89-
if err != nil {
90-
return err
91-
}
92-
}
93-
return nil
94-
}
95106

96107
newAddedDiff := func(key []byte) (JsonDiff, error) {
97108
addedValue, err := jd.currentToCursor.NextValue(ctx)
98109
if err != nil {
99110
return JsonDiff{}, err
100111
}
101-
err = advanceCursor(&jd.currentToCursor)
112+
err = advanceCursor(ctx, &jd.currentToCursor)
102113
if err != nil {
103114
return JsonDiff{}, err
104115
}
@@ -114,7 +125,7 @@ func (jd *IndexedJsonDiffer) Next(ctx context.Context) (diff JsonDiff, err error
114125
if err != nil {
115126
return JsonDiff{}, err
116127
}
117-
err = advanceCursor(&jd.currentFromCursor)
128+
err = advanceCursor(ctx, &jd.currentFromCursor)
118129
if err != nil {
119130
return JsonDiff{}, err
120131
}
@@ -158,7 +169,7 @@ func (jd *IndexedJsonDiffer) Next(ctx context.Context) (diff JsonDiff, err error
158169
return JsonDiff{}, err
159170
}
160171

161-
err = advanceCursor(&jd.currentFromCursor)
172+
err = advanceCursor(ctx, &jd.currentFromCursor)
162173
if err != nil {
163174
return JsonDiff{}, err
164175
}
@@ -172,7 +183,7 @@ func (jd *IndexedJsonDiffer) Next(ctx context.Context) (diff JsonDiff, err error
172183
return JsonDiff{}, err
173184
}
174185

175-
err = advanceCursor(&jd.currentToCursor)
186+
err = advanceCursor(ctx, &jd.currentToCursor)
176187
if err != nil {
177188
return JsonDiff{}, err
178189
}
@@ -209,11 +220,11 @@ func (jd *IndexedJsonDiffer) Next(ctx context.Context) (diff JsonDiff, err error
209220
if compareJsonLocations(fromCurrentLocation, toCurrentLocation) != 0 {
210221
return JsonDiff{}, jsonParseError
211222
}
212-
err = advanceCursor(&jd.currentFromCursor)
223+
err = advanceCursor(ctx, &jd.currentFromCursor)
213224
if err != nil {
214225
return JsonDiff{}, err
215226
}
216-
err = advanceCursor(&jd.currentToCursor)
227+
err = advanceCursor(ctx, &jd.currentToCursor)
217228
if err != nil {
218229
return JsonDiff{}, err
219230
}
@@ -230,11 +241,11 @@ func (jd *IndexedJsonDiffer) Next(ctx context.Context) (diff JsonDiff, err error
230241
// Otherwise, compare them and possibly return a modification.
231242
if (fromScanner.current() == '{' && toScanner.current() == '{') ||
232243
(fromScanner.current() == '[' && toScanner.current() == '[') {
233-
err = advanceCursor(&jd.currentFromCursor)
244+
err = advanceCursor(ctx, &jd.currentFromCursor)
234245
if err != nil {
235246
return JsonDiff{}, err
236247
}
237-
err = advanceCursor(&jd.currentToCursor)
248+
err = advanceCursor(ctx, &jd.currentToCursor)
238249
if err != nil {
239250
return JsonDiff{}, err
240251
}

0 commit comments

Comments
 (0)