//go:build unix

package sqlite3_wrap

import (
	

	
)

type Memory struct {
	Buf []byte
	Max int64
	com int
}

func ( *Memory) () *[]byte {
	return &.Buf
}

func ( *Memory) (,  int64) int64 {
	if .Buf == nil {
		.allocate(uint64(.Max) << 16)
	}

	 := len(.Buf)
	 := int64( >> 16)
	if  == 0 {
		return 
	}
	 :=  + 
	if  > .Max {
		return -1
	}
	.reallocate(uint64() << 16)
	return 
}

func ( *Memory) ( uint64) {
	// Round up to the page size.
	 := uint64(unix.Getpagesize() - 1)
	 := ( + ) &^ 

	if  > math.MaxInt {
		// This ensures int(res) overflows to a negative value,
		// and unix.Mmap returns EINVAL.
		 = math.MaxUint64
	}

	// Reserve res bytes of address space, to ensure we won't need to move it.
	// A protected, private, anonymous mapping should not commit memory.
	,  := unix.Mmap(-1, 0, int(), unix.PROT_NONE, unix.MAP_PRIVATE|unix.MAP_ANON)
	if  != nil {
		panic()
	}
	.Buf = [:0]
}

func ( *Memory) ( uint64) {
	 := uint64(.com)
	 := uint64(cap(.Buf))
	if  <  &&  <=  {
		// Grow geometrically, round up to the page size.
		 := uint64(unix.Getpagesize() - 1)
		 :=  + >>3
		 = min(max(, ), )
		 = ( + ) &^ 

		// Commit additional memory up to new bytes.
		 := unix.Mprotect(.Buf[.com:], unix.PROT_READ|unix.PROT_WRITE)
		if  != nil {
			panic()
		}
		.com = int()
	}
	.Buf = .Buf[:]
}

func ( *Memory) () error {
	 := unix.Munmap(.Buf[:cap(.Buf)])
	.Buf = nil
	.com = 0
	return 
}