From 5500ecf9c3e86ed10aba0605048ed4ed093581a0 Mon Sep 17 00:00:00 2001 From: Martin Hutchinson Date: Thu, 5 Dec 2024 12:05:12 +0000 Subject: [PATCH] Better --- cmd/conformance/mysql/main.go | 4 ++-- storage/mysql/mysql.go | 23 ++++++++++------------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/cmd/conformance/mysql/main.go b/cmd/conformance/mysql/main.go index fd1eebe0..21103abb 100644 --- a/cmd/conformance/mysql/main.go +++ b/cmd/conformance/mysql/main.go @@ -165,8 +165,8 @@ func configureTilesReadAPI(mux *http.ServeMux, storage *mysql.Storage) { } return } - impliedSize := (index*256 + width) << (level * 8) - tile, err := storage.ReadTile(r.Context(), level, index, impliedSize) + inferredMinTreeSize := (index*256 + width) << (level * 8) + tile, err := storage.ReadTile(r.Context(), level, index, inferredMinTreeSize) if err != nil { if os.IsNotExist(err) { w.WriteHeader(http.StatusNotFound) diff --git a/storage/mysql/mysql.go b/storage/mysql/mysql.go index e033c3b9..a3aebe4a 100644 --- a/storage/mysql/mysql.go +++ b/storage/mysql/mysql.go @@ -244,7 +244,7 @@ func (s *Storage) writeTreeState(ctx context.Context, tx *sql.Tx, size uint64, r // 3. Partial tile request with full/larger partial tile output: Return trimmed partial tile with correct tile width. // 4. Partial tile request with partial tile (same width) output: Return partial tile. // 5. Partial tile request with smaller partial tile output: Return error. -func (s *Storage) ReadTile(ctx context.Context, level, index, treeSize uint64) ([]byte, error) { +func (s *Storage) ReadTile(ctx context.Context, level, index, minTreeSize uint64) ([]byte, error) { row := s.db.QueryRowContext(ctx, selectSubtreeByLevelAndIndexSQL, level, index) if err := row.Err(); err != nil { return nil, err @@ -258,20 +258,17 @@ func (s *Storage) ReadTile(ctx context.Context, level, index, treeSize uint64) ( return nil, fmt.Errorf("scan tile: %v", err) } - if false { - numEntries := uint64(len(tile) / 32) - // A tile at this height implies this many - // modulus := 1 << (level * 8) - width := treeSize % 256 - if width == 0 { - width = 256 - } + // Do some validation to make sure we don't return data at a tree size we haven't reached yet + // Doing so could break caching at a higher level + entriesPerLevel := 1 << level * 8 + numEntries := uint64(len(tile) / 32) - if width > numEntries { - // If the user has requested more entries than we have, then return not found. - return nil, os.ErrNotExist - } + minPermanentEntries := numEntries * uint64(entriesPerLevel) + + if minTreeSize > minPermanentEntries { + // If the user has requested a size larger than we have, they can't have it + return nil, os.ErrNotExist } return tile, nil