2023-09-14 22:30:17 +03:00
|
|
|
package main
|
|
|
|
|
2024-03-21 22:48:09 +03:00
|
|
|
import (
|
|
|
|
. "github.com/antonmedv/fx/internal/jsonx"
|
|
|
|
)
|
|
|
|
|
2023-09-15 00:25:52 +03:00
|
|
|
type search struct {
|
|
|
|
err error
|
2024-03-21 22:48:09 +03:00
|
|
|
results []*Node
|
2023-09-15 00:25:52 +03:00
|
|
|
cursor int
|
2024-03-21 22:48:09 +03:00
|
|
|
values map[*Node][]match
|
|
|
|
keys map[*Node][]match
|
2023-09-15 00:25:52 +03:00
|
|
|
}
|
|
|
|
|
2023-09-15 10:16:36 +03:00
|
|
|
func newSearch() *search {
|
2023-09-15 00:25:52 +03:00
|
|
|
return &search{
|
2024-03-21 22:48:09 +03:00
|
|
|
results: make([]*Node, 0),
|
|
|
|
values: make(map[*Node][]match),
|
|
|
|
keys: make(map[*Node][]match),
|
2023-09-15 00:25:52 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-14 22:30:17 +03:00
|
|
|
type match struct {
|
|
|
|
start, end int
|
|
|
|
index int
|
|
|
|
}
|
|
|
|
|
2023-09-15 10:03:35 +03:00
|
|
|
type piece struct {
|
2023-09-14 22:45:51 +03:00
|
|
|
b []byte
|
|
|
|
index int
|
|
|
|
}
|
|
|
|
|
2023-09-15 10:03:35 +03:00
|
|
|
func splitBytesByIndexes(b []byte, indexes []match) []piece {
|
|
|
|
out := make([]piece, 0, 1)
|
2023-09-14 22:30:17 +03:00
|
|
|
pos := 0
|
|
|
|
for _, pair := range indexes {
|
2023-09-15 10:03:35 +03:00
|
|
|
out = append(out, piece{safeSlice(b, pos, pair.start), -1})
|
|
|
|
out = append(out, piece{safeSlice(b, pair.start, pair.end), pair.index})
|
2023-09-14 22:45:51 +03:00
|
|
|
pos = pair.end
|
2023-09-14 22:30:17 +03:00
|
|
|
}
|
2023-09-15 10:03:35 +03:00
|
|
|
out = append(out, piece{safeSlice(b, pos, len(b)), -1})
|
2023-09-14 22:30:17 +03:00
|
|
|
return out
|
|
|
|
}
|
|
|
|
|
2023-09-14 22:45:51 +03:00
|
|
|
func splitIndexesToChunks(chunks [][]byte, indexes [][]int, searchIndex int) (chunkIndexes [][]match) {
|
|
|
|
chunkIndexes = make([][]match, len(chunks))
|
2023-09-14 22:30:17 +03:00
|
|
|
|
2023-09-14 22:45:51 +03:00
|
|
|
for index, idx := range indexes {
|
2023-09-14 22:30:17 +03:00
|
|
|
position := 0
|
|
|
|
for i, chunk := range chunks {
|
|
|
|
// If start index lies in this chunk
|
|
|
|
if idx[0] < position+len(chunk) {
|
|
|
|
// Calculate local start and end for this chunk
|
|
|
|
localStart := idx[0] - position
|
|
|
|
localEnd := idx[1] - position
|
|
|
|
|
|
|
|
// If the end index also lies in this chunk
|
|
|
|
if idx[1] <= position+len(chunk) {
|
2023-09-14 22:45:51 +03:00
|
|
|
chunkIndexes[i] = append(chunkIndexes[i], match{start: localStart, end: localEnd, index: searchIndex + index})
|
2023-09-14 22:30:17 +03:00
|
|
|
break
|
|
|
|
} else {
|
|
|
|
// If the end index is outside this chunk, split the index
|
2023-09-14 22:45:51 +03:00
|
|
|
chunkIndexes[i] = append(chunkIndexes[i], match{start: localStart, end: len(chunk), index: searchIndex + index})
|
2023-09-14 22:30:17 +03:00
|
|
|
|
|
|
|
// Adjust the starting index for the next chunk
|
|
|
|
idx[0] = position + len(chunk)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
position += len(chunk)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|