Skip to content

Commit c9b6269

Browse files
committed
When reaching the end of a chunk while scanning for differences, look ahead into the next chunk to detect whether the next value is an object/array or not.
1 parent c3f4cff commit c9b6269

File tree

2 files changed

+39
-11
lines changed

2 files changed

+39
-11
lines changed

go/store/prolly/tree/indexed_json_diff.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,10 +245,24 @@ func (jd *IndexedJsonDiffer) Next(ctx context.Context) (diff JsonDiff, err error
245245
case 0:
246246
key := fromCurrentLocation.Clone().key
247247

248+
fromNextCharacter, err := jd.currentFromCursor.nextCharacter(ctx)
249+
if err == io.EOF {
250+
return JsonDiff{}, jsonParseError
251+
}
252+
if err != nil {
253+
return JsonDiff{}, err
254+
}
255+
toNextCharacter, err := jd.currentToCursor.nextCharacter(ctx)
256+
if err == io.EOF {
257+
return JsonDiff{}, jsonParseError
258+
}
259+
if err != nil {
260+
return JsonDiff{}, err
261+
}
248262
// Both sides have the same key. If they're both an object or both an array, continue.
249263
// Otherwise, compare them and possibly return a modification.
250-
if (fromScanner.current() == '{' && toScanner.current() == '{') ||
251-
(fromScanner.current() == '[' && toScanner.current() == '[') {
264+
if (fromNextCharacter == '{' && toNextCharacter == '{') ||
265+
(fromNextCharacter == '[' && toNextCharacter == '[') {
252266
err = advanceCursor(ctx, &jd.currentFromCursor)
253267
if err != nil {
254268
return JsonDiff{}, err

go/store/prolly/tree/json_cursor.go

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -195,20 +195,28 @@ func (j *JsonCursor) AdvanceToLocation(ctx context.Context, path jsonLocation, f
195195
return true, nil
196196
}
197197

198+
func (j *JsonCursor) advanceCursor(ctx context.Context) error {
199+
err := j.cur.advance(ctx)
200+
if err != nil {
201+
return err
202+
}
203+
if !j.cur.Valid() {
204+
// We hit the end of the tree. This shouldn't happen.
205+
return io.EOF
206+
}
207+
j.jsonScanner = ScanJsonFromMiddle(j.cur.currentValue(), j.jsonScanner.currentPath)
208+
return nil
209+
}
210+
198211
func (j *JsonCursor) AdvanceToNextLocation(ctx context.Context) (crossedBoundary bool, err error) {
199212
err = j.jsonScanner.AdvanceToNextLocation()
200213
if err == io.EOF {
201214
crossedBoundary = true
202215
// We hit the end of the chunk, load the next one
203-
err = j.cur.advance(ctx)
216+
err = j.advanceCursor(ctx)
204217
if err != nil {
205-
return
206-
}
207-
if !j.cur.Valid() {
208-
// We hit the end of the tree. This shouldn't happen.
209-
return true, io.EOF
218+
return false, err
210219
}
211-
j.jsonScanner = ScanJsonFromMiddle(j.cur.currentValue(), j.jsonScanner.currentPath)
212220
return true, j.jsonScanner.AdvanceToNextLocation()
213221
} else if err != nil {
214222
return
@@ -221,6 +229,12 @@ func (j *JsonCursor) GetCurrentPath() jsonLocation {
221229
return j.jsonScanner.currentPath
222230
}
223231

224-
func (j *JsonCursor) nextCharacter() byte {
225-
return j.jsonScanner.jsonBuffer[j.jsonScanner.valueOffset]
232+
func (j *JsonCursor) nextCharacter(ctx context.Context) (byte, error) {
233+
if j.jsonScanner.atEndOfChunk() {
234+
err := j.advanceCursor(ctx)
235+
if err != nil {
236+
return 255, err
237+
}
238+
}
239+
return j.jsonScanner.jsonBuffer[j.jsonScanner.valueOffset], nil
226240
}

0 commit comments

Comments
 (0)