mirror of
https://github.com/ncruces/go-sqlite3.git
synced 2026-01-11 21:49:13 +00:00
Memory optimizations.
This commit is contained in:
2
blob.go
2
blob.go
@@ -18,9 +18,9 @@ type ZeroBlob int64
|
||||
// https://www.sqlite.org/c3ref/blob.html
|
||||
type Blob struct {
|
||||
c *Conn
|
||||
handle uint32
|
||||
bytes int64
|
||||
offset int64
|
||||
handle uint32
|
||||
}
|
||||
|
||||
var _ io.ReadWriteSeeker = &Blob{}
|
||||
|
||||
5
conn.go
5
conn.go
@@ -21,11 +21,12 @@ import (
|
||||
type Conn struct {
|
||||
*module
|
||||
|
||||
handle uint32
|
||||
arena arena
|
||||
interrupt context.Context
|
||||
waiter chan struct{}
|
||||
pending *Stmt
|
||||
arena arena
|
||||
|
||||
handle uint32
|
||||
}
|
||||
|
||||
// Open calls [OpenFlags] with [OPEN_READWRITE], [OPEN_CREATE], [OPEN_URI] and [OPEN_NOFOLLOW].
|
||||
|
||||
2
error.go
2
error.go
@@ -9,10 +9,10 @@ import (
|
||||
//
|
||||
// https://www.sqlite.org/c3ref/errcode.html
|
||||
type Error struct {
|
||||
code uint64
|
||||
str string
|
||||
msg string
|
||||
sql string
|
||||
code uint64
|
||||
}
|
||||
|
||||
// Code returns the primary error code for this error.
|
||||
|
||||
@@ -196,22 +196,22 @@ const (
|
||||
)
|
||||
|
||||
// https://www.sqlite.org/c3ref/c_iocap_atomic.html
|
||||
type _DeviceChars uint32
|
||||
type _DeviceCharacteristic uint32
|
||||
|
||||
const (
|
||||
_IOCAP_ATOMIC _DeviceChars = 0x00000001
|
||||
_IOCAP_ATOMIC512 _DeviceChars = 0x00000002
|
||||
_IOCAP_ATOMIC1K _DeviceChars = 0x00000004
|
||||
_IOCAP_ATOMIC2K _DeviceChars = 0x00000008
|
||||
_IOCAP_ATOMIC4K _DeviceChars = 0x00000010
|
||||
_IOCAP_ATOMIC8K _DeviceChars = 0x00000020
|
||||
_IOCAP_ATOMIC16K _DeviceChars = 0x00000040
|
||||
_IOCAP_ATOMIC32K _DeviceChars = 0x00000080
|
||||
_IOCAP_ATOMIC64K _DeviceChars = 0x00000100
|
||||
_IOCAP_SAFE_APPEND _DeviceChars = 0x00000200
|
||||
_IOCAP_SEQUENTIAL _DeviceChars = 0x00000400
|
||||
_IOCAP_UNDELETABLE_WHEN_OPEN _DeviceChars = 0x00000800
|
||||
_IOCAP_POWERSAFE_OVERWRITE _DeviceChars = 0x00001000
|
||||
_IOCAP_IMMUTABLE _DeviceChars = 0x00002000
|
||||
_IOCAP_BATCH_ATOMIC _DeviceChars = 0x00004000
|
||||
_IOCAP_ATOMIC _DeviceCharacteristic = 0x00000001
|
||||
_IOCAP_ATOMIC512 _DeviceCharacteristic = 0x00000002
|
||||
_IOCAP_ATOMIC1K _DeviceCharacteristic = 0x00000004
|
||||
_IOCAP_ATOMIC2K _DeviceCharacteristic = 0x00000008
|
||||
_IOCAP_ATOMIC4K _DeviceCharacteristic = 0x00000010
|
||||
_IOCAP_ATOMIC8K _DeviceCharacteristic = 0x00000020
|
||||
_IOCAP_ATOMIC16K _DeviceCharacteristic = 0x00000040
|
||||
_IOCAP_ATOMIC32K _DeviceCharacteristic = 0x00000080
|
||||
_IOCAP_ATOMIC64K _DeviceCharacteristic = 0x00000100
|
||||
_IOCAP_SAFE_APPEND _DeviceCharacteristic = 0x00000200
|
||||
_IOCAP_SEQUENTIAL _DeviceCharacteristic = 0x00000400
|
||||
_IOCAP_UNDELETABLE_WHEN_OPEN _DeviceCharacteristic = 0x00000800
|
||||
_IOCAP_POWERSAFE_OVERWRITE _DeviceCharacteristic = 0x00001000
|
||||
_IOCAP_IMMUTABLE _DeviceCharacteristic = 0x00002000
|
||||
_IOCAP_BATCH_ATOMIC _DeviceCharacteristic = 0x00004000
|
||||
)
|
||||
|
||||
@@ -362,7 +362,7 @@ func vfsSectorSize(ctx context.Context, mod api.Module, pFile uint32) uint32 {
|
||||
return _DEFAULT_SECTOR_SIZE
|
||||
}
|
||||
|
||||
func vfsDeviceCharacteristics(ctx context.Context, mod api.Module, pFile uint32) _DeviceChars {
|
||||
func vfsDeviceCharacteristics(ctx context.Context, mod api.Module, pFile uint32) _DeviceCharacteristic {
|
||||
file := getVFSFile(ctx, mod, pFile)
|
||||
if file.psow {
|
||||
return _IOCAP_POWERSAFE_OVERWRITE
|
||||
|
||||
@@ -11,8 +11,8 @@ import (
|
||||
|
||||
type vfsFile struct {
|
||||
*os.File
|
||||
lock _LockLevel
|
||||
lockTimeout time.Duration
|
||||
lock _LockLevel
|
||||
psow bool
|
||||
syncDir bool
|
||||
readOnly bool
|
||||
|
||||
20
module.go
20
module.go
@@ -26,10 +26,10 @@ var (
|
||||
)
|
||||
|
||||
var sqlite3 struct {
|
||||
once sync.Once
|
||||
runtime wazero.Runtime
|
||||
compiled wazero.CompiledModule
|
||||
err error
|
||||
once sync.Once
|
||||
}
|
||||
|
||||
func instantiateModule() (*module, error) {
|
||||
@@ -72,8 +72,9 @@ func compileModule() {
|
||||
type module struct {
|
||||
ctx context.Context
|
||||
mod api.Module
|
||||
api sqliteAPI
|
||||
vfs io.Closer
|
||||
api sqliteAPI
|
||||
arg []uint64
|
||||
}
|
||||
|
||||
func newModule(mod api.Module) (m *module, err error) {
|
||||
@@ -91,18 +92,18 @@ func newModule(mod api.Module) (m *module, err error) {
|
||||
}
|
||||
|
||||
getVal := func(name string) uint32 {
|
||||
global := mod.ExportedGlobal(name)
|
||||
if global == nil {
|
||||
g := mod.ExportedGlobal(name)
|
||||
if g == nil {
|
||||
err = util.NoGlobalErr + util.ErrorString(name)
|
||||
return 0
|
||||
}
|
||||
return util.ReadUint32(mod, uint32(global.Get()))
|
||||
return util.ReadUint32(mod, uint32(g.Get()))
|
||||
}
|
||||
|
||||
m.api = sqliteAPI{
|
||||
free: getFun("free"),
|
||||
malloc: getFun("malloc"),
|
||||
destructor: uint64(getVal("malloc_destructor")),
|
||||
destructor: getVal("malloc_destructor"),
|
||||
errcode: getFun("sqlite3_errcode"),
|
||||
errstr: getFun("sqlite3_errstr"),
|
||||
errmsg: getFun("sqlite3_errmsg"),
|
||||
@@ -199,7 +200,8 @@ func (m *module) error(rc uint64, handle uint32, sql ...string) error {
|
||||
}
|
||||
|
||||
func (m *module) call(fn api.Function, params ...uint64) []uint64 {
|
||||
r, err := fn.Call(m.ctx, params...)
|
||||
m.arg = append(m.arg[:0], params...)
|
||||
r, err := fn.Call(m.ctx, m.arg...)
|
||||
if err != nil {
|
||||
// The module closed or panicked; release resources.
|
||||
m.vfs.Close()
|
||||
@@ -252,10 +254,10 @@ func (m *module) newArena(size uint64) arena {
|
||||
|
||||
type arena struct {
|
||||
m *module
|
||||
ptrs []uint32
|
||||
base uint32
|
||||
next uint32
|
||||
size uint32
|
||||
ptrs []uint32
|
||||
}
|
||||
|
||||
func (a *arena) free() {
|
||||
@@ -295,7 +297,6 @@ func (a *arena) string(s string) uint32 {
|
||||
type sqliteAPI struct {
|
||||
free api.Function
|
||||
malloc api.Function
|
||||
destructor uint64
|
||||
errcode api.Function
|
||||
errstr api.Function
|
||||
errmsg api.Function
|
||||
@@ -340,5 +341,6 @@ type sqliteAPI struct {
|
||||
backupFinish api.Function
|
||||
backupRemaining api.Function
|
||||
backupPageCount api.Function
|
||||
destructor uint32
|
||||
interrupt uint32
|
||||
}
|
||||
|
||||
@@ -39,8 +39,8 @@ int os_check_reserved_lock(sqlite3_file *, int *pResOut);
|
||||
static int os_file_control_w(sqlite3_file *file, int op, void *pArg) {
|
||||
struct os_file *pFile = (struct os_file *)file;
|
||||
if (op == SQLITE_FCNTL_VFSNAME) {
|
||||
*(char **)pArg = sqlite3_mprintf("%s", "os");
|
||||
return SQLITE_OK;
|
||||
*(char **)pArg = sqlite3_mprintf("%s", "os");
|
||||
return SQLITE_OK;
|
||||
}
|
||||
return os_file_control(file, op, pArg);
|
||||
}
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
#define SQLITE_OMIT_AUTOINIT
|
||||
#define SQLITE_USE_ALLOCA
|
||||
|
||||
// Other Options
|
||||
// #define SQLITE_ALLOW_URI_AUTHORITY
|
||||
|
||||
// Because WASM does not support shared memory,
|
||||
// SQLite disables WAL for WASM builds.
|
||||
// We set the default locking mode to EXCLUSIVE instead.
|
||||
|
||||
6
stmt.go
6
stmt.go
@@ -12,8 +12,8 @@ import (
|
||||
// https://www.sqlite.org/c3ref/stmt.html
|
||||
type Stmt struct {
|
||||
c *Conn
|
||||
handle uint32
|
||||
err error
|
||||
handle uint32
|
||||
}
|
||||
|
||||
// Close destroys the prepared statement object.
|
||||
@@ -174,7 +174,7 @@ func (s *Stmt) BindText(param int, value string) error {
|
||||
r := s.c.call(s.c.api.bindText,
|
||||
uint64(s.handle), uint64(param),
|
||||
uint64(ptr), uint64(len(value)),
|
||||
s.c.api.destructor, _UTF8)
|
||||
uint64(s.c.api.destructor), _UTF8)
|
||||
return s.c.error(r[0])
|
||||
}
|
||||
|
||||
@@ -188,7 +188,7 @@ func (s *Stmt) BindBlob(param int, value []byte) error {
|
||||
r := s.c.call(s.c.api.bindBlob,
|
||||
uint64(s.handle), uint64(param),
|
||||
uint64(ptr), uint64(len(value)),
|
||||
s.c.api.destructor)
|
||||
uint64(s.c.api.destructor))
|
||||
return s.c.error(r[0])
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user