Skip to content

Commit

Permalink
storagenode/storagenodedb: add gc_filewalker_progress and used_space_…
Browse files Browse the repository at this point in the history
…per_prefix DBs

These DBs will be respectively used by the GC and used space filewalkers

Updates #6708

Change-Id: I042a472a9719ce1141c87daa079b8557b629da05
  • Loading branch information
profclems committed Mar 5, 2024
1 parent b1dd96d commit 537a9ba
Show file tree
Hide file tree
Showing 10 changed files with 521 additions and 70 deletions.
2 changes: 2 additions & 0 deletions storagenode/peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ type DB interface {
Payout() payouts.DB
Pricing() pricing.DB
APIKeys() apikeys.DB
GCFilewalkerProgress() pieces.GCFilewalkerProgressDB
UsedSpacePerPrefix() pieces.UsedSpacePerPrefixDB

Preflight(ctx context.Context) error
}
Expand Down
45 changes: 45 additions & 0 deletions storagenode/pieces/filewalkerdb.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (C) 2024 Storj Labs, Inc.
// See LICENSE for copying information.

package pieces

import (
"context"
"time"

"storj.io/common/storj"
)

// GCFilewalkerProgressDB is used to store intermediate progress to resume garbage
// collection after restarting the node.
type GCFilewalkerProgressDB interface {
// Store stores the GC filewalker progress.
Store(ctx context.Context, progress GCFilewalkerProgress) error
// Get returns the GC filewalker progress for the satellite.
Get(ctx context.Context, satelliteID storj.NodeID) (GCFilewalkerProgress, error)
// Reset resets the GC filewalker progress for the satellite.
Reset(ctx context.Context, satelliteID storj.NodeID) error
}

// UsedSpacePerPrefixDB is an interface for the used_space_per_prefix database.
type UsedSpacePerPrefixDB interface {
// Store stores the used space per prefix.
Store(ctx context.Context, usedSpace PrefixUsedSpace) error
// Get returns the used space per prefix for the satellite.
Get(ctx context.Context, satelliteID storj.NodeID) ([]PrefixUsedSpace, error)
}

// GCFilewalkerProgress keeps track of the GC filewalker progress.
type GCFilewalkerProgress struct {
Prefix string
SatelliteID storj.NodeID
BFCreatedBefore time.Time
}

// PrefixUsedSpace contains the used space information of a prefix.
type PrefixUsedSpace struct {
Prefix string
SatelliteID storj.NodeID
TotalBytes int64
LastUpdated time.Time
}
81 changes: 81 additions & 0 deletions storagenode/pieces/filewalkerdb_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Copyright (C) 2024 Storj Labs, Inc.
// See LICENSE for copying information.

package pieces_test

import (
"testing"
"time"

"github.com/stretchr/testify/require"

"storj.io/common/testcontext"
"storj.io/common/testrand"
"storj.io/storj/storagenode"
"storj.io/storj/storagenode/pieces"
"storj.io/storj/storagenode/storagenodedb/storagenodedbtest"
)

func TestGCFilewalkerDB_GetInsert(t *testing.T) {
storagenodedbtest.Run(t, func(ctx *testcontext.Context, t *testing.T, db storagenode.DB) {
gcFilewalkerDB := db.GCFilewalkerProgress()

progress := pieces.GCFilewalkerProgress{
SatelliteID: testrand.NodeID(),
BFCreatedBefore: time.Now().UTC(),
Prefix: "yf",
}

t.Run("insert", func(t *testing.T) {
err := gcFilewalkerDB.Store(ctx, progress)
require.NoError(t, err)
})

t.Run("get", func(t *testing.T) {
result, err := gcFilewalkerDB.Get(ctx, progress.SatelliteID)
require.NoError(t, err)

require.Equal(t, result.SatelliteID, progress.SatelliteID)
require.Equal(t, result.BFCreatedBefore, progress.BFCreatedBefore)
require.Equal(t, result.Prefix, progress.Prefix)
})

t.Run("reset", func(t *testing.T) {
err := gcFilewalkerDB.Reset(ctx, progress.SatelliteID)
require.NoError(t, err)

result, err := gcFilewalkerDB.Get(ctx, progress.SatelliteID)
require.Error(t, err)
require.Equal(t, pieces.GCFilewalkerProgress{SatelliteID: progress.SatelliteID}, result)
})
})
}

func TestUsedSpacePerPrefix_GetInsert(t *testing.T) {
storagenodedbtest.Run(t, func(ctx *testcontext.Context, t *testing.T, db storagenode.DB) {
usedSpacePerPrefixDB := db.UsedSpacePerPrefix()

usedSpace := pieces.PrefixUsedSpace{
SatelliteID: testrand.NodeID(),
Prefix: "yf",
TotalBytes: 1234567890,
LastUpdated: time.Now().UTC(),
}

t.Run("insert", func(t *testing.T) {
err := usedSpacePerPrefixDB.Store(ctx, usedSpace)
require.NoError(t, err)
})

t.Run("get", func(t *testing.T) {
results, err := usedSpacePerPrefixDB.Get(ctx, usedSpace.SatelliteID)
require.NoError(t, err)

require.Len(t, results, 1)
require.Equal(t, results[0].SatelliteID, usedSpace.SatelliteID)
require.Equal(t, results[0].Prefix, usedSpace.Prefix)
require.Equal(t, results[0].TotalBytes, usedSpace.TotalBytes)
require.Equal(t, results[0].LastUpdated, usedSpace.LastUpdated)
})
})
}

1 comment on commit 537a9ba

@storjrobot
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commit has been mentioned on Storj Community Forum (official). There might be relevant details there:

https://forum.storj.io/t/disk-usage-discrepancy/24715/589

Please sign in to comment.