mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-05-19 00:01:31 +00:00
adding ReadFromFile with read options
This commit is contained in:
24
weed/storage/needle/needle_read_options.go
Normal file
24
weed/storage/needle/needle_read_options.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package needle
|
||||
|
||||
import (
|
||||
"github.com/seaweedfs/seaweedfs/weed/storage/backend"
|
||||
. "github.com/seaweedfs/seaweedfs/weed/storage/types"
|
||||
)
|
||||
|
||||
// NeedleReadOptions specifies which parts of the Needle to read.
|
||||
type NeedleReadOptions struct {
|
||||
ReadHeader bool // always true for any read
|
||||
ReadData bool // read the Data field
|
||||
ReadMeta bool // read metadata fields (Name, Mime, LastModified, Ttl, Pairs, etc.)
|
||||
}
|
||||
|
||||
// ReadFromFile reads the Needle from the backend file according to the specified options.
|
||||
// For now, this is equivalent to ReadData (reads everything).
|
||||
func (n *Needle) ReadFromFile(r backend.BackendStorageFile, offset int64, size Size, version Version, opts NeedleReadOptions) error {
|
||||
// Always read header and body for now (full read)
|
||||
bytes, err := ReadNeedleBlob(r, offset, size, version)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return n.ReadBytes(bytes, offset, size, version)
|
||||
}
|
||||
92
weed/storage/needle/needle_read_options_test.go
Normal file
92
weed/storage/needle/needle_read_options_test.go
Normal file
@@ -0,0 +1,92 @@
|
||||
package needle
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
. "github.com/seaweedfs/seaweedfs/weed/storage/types"
|
||||
)
|
||||
|
||||
type mockBackend struct {
|
||||
data []byte
|
||||
}
|
||||
|
||||
func (m *mockBackend) ReadAt(p []byte, off int64) (n int, err error) {
|
||||
if int(off) >= len(m.data) {
|
||||
return 0, io.EOF
|
||||
}
|
||||
n = copy(p, m.data[off:])
|
||||
if n < len(p) {
|
||||
return n, io.EOF
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func (m *mockBackend) GetStat() (int64, time.Time, error) {
|
||||
return int64(len(m.data)), time.Time{}, nil
|
||||
}
|
||||
|
||||
func (m *mockBackend) Name() string {
|
||||
return "mock"
|
||||
}
|
||||
|
||||
func (m *mockBackend) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockBackend) Sync() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockBackend) Truncate(size int64) error {
|
||||
m.data = m.data[:size]
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockBackend) WriteAt(p []byte, off int64) (n int, err error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func TestReadFromFile_EquivalenceWithReadData(t *testing.T) {
|
||||
n := &Needle{
|
||||
Cookie: 0x12345678,
|
||||
Id: 0x1122334455667788,
|
||||
Data: []byte("hello world"),
|
||||
Flags: 0xFF,
|
||||
Name: []byte("filename.txt"),
|
||||
Mime: []byte("text/plain"),
|
||||
LastModified: 0x1234567890,
|
||||
Ttl: nil,
|
||||
Pairs: []byte("key=value"),
|
||||
PairsSize: 9,
|
||||
Checksum: 0xCAFEBABE,
|
||||
AppendAtNs: 0xDEADBEEF,
|
||||
}
|
||||
buf := &bytes.Buffer{}
|
||||
_, _, err := writeNeedleV2(n, 0, buf)
|
||||
if err != nil {
|
||||
t.Fatalf("writeNeedleV2 failed: %v", err)
|
||||
}
|
||||
backend := &mockBackend{data: buf.Bytes()}
|
||||
size := Size(len(buf.Bytes()) - NeedleHeaderSize - NeedleChecksumSize - int(PaddingLength(Size(len(buf.Bytes())-NeedleHeaderSize-NeedleChecksumSize), Version2)))
|
||||
|
||||
// Old method
|
||||
nOld := &Needle{}
|
||||
errOld := nOld.ReadData(backend, 0, size, Version2)
|
||||
|
||||
// New method
|
||||
nNew := &Needle{}
|
||||
opts := NeedleReadOptions{ReadHeader: true, ReadData: true, ReadMeta: true}
|
||||
errNew := nNew.ReadFromFile(backend, 0, size, Version2, opts)
|
||||
|
||||
if (errOld != nil) != (errNew != nil) || (errOld != nil && errOld.Error() != errNew.Error()) {
|
||||
t.Errorf("error mismatch: old=%v new=%v", errOld, errNew)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(nOld, nNew) {
|
||||
t.Errorf("needle mismatch: old=%+v new=%+v", nOld, nNew)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user