github.com/phuslu/lru@v1.0.16-0.20240421170520-46288a2fd47c/bytes_file.go (about)

     1  //go:build linux && amd64
     2  // +build linux,amd64
     3  
     4  package lru
     5  
     6  import (
     7  	"fmt"
     8  	"os"
     9  	"syscall"
    10  )
    11  
    12  type bytesfile struct {
    13  	location string
    14  	file     *os.File
    15  	size     int
    16  }
    17  
    18  func (m *bytesfile) close() error {
    19  	return m.file.Close()
    20  }
    21  
    22  func (m *bytesfile) open() error {
    23  	var openingFlag = os.O_RDWR
    24  	if _, err := os.Stat(m.location); os.IsNotExist(err) {
    25  		openingFlag = openingFlag | os.O_CREATE
    26  	}
    27  	var err error
    28  	if m.file, err = os.OpenFile(m.location, openingFlag, 0644); err != nil {
    29  		return fmt.Errorf("failed to create file %v: %w", m.location, err)
    30  	}
    31  	return m.allocate()
    32  }
    33  
    34  func (m *bytesfile) assign(offset int64, target *[]byte) error {
    35  	buffer, err := syscall.Mmap(int(m.file.Fd()), offset, m.size, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED)
    36  	if err != nil {
    37  		return fmt.Errorf("failed to map memory %v: %w", m.location, err)
    38  	}
    39  	*target = buffer
    40  	return nil
    41  }
    42  
    43  func (m *bytesfile) allocate() error {
    44  	info, err := os.Stat(m.location)
    45  	if err != nil {
    46  		return err
    47  	}
    48  	if info.Size() < int64(m.size) {
    49  		_, err := m.file.Seek(int64(m.size-1), 0)
    50  		if err != nil {
    51  			return fmt.Errorf("Failed to seek file %v", err)
    52  		}
    53  		_, err = m.file.Write([]byte{0})
    54  		if err != nil {
    55  			return fmt.Errorf("failed to resize %v: %w", m.location, err)
    56  		}
    57  	}
    58  	return nil
    59  }