package parquet

import (
	
	
	

	
	
	
	
)

// Page values represent sequences of parquet values. From the Parquet
// documentation: "Column chunks are a chunk of the data for a particular
// column. They live in a particular row group and are guaranteed to be
// contiguous in the file. Column chunks are divided up into pages. A page is
// conceptually an indivisible unit (in terms of compression and encoding).
// There can be multiple page types which are interleaved in a column chunk."
//
// https://github.com/apache/parquet-format#glossary
type Page interface {
	// Returns the type of values read from this page.
	//
	// The returned type can be used to encode the page data, in the case of
	// an indexed page (which has a dictionary), the type is configured to
	// encode the indexes stored in the page rather than the plain values.
	Type() Type

	// Returns the column index that this page belongs to.
	Column() int

	// If the page contains indexed values, calling this method returns the
	// dictionary in which the values are looked up. Otherwise, the method
	// returns nil.
	Dictionary() Dictionary

	// Returns the number of rows, values, and nulls in the page. The number of
	// rows may be less than the number of values in the page if the page is
	// part of a repeated column.
	NumRows() int64
	NumValues() int64
	NumNulls() int64

	// Returns the page's min and max values.
	//
	// The third value is a boolean indicating whether the page bounds were
	// available. Page bounds may not be known if the page contained no values
	// or only nulls, or if they were read from a parquet file which had neither
	// page statistics nor a page index.
	Bounds() (min, max Value, ok bool)

	// Returns the size of the page in bytes (uncompressed).
	Size() int64

	// Returns a reader exposing the values contained in the page.
	//
	// Depending on the underlying implementation, the returned reader may
	// support reading an array of typed Go values by implementing interfaces
	// like parquet.Int32Reader. Applications should use type assertions on
	// the returned reader to determine whether those optimizations are
	// available.
	Values() ValueReader

	// Returns a new page which is as slice of the receiver between row indexes
	// i and j.
	Slice(i, j int64) Page

	// Expose the lists of repetition and definition levels of the page.
	//
	// The returned slices may be empty when the page has no repetition or
	// definition levels.
	RepetitionLevels() []byte
	DefinitionLevels() []byte

	// Returns the in-memory buffer holding the page values.
	//
	// The intent is for the returned value to be used as input parameter when
	// calling the Encode method of the associated Type.
	//
	// The slices referenced by the encoding.Values may be the same across
	// multiple calls to this method, applications must treat the content as
	// immutable.
	Data() encoding.Values
}

// PageReader is an interface implemented by types that support producing a
// sequence of pages.
type PageReader interface {
	// Reads and returns the next page from the sequence. When all pages have
	// been read, or if the sequence was closed, the method returns io.EOF.
	ReadPage() (Page, error)
}

// PageWriter is an interface implemented by types that support writing pages
// to an underlying storage medium.
type PageWriter interface {
	WritePage(Page) (int64, error)
}

// Pages is an interface implemented by page readers returned by calling the
// Pages method of ColumnChunk instances.
type Pages interface {
	PageReader
	RowSeeker
	io.Closer
}

// AsyncPages wraps the given Pages instance to perform page reads
// asynchronously in a separate goroutine.
//
// Performing page reads asynchronously is important when the application may
// be reading pages from a high latency backend, and the last
// page read may be processed while initiating reading of the next page.
func ( Pages) Pages {
	 := new(asyncPages)
	.init(, nil)
	// If the pages object gets garbage collected without Close being called,
	// this finalizer would ensure that the goroutine is stopped and doesn't
	// leak.
	debug.SetFinalizer(, func( *asyncPages) { .Close() })
	return 
}

type asyncPages struct {
	read    <-chan asyncPage
	seek    chan<- int64
	done    chan<- struct{}
	version int64
}

type asyncPage struct {
	page    Page
	err     error
	version int64
}

func ( *asyncPages) ( Pages,  chan struct{}) {
	 := make(chan asyncPage)
	 := make(chan int64, 1)

	.read = 
	.seek = 

	if  == nil {
		 = make(chan struct{})
		.done = 
	}

	go readPages(, , , )
}

func ( *asyncPages) () ( error) {
	if .done != nil {
		close(.done)
		.done = nil
	}
	for  := range .read {
		// Capture the last error, which is the value returned from closing the
		// underlying Pages instance.
		 = .err
	}
	.seek = nil
	return 
}

func ( *asyncPages) () (Page, error) {
	for {
		,  := <-.read
		if ! {
			return nil, io.EOF
		}
		// Because calls to SeekToRow might be made concurrently to reading
		// pages, it is possible for ReadPage to see pages that were read before
		// the last SeekToRow call.
		//
		// A version number is attached to each page read asynchronously to
		// discard outdated pages and ensure that we maintain a consistent view
		// of the sequence of pages read.
		if .version == .version {
			return .page, .err
		}
	}
}

func ( *asyncPages) ( int64) error {
	if .seek == nil {
		return io.ErrClosedPipe
	}
	// The seek channel has a capacity of 1 to allow the first SeekToRow call to
	// be non-blocking.
	//
	// If SeekToRow calls are performed faster than they can be handled by the
	// goroutine reading pages, this path might become a contention point.
	.seek <- 
	.version++
	return nil
}

func readPages( Pages,  chan<- asyncPage,  <-chan int64,  <-chan struct{}) {
	defer func() {
		 <- asyncPage{err: .Close(), version: -1}
		close()
	}()

	 := int64(0)
	for {
		,  := .ReadPage()

		for {
			select {
			case <-:
				return
			case  <- asyncPage{
				page:    ,
				err:     ,
				version: ,
			}:
			case  := <-:
				++
				 = .SeekToRow()
			}
			if  == nil {
				break
			}
		}
	}
}

type singlePage struct {
	page    Page
	seek    int64
	numRows int64
}

func ( *singlePage) () (Page, error) {
	if .page != nil {
		if .seek < .numRows {
			 := .seek
			.seek = .numRows
			if  > 0 {
				return .page.Slice(, .numRows), nil
			}
			return .page, nil
		}
	}
	return nil, io.EOF
}

func ( *singlePage) ( int64) error {
	.seek = 
	return nil
}

func ( *singlePage) () error {
	.page = nil
	.seek = 0
	return nil
}

func onePage( Page) Pages {
	return &singlePage{page: , numRows: .NumRows()}
}

// CopyPages copies pages from src to dst, returning the number of values that
// were copied.
//
// The function returns any error it encounters reading or writing pages, except
// for io.EOF from the reader which indicates that there were no more pages to
// read.
func ( PageWriter,  PageReader) ( int64,  error) {
	for {
		,  := .ReadPage()
		if  != nil {
			if  == io.EOF {
				 = nil
			}
			return , 
		}
		,  := .WritePage()
		 += 
		if  != nil {
			return , 
		}
	}
}

// errorPage is an implementation of the Page interface which always errors when
// attempting to read its values.
//
// The error page declares that it contains one value (even if it does not)
// as a way to ensure that it is not ignored due to being empty when written
// to a file.
type errorPage struct {
	typ         Type
	err         error
	columnIndex int
}

func newErrorPage( Type,  int,  string,  ...interface{}) *errorPage {
	return &errorPage{
		typ:         ,
		err:         fmt.Errorf(, ...),
		columnIndex: ,
	}
}

func ( *errorPage) () Type                        { return .typ }
func ( *errorPage) () int                       { return .columnIndex }
func ( *errorPage) () Dictionary            { return nil }
func ( *errorPage) () int64                    { return 1 }
func ( *errorPage) () int64                  { return 1 }
func ( *errorPage) () int64                   { return 0 }
func ( *errorPage) () (,  Value,  bool) { return }
func ( *errorPage) (,  int64) Page             { return  }
func ( *errorPage) () int64                       { return 1 }
func ( *errorPage) () []byte          { return nil }
func ( *errorPage) () []byte          { return nil }
func ( *errorPage) () encoding.Values             { return encoding.Values{} }
func ( *errorPage) () ValueReader               { return errorPageValues{page: } }

type errorPageValues struct{ page *errorPage }

func ( errorPageValues) ([]Value) (int, error) { return 0, .page.err }
func ( errorPageValues) () error                    { return nil }

func errPageBoundsOutOfRange(, ,  int64) error {
	return fmt.Errorf("page bounds out of range [%d:%d]: with length %d", , , )
}

type optionalPage struct {
	base               Page
	maxDefinitionLevel byte
	definitionLevels   []byte
}

func newOptionalPage( Page,  byte,  []byte) *optionalPage {
	return &optionalPage{
		base:               ,
		maxDefinitionLevel: ,
		definitionLevels:   ,
	}
}

func ( *optionalPage) () Type { return .base.Type() }

func ( *optionalPage) () int { return .base.Column() }

func ( *optionalPage) () Dictionary { return .base.Dictionary() }

func ( *optionalPage) () int64 { return int64(len(.definitionLevels)) }

func ( *optionalPage) () int64 { return int64(len(.definitionLevels)) }

func ( *optionalPage) () int64 {
	return int64(countLevelsNotEqual(.definitionLevels, .maxDefinitionLevel))
}

func ( *optionalPage) () (,  Value,  bool) { return .base.Bounds() }

func ( *optionalPage) () int64 { return int64(len(.definitionLevels)) + .base.Size() }

func ( *optionalPage) () []byte { return nil }

func ( *optionalPage) () []byte { return .definitionLevels }

func ( *optionalPage) () encoding.Values { return .base.Data() }

func ( *optionalPage) () ValueReader {
	return &optionalPageValues{
		page:   ,
		values: .base.Values(),
	}
}

func ( *optionalPage) (,  int64) Page {
	 := .maxDefinitionLevel
	 := .definitionLevels
	 := int64(countLevelsNotEqual([:], ))
	 := int64(countLevelsNotEqual([:], ))
	return newOptionalPage(
		.base.Slice(-, -(+)),
		,
		[::],
	)
}

type repeatedPage struct {
	base               Page
	maxRepetitionLevel byte
	maxDefinitionLevel byte
	definitionLevels   []byte
	repetitionLevels   []byte
}

func newRepeatedPage( Page, ,  byte, ,  []byte) *repeatedPage {
	return &repeatedPage{
		base:               ,
		maxRepetitionLevel: ,
		maxDefinitionLevel: ,
		definitionLevels:   ,
		repetitionLevels:   ,
	}
}

func ( *repeatedPage) () Type { return .base.Type() }

func ( *repeatedPage) () int { return .base.Column() }

func ( *repeatedPage) () Dictionary { return .base.Dictionary() }

func ( *repeatedPage) () int64 { return int64(countLevelsEqual(.repetitionLevels, 0)) }

func ( *repeatedPage) () int64 { return int64(len(.definitionLevels)) }

func ( *repeatedPage) () int64 {
	return int64(countLevelsNotEqual(.definitionLevels, .maxDefinitionLevel))
}

func ( *repeatedPage) () (,  Value,  bool) { return .base.Bounds() }

func ( *repeatedPage) () int64 {
	return int64(len(.repetitionLevels)) + int64(len(.definitionLevels)) + .base.Size()
}

func ( *repeatedPage) () []byte { return .repetitionLevels }

func ( *repeatedPage) () []byte { return .definitionLevels }

func ( *repeatedPage) () encoding.Values { return .base.Data() }

func ( *repeatedPage) () ValueReader {
	return &repeatedPageValues{
		page:   ,
		values: .base.Values(),
	}
}

func ( *repeatedPage) (,  int64) Page {
	 := .NumRows()
	if  < 0 ||  >  {
		panic(errPageBoundsOutOfRange(, , ))
	}
	if  < 0 ||  >  {
		panic(errPageBoundsOutOfRange(, , ))
	}
	if  >  {
		panic(errPageBoundsOutOfRange(, , ))
	}

	 := .maxRepetitionLevel
	 := .maxDefinitionLevel
	 := .repetitionLevels
	 := .definitionLevels

	 := 0
	 := len()
	 := len()

	for ,  := range  {
		if  == 0 {
			if  == int() {
				 = 
				break
			}
			++
		}
	}

	for ,  := range [:] {
		if  == 0 {
			if  == int() {
				 =  + 
				break
			}
			++
		}
	}

	 := countLevelsNotEqual([:], )
	 := countLevelsNotEqual([:], )

	 = int64( - )
	 = int64( - ( + ))

	return newRepeatedPage(
		.base.Slice(, ),
		,
		,
		[::],
		[::],
	)
}

type booleanPage struct {
	typ         Type
	bits        []byte
	offset      int32
	numValues   int32
	columnIndex int16
}

func newBooleanPage( Type,  int16,  int32,  encoding.Values) *booleanPage {
	return &booleanPage{
		typ:         ,
		bits:        .Boolean()[:bitpack.ByteCount(uint())],
		numValues:   ,
		columnIndex: ^,
	}
}

func ( *booleanPage) () Type { return .typ }

func ( *booleanPage) () int { return int(^.columnIndex) }

func ( *booleanPage) () Dictionary { return nil }

func ( *booleanPage) () int64 { return int64(.numValues) }

func ( *booleanPage) () int64 { return int64(.numValues) }

func ( *booleanPage) () int64 { return 0 }

func ( *booleanPage) () int64 { return int64(len(.bits)) }

func ( *booleanPage) () []byte { return nil }

func ( *booleanPage) () []byte { return nil }

func ( *booleanPage) () encoding.Values { return encoding.BooleanValues(.bits) }

func ( *booleanPage) () ValueReader { return &booleanPageValues{page: } }

func ( *booleanPage) ( int) bool {
	 := uint32(int(.offset)+) / 8
	 := uint32(int(.offset)+) % 8
	return ((.bits[] >> ) & 1) != 0
}

func ( *booleanPage) () bool {
	for  := 0;  < int(.numValues); ++ {
		if !.valueAt() {
			return false
		}
	}
	return .numValues > 0
}

func ( *booleanPage) () bool {
	for  := 0;  < int(.numValues); ++ {
		if .valueAt() {
			return true
		}
	}
	return false
}

func ( *booleanPage) () (,  bool) {
	,  := false, false

	for  := 0;  < int(.numValues); ++ {
		 := .valueAt()
		if  {
			 = true
		} else {
			 = true
		}
		if  &&  {
			break
		}
	}

	 = !
	 = 
	return , 
}

func ( *booleanPage) () (,  Value,  bool) {
	if  = .numValues > 0;  {
		,  := .bounds()
		 = .makeValue()
		 = .makeValue()
	}
	return , , 
}

func ( *booleanPage) (,  int64) Page {
	 :=  + int64(.offset)
	 :=  + int64(.offset)

	 :=  / 8
	 :=  / 8

	if ( % 8) != 0 {
		++
	}

	return &booleanPage{
		typ:         .typ,
		bits:        .bits[:],
		offset:      int32( % 8),
		numValues:   int32( - ),
		columnIndex: .columnIndex,
	}
}

func ( *booleanPage) ( bool) Value {
	 := makeValueBoolean()
	.columnIndex = .columnIndex
	return 
}

type int32Page struct {
	typ         Type
	values      []int32
	columnIndex int16
}

func newInt32Page( Type,  int16,  int32,  encoding.Values) *int32Page {
	return &int32Page{
		typ:         ,
		values:      .Int32()[:],
		columnIndex: ^,
	}
}

func ( *int32Page) () Type { return .typ }

func ( *int32Page) () int { return int(^.columnIndex) }

func ( *int32Page) () Dictionary { return nil }

func ( *int32Page) () int64 { return int64(len(.values)) }

func ( *int32Page) () int64 { return int64(len(.values)) }

func ( *int32Page) () int64 { return 0 }

func ( *int32Page) () int64 { return 4 * int64(len(.values)) }

func ( *int32Page) () []byte { return nil }

func ( *int32Page) () []byte { return nil }

func ( *int32Page) () encoding.Values { return encoding.Int32Values(.values) }

func ( *int32Page) () ValueReader { return &int32PageValues{page: } }

func ( *int32Page) () int32 { return minInt32(.values) }

func ( *int32Page) () int32 { return maxInt32(.values) }

func ( *int32Page) () (,  int32) { return boundsInt32(.values) }

func ( *int32Page) () (,  Value,  bool) {
	if  = len(.values) > 0;  {
		,  := .bounds()
		 = .makeValue()
		 = .makeValue()
	}
	return , , 
}

func ( *int32Page) (,  int64) Page {
	return &int32Page{
		typ:         .typ,
		values:      .values[:],
		columnIndex: .columnIndex,
	}
}

func ( *int32Page) ( int32) Value {
	 := makeValueInt32()
	.columnIndex = .columnIndex
	return 
}

type int64Page struct {
	typ         Type
	values      []int64
	columnIndex int16
}

func newInt64Page( Type,  int16,  int32,  encoding.Values) *int64Page {
	return &int64Page{
		typ:         ,
		values:      .Int64()[:],
		columnIndex: ^,
	}
}

func ( *int64Page) () Type { return .typ }

func ( *int64Page) () int { return int(^.columnIndex) }

func ( *int64Page) () Dictionary { return nil }

func ( *int64Page) () int64 { return int64(len(.values)) }

func ( *int64Page) () int64 { return int64(len(.values)) }

func ( *int64Page) () int64 { return 0 }

func ( *int64Page) () int64 { return 8 * int64(len(.values)) }

func ( *int64Page) () []byte { return nil }

func ( *int64Page) () []byte { return nil }

func ( *int64Page) () encoding.Values { return encoding.Int64Values(.values) }

func ( *int64Page) () ValueReader { return &int64PageValues{page: } }

func ( *int64Page) () int64 { return minInt64(.values) }

func ( *int64Page) () int64 { return maxInt64(.values) }

func ( *int64Page) () (,  int64) { return boundsInt64(.values) }

func ( *int64Page) () (,  Value,  bool) {
	if  = len(.values) > 0;  {
		,  := .bounds()
		 = .makeValue()
		 = .makeValue()
	}
	return , , 
}

func ( *int64Page) (,  int64) Page {
	return &int64Page{
		typ:         .typ,
		values:      .values[:],
		columnIndex: .columnIndex,
	}
}

func ( *int64Page) ( int64) Value {
	 := makeValueInt64()
	.columnIndex = .columnIndex
	return 
}

type int96Page struct {
	typ         Type
	values      []deprecated.Int96
	columnIndex int16
}

func newInt96Page( Type,  int16,  int32,  encoding.Values) *int96Page {
	return &int96Page{
		typ:         ,
		values:      .Int96()[:],
		columnIndex: ^,
	}
}

func ( *int96Page) () Type { return .typ }

func ( *int96Page) () int { return int(^.columnIndex) }

func ( *int96Page) () Dictionary { return nil }

func ( *int96Page) () int64 { return int64(len(.values)) }

func ( *int96Page) () int64 { return int64(len(.values)) }

func ( *int96Page) () int64 { return 0 }

func ( *int96Page) () int64 { return 12 * int64(len(.values)) }

func ( *int96Page) () []byte { return nil }

func ( *int96Page) () []byte { return nil }

func ( *int96Page) () encoding.Values { return encoding.Int96Values(.values) }

func ( *int96Page) () ValueReader { return &int96PageValues{page: } }

func ( *int96Page) () deprecated.Int96 { return deprecated.MinInt96(.values) }

func ( *int96Page) () deprecated.Int96 { return deprecated.MaxInt96(.values) }

func ( *int96Page) () (,  deprecated.Int96) {
	return deprecated.MinMaxInt96(.values)
}

func ( *int96Page) () (,  Value,  bool) {
	if  = len(.values) > 0;  {
		,  := .bounds()
		 = .makeValue()
		 = .makeValue()
	}
	return , , 
}

func ( *int96Page) (,  int64) Page {
	return &int96Page{
		typ:         .typ,
		values:      .values[:],
		columnIndex: .columnIndex,
	}
}

func ( *int96Page) ( deprecated.Int96) Value {
	 := makeValueInt96()
	.columnIndex = .columnIndex
	return 
}

type floatPage struct {
	typ         Type
	values      []float32
	columnIndex int16
}

func newFloatPage( Type,  int16,  int32,  encoding.Values) *floatPage {
	return &floatPage{
		typ:         ,
		values:      .Float()[:],
		columnIndex: ^,
	}
}

func ( *floatPage) () Type { return .typ }

func ( *floatPage) () int { return int(^.columnIndex) }

func ( *floatPage) () Dictionary { return nil }

func ( *floatPage) () int64 { return int64(len(.values)) }

func ( *floatPage) () int64 { return int64(len(.values)) }

func ( *floatPage) () int64 { return 0 }

func ( *floatPage) () int64 { return 4 * int64(len(.values)) }

func ( *floatPage) () []byte { return nil }

func ( *floatPage) () []byte { return nil }

func ( *floatPage) () encoding.Values { return encoding.FloatValues(.values) }

func ( *floatPage) () ValueReader { return &floatPageValues{page: } }

func ( *floatPage) () float32 { return minFloat32(.values) }

func ( *floatPage) () float32 { return maxFloat32(.values) }

func ( *floatPage) () (,  float32) { return boundsFloat32(.values) }

func ( *floatPage) () (,  Value,  bool) {
	if  = len(.values) > 0;  {
		,  := .bounds()
		 = .makeValue()
		 = .makeValue()
	}
	return , , 
}

func ( *floatPage) (,  int64) Page {
	return &floatPage{
		typ:         .typ,
		values:      .values[:],
		columnIndex: .columnIndex,
	}
}

func ( *floatPage) ( float32) Value {
	 := makeValueFloat()
	.columnIndex = .columnIndex
	return 
}

type doublePage struct {
	typ         Type
	values      []float64
	columnIndex int16
}

func newDoublePage( Type,  int16,  int32,  encoding.Values) *doublePage {
	return &doublePage{
		typ:         ,
		values:      .Double()[:],
		columnIndex: ^,
	}
}

func ( *doublePage) () Type { return .typ }

func ( *doublePage) () int { return int(^.columnIndex) }

func ( *doublePage) () Dictionary { return nil }

func ( *doublePage) () int64 { return int64(len(.values)) }

func ( *doublePage) () int64 { return int64(len(.values)) }

func ( *doublePage) () int64 { return 0 }

func ( *doublePage) () int64 { return 8 * int64(len(.values)) }

func ( *doublePage) () []byte { return nil }

func ( *doublePage) () []byte { return nil }

func ( *doublePage) () encoding.Values { return encoding.DoubleValues(.values) }

func ( *doublePage) () ValueReader { return &doublePageValues{page: } }

func ( *doublePage) () float64 { return minFloat64(.values) }

func ( *doublePage) () float64 { return maxFloat64(.values) }

func ( *doublePage) () (,  float64) { return boundsFloat64(.values) }

func ( *doublePage) () (,  Value,  bool) {
	if  = len(.values) > 0;  {
		,  := .bounds()
		 = .makeValue()
		 = .makeValue()
	}
	return , , 
}

func ( *doublePage) (,  int64) Page {
	return &doublePage{
		typ:         .typ,
		values:      .values[:],
		columnIndex: .columnIndex,
	}
}

func ( *doublePage) ( float64) Value {
	 := makeValueDouble()
	.columnIndex = .columnIndex
	return 
}

type byteArrayPage struct {
	typ         Type
	values      []byte
	offsets     []uint32
	columnIndex int16
}

func newByteArrayPage( Type,  int16,  int32,  encoding.Values) *byteArrayPage {
	,  := .ByteArray()
	return &byteArrayPage{
		typ:         ,
		values:      ,
		offsets:     [:+1],
		columnIndex: ^,
	}
}

func ( *byteArrayPage) () Type { return .typ }

func ( *byteArrayPage) () int { return int(^.columnIndex) }

func ( *byteArrayPage) () Dictionary { return nil }

func ( *byteArrayPage) () int64 { return int64(.len()) }

func ( *byteArrayPage) () int64 { return int64(.len()) }

func ( *byteArrayPage) () int64 { return 0 }

func ( *byteArrayPage) () int64 { return int64(len(.values)) + 4*int64(len(.offsets)) }

func ( *byteArrayPage) () []byte { return nil }

func ( *byteArrayPage) () []byte { return nil }

func ( *byteArrayPage) () encoding.Values {
	return encoding.ByteArrayValues(.values, .offsets)
}

func ( *byteArrayPage) () ValueReader { return &byteArrayPageValues{page: } }

func ( *byteArrayPage) () int { return len(.offsets) - 1 }

func ( *byteArrayPage) ( int) []byte {
	 := .offsets[+0]
	 := .offsets[+1]
	return .values[::]
}

func ( *byteArrayPage) () ( []byte) {
	if  := .len();  > 0 {
		 = .index(0)

		for  := 1;  < ; ++ {
			 := .index()

			if bytes.Compare(, ) < 0 {
				 = 
			}
		}
	}
	return 
}

func ( *byteArrayPage) () ( []byte) {
	if  := .len();  > 0 {
		 = .index(0)

		for  := 1;  < ; ++ {
			 := .index()

			if bytes.Compare(, ) > 0 {
				 = 
			}
		}
	}
	return 
}

func ( *byteArrayPage) () (,  []byte) {
	if  := .len();  > 0 {
		 = .index(0)
		 = 

		for  := 1;  < ; ++ {
			 := .index()

			switch {
			case bytes.Compare(, ) < 0:
				 = 
			case bytes.Compare(, ) > 0:
				 = 
			}
		}
	}
	return , 
}

func ( *byteArrayPage) () (,  Value,  bool) {
	if  = len(.offsets) > 1;  {
		,  := .bounds()
		 = .makeValueBytes()
		 = .makeValueBytes()
	}
	return , , 
}

func ( *byteArrayPage) () []byte {
	 := make([]byte, len(.values))
	copy(, .values)
	return 
}

func ( *byteArrayPage) () []uint32 {
	 := make([]uint32, len(.offsets))
	copy(, .offsets)
	return 
}

func ( *byteArrayPage) (,  int64) Page {
	return &byteArrayPage{
		typ:         .typ,
		values:      .values,
		offsets:     .offsets[ : +1],
		columnIndex: .columnIndex,
	}
}

func ( *byteArrayPage) ( []byte) Value {
	 := makeValueBytes(ByteArray, )
	.columnIndex = .columnIndex
	return 
}

func ( *byteArrayPage) ( string) Value {
	 := makeValueString(ByteArray, )
	.columnIndex = .columnIndex
	return 
}

type fixedLenByteArrayPage struct {
	typ         Type
	data        []byte
	size        int
	columnIndex int16
}

func newFixedLenByteArrayPage( Type,  int16,  int32,  encoding.Values) *fixedLenByteArrayPage {
	,  := .FixedLenByteArray()
	return &fixedLenByteArrayPage{
		typ:         ,
		data:        [:int()*],
		size:        ,
		columnIndex: ^,
	}
}

func ( *fixedLenByteArrayPage) () Type { return .typ }

func ( *fixedLenByteArrayPage) () int { return int(^.columnIndex) }

func ( *fixedLenByteArrayPage) () Dictionary { return nil }

func ( *fixedLenByteArrayPage) () int64 { return int64(len(.data) / .size) }

func ( *fixedLenByteArrayPage) () int64 { return int64(len(.data) / .size) }

func ( *fixedLenByteArrayPage) () int64 { return 0 }

func ( *fixedLenByteArrayPage) () int64 { return int64(len(.data)) }

func ( *fixedLenByteArrayPage) () []byte { return nil }

func ( *fixedLenByteArrayPage) () []byte { return nil }

func ( *fixedLenByteArrayPage) () encoding.Values {
	return encoding.FixedLenByteArrayValues(.data, .size)
}

func ( *fixedLenByteArrayPage) () ValueReader {
	return &fixedLenByteArrayPageValues{page: }
}

func ( *fixedLenByteArrayPage) () []byte { return minFixedLenByteArray(.data, .size) }

func ( *fixedLenByteArrayPage) () []byte { return maxFixedLenByteArray(.data, .size) }

func ( *fixedLenByteArrayPage) () (,  []byte) {
	return boundsFixedLenByteArray(.data, .size)
}

func ( *fixedLenByteArrayPage) () (,  Value,  bool) {
	if  = len(.data) > 0;  {
		,  := .bounds()
		 = .makeValueBytes()
		 = .makeValueBytes()
	}
	return , , 
}

func ( *fixedLenByteArrayPage) (,  int64) Page {
	return &fixedLenByteArrayPage{
		typ:         .typ,
		data:        .data[*int64(.size) : *int64(.size)],
		size:        .size,
		columnIndex: .columnIndex,
	}
}

func ( *fixedLenByteArrayPage) ( []byte) Value {
	 := makeValueBytes(FixedLenByteArray, )
	.columnIndex = .columnIndex
	return 
}

func ( *fixedLenByteArrayPage) ( string) Value {
	 := makeValueString(FixedLenByteArray, )
	.columnIndex = .columnIndex
	return 
}

type uint32Page struct {
	typ         Type
	values      []uint32
	columnIndex int16
}

func newUint32Page( Type,  int16,  int32,  encoding.Values) *uint32Page {
	return &uint32Page{
		typ:         ,
		values:      .Uint32()[:],
		columnIndex: ^,
	}
}

func ( *uint32Page) () Type { return .typ }

func ( *uint32Page) () int { return int(^.columnIndex) }

func ( *uint32Page) () Dictionary { return nil }

func ( *uint32Page) () int64 { return int64(len(.values)) }

func ( *uint32Page) () int64 { return int64(len(.values)) }

func ( *uint32Page) () int64 { return 0 }

func ( *uint32Page) () int64 { return 4 * int64(len(.values)) }

func ( *uint32Page) () []byte { return nil }

func ( *uint32Page) () []byte { return nil }

func ( *uint32Page) () encoding.Values { return encoding.Uint32Values(.values) }

func ( *uint32Page) () ValueReader { return &uint32PageValues{page: } }

func ( *uint32Page) () uint32 { return minUint32(.values) }

func ( *uint32Page) () uint32 { return maxUint32(.values) }

func ( *uint32Page) () (,  uint32) { return boundsUint32(.values) }

func ( *uint32Page) () (,  Value,  bool) {
	if  = len(.values) > 0;  {
		,  := .bounds()
		 = .makeValue()
		 = .makeValue()
	}
	return , , 
}

func ( *uint32Page) (,  int64) Page {
	return &uint32Page{
		typ:         .typ,
		values:      .values[:],
		columnIndex: .columnIndex,
	}
}

func ( *uint32Page) ( uint32) Value {
	 := makeValueUint32()
	.columnIndex = .columnIndex
	return 
}

type uint64Page struct {
	typ         Type
	values      []uint64
	columnIndex int16
}

func newUint64Page( Type,  int16,  int32,  encoding.Values) *uint64Page {
	return &uint64Page{
		typ:         ,
		values:      .Uint64()[:],
		columnIndex: ^,
	}
}

func ( *uint64Page) () Type { return .typ }

func ( *uint64Page) () int { return int(^.columnIndex) }

func ( *uint64Page) () Dictionary { return nil }

func ( *uint64Page) () int64 { return int64(len(.values)) }

func ( *uint64Page) () int64 { return int64(len(.values)) }

func ( *uint64Page) () int64 { return 0 }

func ( *uint64Page) () int64 { return 8 * int64(len(.values)) }

func ( *uint64Page) () []byte { return nil }

func ( *uint64Page) () []byte { return nil }

func ( *uint64Page) () encoding.Values { return encoding.Uint64Values(.values) }

func ( *uint64Page) () ValueReader { return &uint64PageValues{page: } }

func ( *uint64Page) () uint64 { return minUint64(.values) }

func ( *uint64Page) () uint64 { return maxUint64(.values) }

func ( *uint64Page) () (,  uint64) { return boundsUint64(.values) }

func ( *uint64Page) () (,  Value,  bool) {
	if  = len(.values) > 0;  {
		,  := .bounds()
		 = .makeValue()
		 = .makeValue()
	}
	return , , 
}

func ( *uint64Page) (,  int64) Page {
	return &uint64Page{
		typ:         .typ,
		values:      .values[:],
		columnIndex: .columnIndex,
	}
}

func ( *uint64Page) ( uint64) Value {
	 := makeValueUint64()
	.columnIndex = .columnIndex
	return 
}

type be128Page struct {
	typ         Type
	values      [][16]byte
	columnIndex int16
}

func newBE128Page( Type,  int16,  int32,  encoding.Values) *be128Page {
	return &be128Page{
		typ:         ,
		values:      .Uint128()[:],
		columnIndex: ^,
	}
}

func ( *be128Page) () Type { return .typ }

func ( *be128Page) () int { return int(^.columnIndex) }

func ( *be128Page) () Dictionary { return nil }

func ( *be128Page) () int64 { return int64(len(.values)) }

func ( *be128Page) () int64 { return int64(len(.values)) }

func ( *be128Page) () int64 { return 0 }

func ( *be128Page) () int64 { return 16 * int64(len(.values)) }

func ( *be128Page) () []byte { return nil }

func ( *be128Page) () []byte { return nil }

func ( *be128Page) () encoding.Values { return encoding.Uint128Values(.values) }

func ( *be128Page) () ValueReader { return &be128PageValues{page: } }

func ( *be128Page) () []byte { return minBE128(.values) }

func ( *be128Page) () []byte { return maxBE128(.values) }

func ( *be128Page) () (,  []byte) { return boundsBE128(.values) }

func ( *be128Page) () (,  Value,  bool) {
	if  = len(.values) > 0;  {
		,  := .bounds()
		 = .makeValueBytes()
		 = .makeValueBytes()
	}
	return , , 
}

func ( *be128Page) (,  int64) Page {
	return &be128Page{
		typ:         .typ,
		values:      .values[:],
		columnIndex: .columnIndex,
	}
}

func ( *be128Page) ( *[16]byte) Value {
	return .makeValueBytes([:])
}

func ( *be128Page) ( []byte) Value {
	 := makeValueBytes(FixedLenByteArray, )
	.columnIndex = .columnIndex
	return 
}

func ( *be128Page) ( string) Value {
	 := makeValueString(FixedLenByteArray, )
	.columnIndex = .columnIndex
	return 
}

type nullPage struct {
	typ    Type
	column int
	count  int
}

func newNullPage( Type,  int16,  int32) *nullPage {
	return &nullPage{
		typ:    ,
		column: int(),
		count:  int(),
	}
}

func ( *nullPage) () Type                        { return .typ }
func ( *nullPage) () int                       { return .column }
func ( *nullPage) () Dictionary            { return nil }
func ( *nullPage) () int64                    { return int64(.count) }
func ( *nullPage) () int64                  { return int64(.count) }
func ( *nullPage) () int64                   { return int64(.count) }
func ( *nullPage) () (,  Value,  bool) { return }
func ( *nullPage) () int64                       { return 1 }
func ( *nullPage) () ValueReader {
	return &nullPageValues{column: .column, remain: .count}
}
func ( *nullPage) (,  int64) Page {
	return &nullPage{column: .column, count: .count - int(-)}
}
func ( *nullPage) () []byte { return nil }
func ( *nullPage) () []byte { return nil }
func ( *nullPage) () encoding.Values    { return encoding.Values{} }