Upstream itchyny/gojq state of the touched files before a0fd150fb8
This commit is contained in:
1 parent
af32cf4c58
commit
33d02f2fdb
4 files changed
+82
-899
No files matched your search
@@ -7,7 +7,6 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -375,95 +374,6 @@ func TestCodeRun_RaceRegexp(t *testing.T) {
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestCodeRun_RaceInputIter(t *testing.T) {
|
||||
const n = 10
|
||||
values := make([]int, n)
|
||||
for i := range values {
|
||||
values[i] = i
|
||||
}
|
||||
query, err := gojq.Parse("input")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
code, err := gojq.Compile(query, gojq.WithInputIter(gojq.NewIter(values...)))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var seen sync.Map
|
||||
var wg sync.WaitGroup
|
||||
for range n {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
v, ok := code.Run(nil).Next()
|
||||
if !ok {
|
||||
t.Error("expected a value")
|
||||
return
|
||||
}
|
||||
if _, loaded := seen.LoadOrStore(v, struct{}{}); loaded {
|
||||
t.Errorf("input %v was consumed more than once", v)
|
||||
}
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
for i := range n {
|
||||
if _, ok := seen.Load(i); !ok {
|
||||
t.Errorf("expected input %d to be consumed", i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Building an object or an array of n elements must allocate memory
|
||||
// proportional to n, not to n squared.
|
||||
func TestCodeRun_ReduceAssignmentAllocation(t *testing.T) {
|
||||
for _, src := range []string{
|
||||
`reduce .[] as $x ({}; .[$x|tostring] = $x)`,
|
||||
`reduce .[] as $x ({}; .[$x|tostring] |= $x)`,
|
||||
`reduce .[] as $x ({}; .[$x|tostring] += 1)`,
|
||||
`reduce .[] as $x ([]; .[$x] = $x)`,
|
||||
} {
|
||||
t.Run(src, func(t *testing.T) {
|
||||
query, err := gojq.Parse(src)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
code, err := gojq.Compile(query)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
small, large := allocatedBytes(t, code, 1000), allocatedBytes(t, code, 4000)
|
||||
// Quadratic growth would be about sixteen times as much.
|
||||
if expected := small * 8; large > expected {
|
||||
t.Errorf("expected at most %v bytes for 4000 elements, got %v (%v bytes for 1000 elements)",
|
||||
expected, large, small)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func allocatedBytes(t *testing.T, code *gojq.Code, n int) uint64 {
|
||||
t.Helper()
|
||||
input := make([]any, n)
|
||||
for i := range input {
|
||||
input[i] = i
|
||||
}
|
||||
var before, after runtime.MemStats
|
||||
runtime.GC()
|
||||
runtime.ReadMemStats(&before)
|
||||
iter := code.Run(input)
|
||||
for {
|
||||
v, ok := iter.Next()
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
if err, ok := v.(error); ok {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
runtime.ReadMemStats(&after)
|
||||
return after.TotalAlloc - before.TotalAlloc
|
||||
}
|
||||
|
||||
func BenchmarkCompile(b *testing.B) {
|
||||
cnt, err := os.ReadFile("builtin.jq")
|
||||
if err != nil {
|
||||
|
||||
Reference in new issue
Block a user