github.com/apache/arrow/go/v14@v14.0.1/parquet/file/file_reader_mmap.go (about)

     1  // Licensed to the Apache Software Foundation (ASF) under one
     2  // or more contributor license agreements.  See the NOTICE file
     3  // distributed with this work for additional information
     4  // regarding copyright ownership.  The ASF licenses this file
     5  // to you under the Apache License, Version 2.0 (the
     6  // "License"); you may not use this file except in compliance
     7  // with the License.  You may obtain a copy of the License at
     8  //
     9  // http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing, software
    12  // distributed under the License is distributed on an "AS IS" BASIS,
    13  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  // See the License for the specific language governing permissions and
    15  // limitations under the License.
    16  
    17  //go:build !windows
    18  // +build !windows
    19  
    20  package file
    21  
    22  import (
    23  	"io"
    24  
    25  	"github.com/apache/arrow/go/v14/parquet"
    26  	"golang.org/x/exp/mmap"
    27  	"golang.org/x/xerrors"
    28  )
    29  
    30  func mmapOpen(filename string) (parquet.ReaderAtSeeker, error) {
    31  	rdr, err := mmap.Open(filename)
    32  	if err != nil {
    33  		return nil, err
    34  	}
    35  	return &mmapAdapter{rdr, 0}, nil
    36  }
    37  
    38  // an adapter for mmap'd files
    39  type mmapAdapter struct {
    40  	*mmap.ReaderAt
    41  
    42  	pos int64
    43  }
    44  
    45  func (m *mmapAdapter) Close() error {
    46  	return m.ReaderAt.Close()
    47  }
    48  
    49  func (m *mmapAdapter) ReadAt(p []byte, off int64) (int, error) {
    50  	return m.ReaderAt.ReadAt(p, off)
    51  }
    52  
    53  func (m *mmapAdapter) Read(p []byte) (n int, err error) {
    54  	n, err = m.ReaderAt.ReadAt(p, m.pos)
    55  	m.pos += int64(n)
    56  	return
    57  }
    58  
    59  func (m *mmapAdapter) Seek(offset int64, whence int) (int64, error) {
    60  	newPos, offs := int64(0), offset
    61  	switch whence {
    62  	case io.SeekStart:
    63  		newPos = offs
    64  	case io.SeekCurrent:
    65  		newPos = m.pos + offs
    66  	case io.SeekEnd:
    67  		newPos = int64(m.ReaderAt.Len()) + offs
    68  	}
    69  	if newPos < 0 {
    70  		return 0, xerrors.New("negative result pos")
    71  	}
    72  	if newPos > int64(m.ReaderAt.Len()) {
    73  		return 0, xerrors.New("new position exceeds size of file")
    74  	}
    75  	m.pos = newPos
    76  	return newPos, nil
    77  }