Skip to content

Commit 6a2827f

Browse files
committed
Reuse blob buffer.
1 parent 9d77322 commit 6a2827f

File tree

2 files changed

+43
-25
lines changed

2 files changed

+43
-25
lines changed

blob.go

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ type Blob struct {
2121
bytes int64
2222
offset int64
2323
handle uint32
24+
bufptr uint32
25+
buflen int64
2426
}
2527

2628
var _ io.ReadWriteSeeker = &Blob{}
@@ -66,7 +68,7 @@ func (b *Blob) Close() error {
6668
}
6769

6870
r := b.c.call("sqlite3_blob_close", uint64(b.handle))
69-
71+
b.c.free(b.bufptr)
7072
b.handle = 0
7173
return b.c.error(r)
7274
}
@@ -86,17 +88,18 @@ func (b *Blob) Read(p []byte) (n int, err error) {
8688
return 0, io.EOF
8789
}
8890

89-
avail := b.bytes - b.offset
9091
want := int64(len(p))
92+
avail := b.bytes - b.offset
9193
if want > avail {
9294
want = avail
9395
}
94-
95-
defer b.c.arena.mark()()
96-
ptr := b.c.arena.new(uint64(want))
96+
if want > b.buflen {
97+
b.bufptr = b.c.realloc(b.bufptr, uint64(want))
98+
b.buflen = want
99+
}
97100

98101
r := b.c.call("sqlite3_blob_read", uint64(b.handle),
99-
uint64(ptr), uint64(want), uint64(b.offset))
102+
uint64(b.bufptr), uint64(want), uint64(b.offset))
100103
err = b.c.error(r)
101104
if err != nil {
102105
return 0, err
@@ -106,7 +109,7 @@ func (b *Blob) Read(p []byte) (n int, err error) {
106109
err = io.EOF
107110
}
108111

109-
copy(p, util.View(b.c.mod, ptr, uint64(want)))
112+
copy(p, util.View(b.c.mod, b.bufptr, uint64(want)))
110113
return int(want), err
111114
}
112115

@@ -123,19 +126,20 @@ func (b *Blob) WriteTo(w io.Writer) (n int64, err error) {
123126
if want > avail {
124127
want = avail
125128
}
126-
127-
defer b.c.arena.mark()()
128-
ptr := b.c.arena.new(uint64(want))
129+
if want > b.buflen {
130+
b.bufptr = b.c.realloc(b.bufptr, uint64(want))
131+
b.buflen = want
132+
}
129133

130134
for want > 0 {
131135
r := b.c.call("sqlite3_blob_read", uint64(b.handle),
132-
uint64(ptr), uint64(want), uint64(b.offset))
136+
uint64(b.bufptr), uint64(want), uint64(b.offset))
133137
err = b.c.error(r)
134138
if err != nil {
135139
return n, err
136140
}
137141

138-
mem := util.View(b.c.mod, ptr, uint64(want))
142+
mem := util.View(b.c.mod, b.bufptr, uint64(want))
139143
m, err := w.Write(mem[:want])
140144
b.offset += int64(m)
141145
n += int64(m)
@@ -159,11 +163,15 @@ func (b *Blob) WriteTo(w io.Writer) (n int64, err error) {
159163
//
160164
// https://sqlite.org/c3ref/blob_write.html
161165
func (b *Blob) Write(p []byte) (n int, err error) {
162-
defer b.c.arena.mark()()
163-
ptr := b.c.arena.bytes(p)
166+
want := int64(len(p))
167+
if want > b.buflen {
168+
b.bufptr = b.c.realloc(b.bufptr, uint64(want))
169+
b.buflen = want
170+
}
171+
util.WriteBytes(b.c.mod, b.bufptr, p)
164172

165173
r := b.c.call("sqlite3_blob_write", uint64(b.handle),
166-
uint64(ptr), uint64(len(p)), uint64(b.offset))
174+
uint64(b.bufptr), uint64(want), uint64(b.offset))
167175
err = b.c.error(r)
168176
if err != nil {
169177
return 0, err
@@ -187,16 +195,17 @@ func (b *Blob) ReadFrom(r io.Reader) (n int64, err error) {
187195
if want < 1 {
188196
want = 1
189197
}
190-
191-
defer b.c.arena.mark()()
192-
ptr := b.c.arena.new(uint64(want))
198+
if want > b.buflen {
199+
b.bufptr = b.c.realloc(b.bufptr, uint64(want))
200+
b.buflen = want
201+
}
193202

194203
for {
195-
mem := util.View(b.c.mod, ptr, uint64(want))
204+
mem := util.View(b.c.mod, b.bufptr, uint64(want))
196205
m, err := r.Read(mem[:want])
197206
if m > 0 {
198207
r := b.c.call("sqlite3_blob_write", uint64(b.handle),
199-
uint64(ptr), uint64(m), uint64(b.offset))
208+
uint64(b.bufptr), uint64(m), uint64(b.offset))
200209
err := b.c.error(r)
201210
if err != nil {
202211
return n, err

sqlite.go

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -192,11 +192,16 @@ func (sqlt *sqlite) free(ptr uint32) {
192192
}
193193

194194
func (sqlt *sqlite) new(size uint64) uint32 {
195-
if size == 0 {
196-
size = 1
197-
}
198195
ptr := uint32(sqlt.call("sqlite3_malloc64", size))
199-
if ptr == 0 {
196+
if ptr == 0 && size != 0 {
197+
panic(util.OOMErr)
198+
}
199+
return ptr
200+
}
201+
202+
func (sqlt *sqlite) realloc(ptr uint32, size uint64) uint32 {
203+
ptr = uint32(sqlt.call("sqlite3_realloc64", uint64(ptr), size))
204+
if ptr == 0 && size != 0 {
200205
panic(util.OOMErr)
201206
}
202207
return ptr
@@ -206,7 +211,11 @@ func (sqlt *sqlite) newBytes(b []byte) uint32 {
206211
if (*[0]byte)(b) == nil {
207212
return 0
208213
}
209-
ptr := sqlt.new(uint64(len(b)))
214+
size := len(b)
215+
if size == 0 {
216+
size = 1
217+
}
218+
ptr := sqlt.new(uint64(size))
210219
util.WriteBytes(sqlt.mod, ptr, b)
211220
return ptr
212221
}

0 commit comments

Comments
 (0)