From fe8cbc2c340b5d87937afee406c0c25ed84dd8ca Mon Sep 17 00:00:00 2001 From: Al Cutter Date: Fri, 6 Dec 2024 15:12:24 +0000 Subject: [PATCH] Update MySQL --- storage/mysql/mysql.go | 23 +++++++------------- storage/mysql/mysql_test.go | 42 +++++++++++++++++++------------------ 2 files changed, 29 insertions(+), 36 deletions(-) diff --git a/storage/mysql/mysql.go b/storage/mysql/mysql.go index a6d62dd2..0383c355 100644 --- a/storage/mysql/mysql.go +++ b/storage/mysql/mysql.go @@ -242,7 +242,7 @@ func (s *Storage) writeTreeState(ctx context.Context, tx *sql.Tx, size uint64, r // Note that if a partial tile is requested, but a larger tile is available, this // will return the largest tile available. This could be trimmed to return only the // number of entries specifically requested if this behaviour becomes problematic. -func (s *Storage) ReadTile(ctx context.Context, level, index, minTreeSize uint64) ([]byte, error) { +func (s *Storage) ReadTile(ctx context.Context, level, index uint64, p uint8) ([]byte, error) { row := s.db.QueryRowContext(ctx, selectSubtreeByLevelAndIndexSQL, level, index) if err := row.Err(); err != nil { return nil, err @@ -257,10 +257,12 @@ func (s *Storage) ReadTile(ctx context.Context, level, index, minTreeSize uint64 return nil, fmt.Errorf("scan tile: %v", err) } - requestedWidth := partialTileSize(level, index, minTreeSize) numEntries := uint64(len(tile) / sha256.Size) - - if requestedWidth > numEntries { + requestedEntries := uint64(p) + if requestedEntries == 0 { + requestedEntries = 256 + } + if requestedEntries > numEntries { // If the user has requested a size larger than we have, they can't have it return nil, os.ErrNotExist } @@ -268,17 +270,6 @@ func (s *Storage) ReadTile(ctx context.Context, level, index, minTreeSize uint64 return tile, nil } -// partialTileSize returns the expected number of leaves in a tile at the given location within -// a tree of the specified logSize, or 0 if the tile is expected to be fully populated. -func partialTileSize(level, index, logSize uint64) uint64 { - sizeAtLevel := logSize >> (level * 8) - fullTiles := sizeAtLevel / 256 - if index < fullTiles { - return 256 - } - return sizeAtLevel % 256 -} - // writeTile replaces the tile nodes at the given level and index. func (s *Storage) writeTile(ctx context.Context, tx *sql.Tx, level, index uint64, nodes []byte) error { if _, err := tx.ExecContext(ctx, replaceSubtreeSQL, level, index, nodes); err != nil { @@ -298,7 +289,7 @@ func (s *Storage) writeTile(ctx context.Context, tx *sql.Tx, level, index uint64 // 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) ReadEntryBundle(ctx context.Context, index, treeSize uint64) ([]byte, error) { +func (s *Storage) ReadEntryBundle(ctx context.Context, index uint64, p uint8) ([]byte, error) { row := s.db.QueryRowContext(ctx, selectTiledLeavesSQL, index) if err := row.Err(); err != nil { return nil, err diff --git a/storage/mysql/mysql_test.go b/storage/mysql/mysql_test.go index d84d733e..091537b2 100644 --- a/storage/mysql/mysql_test.go +++ b/storage/mysql/mysql_test.go @@ -189,54 +189,55 @@ func TestGetTile(t *testing.T) { } for _, test := range []struct { - name string - level, index, treeSize uint64 - wantEntries int - wantNotFound bool + name string + level, index uint64 + p uint8 + wantEntries int + wantNotFound bool }{ { name: "requested partial tile for a complete tile", - level: 0, index: 0, treeSize: 10, + level: 0, index: 0, p: 10, wantEntries: 256, wantNotFound: false, }, { name: "too small but that's ok", - level: 0, index: 1, treeSize: uint64(treeSize) - 1, + level: 0, index: 1, p: layout.PartialTileSize(0, 1, uint64(treeSize-1)), wantEntries: 2, wantNotFound: false, }, { name: "just right", - level: 0, index: 1, treeSize: uint64(treeSize), + level: 0, index: 1, p: layout.PartialTileSize(0, 1, uint64(treeSize)), wantEntries: 2, wantNotFound: false, }, { name: "too big", - level: 0, index: 1, treeSize: uint64(treeSize + 1), + level: 0, index: 1, p: layout.PartialTileSize(0, 1, uint64(treeSize+1)), wantNotFound: true, }, { name: "level 1 too small", - level: 1, index: 0, treeSize: uint64(treeSize - 1), + level: 1, index: 0, p: layout.PartialTileSize(1, 0, uint64(treeSize-1)), wantEntries: 1, wantNotFound: false, }, { name: "level 1 just right", - level: 1, index: 0, treeSize: uint64(treeSize), + level: 1, index: 0, p: layout.PartialTileSize(1, 0, uint64(treeSize)), wantEntries: 1, wantNotFound: false, }, { name: "level 1 too big", - level: 1, index: 0, treeSize: 550, + level: 1, index: 0, p: layout.PartialTileSize(1, 0, 550), wantNotFound: true, }, } { t.Run(test.name, func(t *testing.T) { - tile, err := s.ReadTile(ctx, test.level, test.index, test.treeSize) + tile, err := s.ReadTile(ctx, test.level, test.index, test.p) if err != nil { if notFound, wantNotFound := os.IsNotExist(err), test.wantNotFound; notFound != wantNotFound { t.Errorf("wantNotFound %v but notFound %v", wantNotFound, notFound) @@ -259,20 +260,21 @@ func TestReadMissingTile(t *testing.T) { s := newTestMySQLStorage(t, ctx) for _, test := range []struct { - name string - level, index, width uint64 + name string + level, index uint64 + p uint8 }{ { name: "0/0/0", - level: 0, index: 0, width: 0, + level: 0, index: 0, p: 0, }, { name: "123/456/789", - level: 123, index: 456, width: 789, + level: 123, index: 456, p: 789 % layout.TileWidth, }, } { t.Run(test.name, func(t *testing.T) { - tile, err := s.ReadTile(ctx, test.level, test.index, test.width) + tile, err := s.ReadTile(ctx, test.level, test.index, test.p) if err != nil { if os.IsNotExist(err) { // this is success for this test @@ -305,7 +307,7 @@ func TestReadMissingEntryBundle(t *testing.T) { }, } { t.Run(test.name, func(t *testing.T) { - entryBundle, err := s.ReadEntryBundle(ctx, test.index, test.index) + entryBundle, err := s.ReadEntryBundle(ctx, test.index, uint8(test.index%layout.TileWidth)) if err != nil { if os.IsNotExist(err) { // this is success for this test @@ -385,7 +387,7 @@ func TestTileRoundTrip(t *testing.T) { } tileLevel, tileIndex, _, nodeIndex := layout.NodeCoordsToTileAddress(0, entryIndex) - tileRaw, err := s.ReadTile(ctx, tileLevel, tileIndex, nodeIndex+1) + tileRaw, err := s.ReadTile(ctx, tileLevel, tileIndex, uint8(nodeIndex+1)) if err != nil { t.Errorf("ReadTile got err: %v", err) } @@ -434,7 +436,7 @@ func TestEntryBundleRoundTrip(t *testing.T) { if err != nil { t.Errorf("Add got err: %v", err) } - entryBundleRaw, err := s.ReadEntryBundle(ctx, entryIndex/256, entryIndex) + entryBundleRaw, err := s.ReadEntryBundle(ctx, entryIndex/256, uint8(entryIndex%layout.TileWidth)) if err != nil { t.Errorf("ReadEntryBundle got err: %v", err) }