github.com/vc42/parquet-go@v0.0.0-20240320194221-1a9adb5f23f5/page_bounds_test.go (about)

     1  package parquet
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"math/rand"
     7  	"testing"
     8  
     9  	"github.com/vc42/parquet-go/internal/quick"
    10  )
    11  
    12  var benchmarkBufferSizes = [...]int{
    13  	4 * 1024,
    14  	256 * 1024,
    15  	2048 * 1024,
    16  }
    17  
    18  func forEachBenchmarkBufferSize(b *testing.B, f func(*testing.B, int)) {
    19  	for _, bufferSize := range benchmarkBufferSizes {
    20  		b.Run(fmt.Sprintf("%dKiB", bufferSize/1024), func(b *testing.B) {
    21  			b.SetBytes(int64(bufferSize))
    22  			f(b, bufferSize)
    23  		})
    24  	}
    25  }
    26  
    27  func TestBoundsInt32(t *testing.T) {
    28  	err := quick.Check(func(values []int32) bool {
    29  		min := int32(0)
    30  		max := int32(0)
    31  		if len(values) > 0 {
    32  			min = values[0]
    33  			max = values[0]
    34  			for _, v := range values[1:] {
    35  				if v < min {
    36  					min = v
    37  				}
    38  				if v > max {
    39  					max = v
    40  				}
    41  			}
    42  		}
    43  		minValue, maxValue := boundsInt32(values)
    44  		return min == minValue && max == maxValue
    45  	})
    46  	if err != nil {
    47  		t.Error(err)
    48  	}
    49  }
    50  
    51  func TestBoundsInt64(t *testing.T) {
    52  	err := quick.Check(func(values []int64) bool {
    53  		min := int64(0)
    54  		max := int64(0)
    55  		if len(values) > 0 {
    56  			min = values[0]
    57  			max = values[0]
    58  			for _, v := range values[1:] {
    59  				if v < min {
    60  					min = v
    61  				}
    62  				if v > max {
    63  					max = v
    64  				}
    65  			}
    66  		}
    67  		minValue, maxValue := boundsInt64(values)
    68  		return min == minValue && max == maxValue
    69  	})
    70  	if err != nil {
    71  		t.Error(err)
    72  	}
    73  }
    74  
    75  func TestBoundsUint32(t *testing.T) {
    76  	err := quick.Check(func(values []uint32) bool {
    77  		min := uint32(0)
    78  		max := uint32(0)
    79  		if len(values) > 0 {
    80  			min = values[0]
    81  			max = values[0]
    82  			for _, v := range values[1:] {
    83  				if v < min {
    84  					min = v
    85  				}
    86  				if v > max {
    87  					max = v
    88  				}
    89  			}
    90  		}
    91  		minValue, maxValue := boundsUint32(values)
    92  		return min == minValue && max == maxValue
    93  	})
    94  	if err != nil {
    95  		t.Error(err)
    96  	}
    97  }
    98  
    99  func TestBoundsUint64(t *testing.T) {
   100  	err := quick.Check(func(values []uint64) bool {
   101  		min := uint64(0)
   102  		max := uint64(0)
   103  		if len(values) > 0 {
   104  			min = values[0]
   105  			max = values[0]
   106  			for _, v := range values[1:] {
   107  				if v < min {
   108  					min = v
   109  				}
   110  				if v > max {
   111  					max = v
   112  				}
   113  			}
   114  		}
   115  		minValue, maxValue := boundsUint64(values)
   116  		return min == minValue && max == maxValue
   117  	})
   118  	if err != nil {
   119  		t.Error(err)
   120  	}
   121  }
   122  
   123  func TestBoundsFloat32(t *testing.T) {
   124  	err := quick.Check(func(values []float32) bool {
   125  		min := float32(0)
   126  		max := float32(0)
   127  		if len(values) > 0 {
   128  			min = values[0]
   129  			max = values[0]
   130  			for _, v := range values[1:] {
   131  				if v < min {
   132  					min = v
   133  				}
   134  				if v > max {
   135  					max = v
   136  				}
   137  			}
   138  		}
   139  		minValue, maxValue := boundsFloat32(values)
   140  		return min == minValue && max == maxValue
   141  	})
   142  	if err != nil {
   143  		t.Error(err)
   144  	}
   145  }
   146  
   147  func TestBoundsFloat64(t *testing.T) {
   148  	err := quick.Check(func(values []float64) bool {
   149  		min := float64(0)
   150  		max := float64(0)
   151  		if len(values) > 0 {
   152  			min = values[0]
   153  			max = values[0]
   154  			for _, v := range values[1:] {
   155  				if v < min {
   156  					min = v
   157  				}
   158  				if v > max {
   159  					max = v
   160  				}
   161  			}
   162  		}
   163  		minValue, maxValue := boundsFloat64(values)
   164  		return min == minValue && max == maxValue
   165  	})
   166  	if err != nil {
   167  		t.Error(err)
   168  	}
   169  }
   170  
   171  func TestBoundsBE128(t *testing.T) {
   172  	err := quick.Check(func(values [][16]byte) bool {
   173  		min := [16]byte{}
   174  		max := [16]byte{}
   175  		if len(values) > 0 {
   176  			min = values[0]
   177  			max = values[0]
   178  			for _, v := range values[1:] {
   179  				if bytes.Compare(v[:], min[:]) < 0 {
   180  					min = v
   181  				}
   182  				if bytes.Compare(v[:], max[:]) > 0 {
   183  					max = v
   184  				}
   185  			}
   186  		}
   187  		minValue, maxValue := boundsBE128(values)
   188  		return (len(values) == 0 && minValue == nil && maxValue == nil) ||
   189  			(bytes.Equal(min[:], minValue) && bytes.Equal(max[:], maxValue))
   190  	})
   191  	if err != nil {
   192  		t.Error(err)
   193  	}
   194  }
   195  
   196  func TestBoundsFixedLenByteArray(t *testing.T) {
   197  	err := quick.Check(func(values []byte) bool {
   198  		min := [1]byte{}
   199  		max := [1]byte{}
   200  		if len(values) > 0 {
   201  			min[0] = values[0]
   202  			max[0] = values[0]
   203  			for _, v := range values[1:] {
   204  				if v < min[0] {
   205  					min[0] = v
   206  				}
   207  				if v > max[0] {
   208  					max[0] = v
   209  				}
   210  			}
   211  		}
   212  		minValue, maxValue := boundsFixedLenByteArray(values, 1)
   213  		return (len(values) == 0 && minValue == nil && maxValue == nil) ||
   214  			(bytes.Equal(min[:], minValue) && bytes.Equal(max[:], maxValue))
   215  	})
   216  	if err != nil {
   217  		t.Error(err)
   218  	}
   219  }
   220  
   221  func BenchmarkBoundsInt32(b *testing.B) {
   222  	forEachBenchmarkBufferSize(b, func(b *testing.B, bufferSize int) {
   223  		values := make([]int32, bufferSize/4)
   224  		prng := rand.New(rand.NewSource(1))
   225  		for i := range values {
   226  			values[i] = prng.Int31()
   227  		}
   228  		for i := 0; i < b.N; i++ {
   229  			boundsInt32(values)
   230  		}
   231  	})
   232  }
   233  
   234  func BenchmarkBoundsInt64(b *testing.B) {
   235  	forEachBenchmarkBufferSize(b, func(b *testing.B, bufferSize int) {
   236  		values := make([]int64, bufferSize/8)
   237  		prng := rand.New(rand.NewSource(1))
   238  		for i := range values {
   239  			values[i] = prng.Int63()
   240  		}
   241  		for i := 0; i < b.N; i++ {
   242  			boundsInt64(values)
   243  		}
   244  	})
   245  }
   246  
   247  func BenchmarkBoundsUint32(b *testing.B) {
   248  	forEachBenchmarkBufferSize(b, func(b *testing.B, bufferSize int) {
   249  		values := make([]uint32, bufferSize/4)
   250  		prng := rand.New(rand.NewSource(1))
   251  		for i := range values {
   252  			values[i] = prng.Uint32()
   253  		}
   254  		for i := 0; i < b.N; i++ {
   255  			boundsUint32(values)
   256  		}
   257  	})
   258  }
   259  
   260  func BenchmarkBoundsUint64(b *testing.B) {
   261  	forEachBenchmarkBufferSize(b, func(b *testing.B, bufferSize int) {
   262  		values := make([]uint64, bufferSize/8)
   263  		prng := rand.New(rand.NewSource(1))
   264  		for i := range values {
   265  			values[i] = prng.Uint64()
   266  		}
   267  		for i := 0; i < b.N; i++ {
   268  			boundsUint64(values)
   269  		}
   270  	})
   271  }
   272  
   273  func BenchmarkBoundsFloat32(b *testing.B) {
   274  	forEachBenchmarkBufferSize(b, func(b *testing.B, bufferSize int) {
   275  		values := make([]float32, bufferSize/4)
   276  		prng := rand.New(rand.NewSource(1))
   277  		for i := range values {
   278  			values[i] = prng.Float32()
   279  		}
   280  		for i := 0; i < b.N; i++ {
   281  			boundsFloat32(values)
   282  		}
   283  	})
   284  }
   285  
   286  func BenchmarkBoundsFloat64(b *testing.B) {
   287  	forEachBenchmarkBufferSize(b, func(b *testing.B, bufferSize int) {
   288  		values := make([]float64, bufferSize/8)
   289  		prng := rand.New(rand.NewSource(1))
   290  		for i := range values {
   291  			values[i] = prng.Float64()
   292  		}
   293  		for i := 0; i < b.N; i++ {
   294  			boundsFloat64(values)
   295  		}
   296  	})
   297  }
   298  
   299  func BenchmarkBoundsBE128(b *testing.B) {
   300  	forEachBenchmarkBufferSize(b, func(b *testing.B, bufferSize int) {
   301  		values := make([][16]byte, bufferSize)
   302  		prng := rand.New(rand.NewSource(1))
   303  		for i := range values {
   304  			prng.Read(values[i][:])
   305  		}
   306  		for i := 0; i < b.N; i++ {
   307  			boundsBE128(values)
   308  		}
   309  	})
   310  }
   311  
   312  func BenchmarkBoundsFixedLenByteArray(b *testing.B) {
   313  	forEachBenchmarkBufferSize(b, func(b *testing.B, bufferSize int) {
   314  		values := make([]byte, bufferSize)
   315  		prng := rand.New(rand.NewSource(1))
   316  		prng.Read(values)
   317  		for i := 0; i < b.N; i++ {
   318  			boundsFixedLenByteArray(values, 32)
   319  		}
   320  	})
   321  }