From 55d4bcaf26edf34b4fe7b87a1e6aa6581d46d064 Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Tue, 27 Oct 2020 11:08:08 +1100 Subject: [PATCH] sqlite storage: Do ReadAt without using incremental I/O --- storage/sqlite/sqlite-storage.go | 54 ++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/storage/sqlite/sqlite-storage.go b/storage/sqlite/sqlite-storage.go index e4eba4be..2674b4d9 100644 --- a/storage/sqlite/sqlite-storage.go +++ b/storage/sqlite/sqlite-storage.go @@ -221,20 +221,48 @@ func (i instance) Stat() (ret os.FileInfo, err error) { func (i instance) ReadAt(p []byte, off int64) (n int, err error) { i.withConn(func(conn conn) { - var blob *sqlite.Blob - blob, err = i.openBlob(conn, false, true) - if err != nil { - return - } - defer blob.Close() - if off >= blob.Size() { - err = io.EOF - return - } - if off+int64(len(p)) > blob.Size() { - p = p[:blob.Size()-off] + if false { + var blob *sqlite.Blob + blob, err = i.openBlob(conn, false, true) + if err != nil { + return + } + defer blob.Close() + if off >= blob.Size() { + err = io.EOF + return + } + if off+int64(len(p)) > blob.Size() { + p = p[:blob.Size()-off] + } + n, err = blob.ReadAt(p, off) + } else { + gotRow := false + err = sqlitex.Exec( + conn, + "select substr(data, ?, ?) from blob where name=?", + func(stmt *sqlite.Stmt) error { + if gotRow { + panic("found multiple matching blobs") + } else { + gotRow = true + } + n = stmt.ColumnBytes(0, p) + return nil + }, + off+1, len(p), i.location, + ) + if err != nil { + return + } + if !gotRow { + err = errors.New("blob not found") + return + } + if n < len(p) { + err = io.EOF + } } - n, err = blob.ReadAt(p, off) }) return } -- 2.48.1