diff --git a/reader.go b/reader.go index f965a25..0dc4afd 100644 --- a/reader.go +++ b/reader.go @@ -9,6 +9,7 @@ import ( "sync" "time" + "github.com/0xsequence/ethwal/storage/stub" "github.com/fatih/structs" "github.com/0xsequence/ethwal/storage" @@ -19,7 +20,8 @@ const firstFileIndex = 0 const loadIndexFileTimeout = 30 * time.Second type Reader[T any] interface { - FilesNum() int + FileNum() int + FileIndex() *FileIndex Read(ctx context.Context) (Block[T], error) Seek(ctx context.Context, blockNum uint64) error BlockNum() uint64 @@ -102,13 +104,27 @@ func NewReader[T any](opt Options) (Reader[T], error) { }, nil } -func (r *reader[T]) FilesNum() int { +func (r *reader[T]) FileNum() int { r.mu.Lock() defer r.mu.Unlock() return len(r.fileIndex.Files()) } +func (r *reader[T]) FileIndex() *FileIndex { + r.mu.Lock() + defer r.mu.Unlock() + + newfiles := make([]*File, len(r.fileIndex.Files())) + for index, file := range r.fileIndex.Files() { + newfiles[index] = &File{ + FirstBlockNum: file.FirstBlockNum, + LastBlockNum: file.LastBlockNum, + } + } + return NewFileIndexFromFiles(stub.Stub{}, newfiles) +} + func (r *reader[T]) Read(ctx context.Context) (Block[T], error) { r.mu.Lock() defer r.mu.Unlock() diff --git a/reader_test.go b/reader_test.go index 0342637..b0211ff 100644 --- a/reader_test.go +++ b/reader_test.go @@ -223,7 +223,7 @@ func TestReader_Read(t *testing.T) { } } -func TestReader_NumWALFiles(t *testing.T) { +func TestReader_FileNum(t *testing.T) { testSetup(t, NewCBOREncoder, nil) defer testTeardown(t) @@ -238,7 +238,29 @@ func TestReader_NumWALFiles(t *testing.T) { }) require.NoError(t, err) - assert.Equal(t, 3, rdr.FilesNum()) + assert.Equal(t, 3, rdr.FileNum()) + + require.NoError(t, rdr.Close()) +} + +func TestReader_FileIndex(t *testing.T) { + testSetup(t, NewCBOREncoder, nil) + defer testTeardown(t) + + rdr, err := NewReader[int](Options{ + Dataset: Dataset{ + Name: "int-wal", + Path: testPath, + Version: defaultDatasetVersion, + }, + NewEncoder: NewCBOREncoder, + NewDecoder: NewCBORDecoder, + }) + require.NoError(t, err) + + fileIndex := rdr.FileIndex() + require.NotNil(t, fileIndex) + assert.Equal(t, 3, len(fileIndex.Files())) require.NoError(t, rdr.Close()) } diff --git a/reader_with_filter.go b/reader_with_filter.go index 7f43208..df906b3 100644 --- a/reader_with_filter.go +++ b/reader_with_filter.go @@ -22,8 +22,12 @@ func NewReaderWithFilter[T any](reader Reader[T], filter Filter) (Reader[T], err }, nil } -func (c *readerWithFilter[T]) FilesNum() int { - return c.reader.FilesNum() +func (c *readerWithFilter[T]) FileNum() int { + return c.reader.FileNum() +} + +func (c *readerWithFilter[T]) FileIndex() *FileIndex { + return c.reader.FileIndex() } func (c *readerWithFilter[T]) Seek(ctx context.Context, blockNum uint64) error { diff --git a/storage/stub/stub.go b/storage/stub/stub.go new file mode 100644 index 0000000..87af941 --- /dev/null +++ b/storage/stub/stub.go @@ -0,0 +1,38 @@ +package stub + +import ( + "context" + "fmt" + "io" + + "github.com/Shopify/go-storage" +) + +type Stub struct { +} + +func (s Stub) Walk(ctx context.Context, path string, fn storage.WalkFn) error { + return nil +} + +func (s Stub) Open(ctx context.Context, path string, options *storage.ReaderOptions) (*storage.File, error) { + return nil, fmt.Errorf("not implemented") +} + +func (s Stub) Attributes(ctx context.Context, path string, options *storage.ReaderOptions) (*storage.Attributes, error) { + return nil, fmt.Errorf("not implemented") +} + +func (s Stub) Create(ctx context.Context, path string, options *storage.WriterOptions) (io.WriteCloser, error) { + return nil, fmt.Errorf("not implemented") +} + +func (s Stub) Delete(ctx context.Context, path string) error { + return nil +} + +func (s Stub) URL(ctx context.Context, path string, options *storage.SignedURLOptions) (string, error) { + return "", nil +} + +var _ storage.FS = (*Stub)(nil)