Documentation
¶
Overview ¶
Package device defines the storage device a browser volume engine writes through, with memory and file implementations.
A device holds named files addressed by byte offset. It orders every call and makes them durable only at a flush: a crash keeps every call before the last completed flush and may keep, drop, or tear any later write, truncate, or remove.
Index ¶
- Constants
- Variables
- func ValidName(name string) error
- type Device
- type Dir
- func (d *Dir) Close() error
- func (d *Dir) List(ctx context.Context) ([]File, error)
- func (d *Dir) Read(ctx context.Context, reads []Read) error
- func (d *Dir) Remove(ctx context.Context, names []string) error
- func (d *Dir) Truncate(ctx context.Context, name string, size int64) error
- func (d *Dir) Write(ctx context.Context, writes []Write, flush bool) error
- type File
- type Handle
- type Memory
- func (m *Memory) Calls() int
- func (m *Memory) CrashAfter(n int)
- func (m *Memory) List(ctx context.Context) ([]File, error)
- func (m *Memory) PowerLoss(rng *rand.Rand)
- func (m *Memory) Read(ctx context.Context, reads []Read) error
- func (m *Memory) Remove(ctx context.Context, names []string) error
- func (m *Memory) Truncate(ctx context.Context, name string, size int64) error
- func (m *Memory) Write(ctx context.Context, writes []Write, flush bool) error
- type Read
- type Write
Constants ¶
const SectorSize = 512
SectorSize is the unit a torn write keeps or loses in a simulated power loss.
Variables ¶
var ErrCrashed = errors.New("device crashed")
ErrCrashed reports a call on a memory device after its injected crash.
var ErrHeld = errors.New("device is held by another opener")
ErrHeld reports a device that another opener holds open. A device has one opener at a time, which is the only writer of its files.
var ErrShortRead = errors.New("read past end of file")
ErrShortRead reports a read range that extends past the end of its file.
Functions ¶
Types ¶
type Device ¶
type Device interface {
// Write applies writes in order. With flush set it returns once every
// earlier call on the device, including these writes, is durable.
Write(ctx context.Context, writes []Write, flush bool) error
// Read fills every read. A range past the end of its file, or of a
// missing file, fails with ErrShortRead.
Read(ctx context.Context, reads []Read) error
// Truncate sets a file's length, zero filling when it grows.
Truncate(ctx context.Context, name string, size int64) error
// Remove deletes files; a missing file is not an error.
Remove(ctx context.Context, names []string) error
// List returns every file.
List(ctx context.Context) ([]File, error)
}
Device is a flat namespace of files with batched positional I/O. Every method is one device round trip, and calls apply in the order they return.
type Dir ¶
type Dir struct {
// contains filtered or unexported fields
}
Dir is a Device over an operating system directory. It keeps one open handle per file and flushes with fsync of each file written since the last flush and of the directory when files were created or removed.
type File ¶
type File struct {
// Name is the file name.
Name string
// Size is the file length in bytes.
Size int64
}
File describes one file on a device.
type Handle ¶
type Handle struct {
// contains filtered or unexported fields
}
Handle is one device file used as a positional file. Writes collect until Sync, which issues them with the flush in one device call, so a caller that writes many ranges and then syncs costs one round trip. Close and every other call issue collected writes first, unflushed, to keep device order. A Handle satisfies bbolt's Storage.
func OpenHandle ¶
OpenHandle returns a Handle on the named file, which need not exist.
func (*Handle) ReadAt ¶
ReadAt reads len(p) bytes at off, returning io.EOF when the file ends first.
func (*Handle) Sync ¶
Sync issues the collected writes with a flush, making every earlier call on the device durable, including calls through other handles.
type Memory ¶
type Memory struct {
// contains filtered or unexported fields
}
Memory is an in-memory Device that simulates power loss. It keeps the durable image as of the last flush and the calls made since, so PowerLoss can build any image a crash could leave.
func NewMemory ¶
func NewMemory() *Memory
NewMemory returns an empty memory device that never crashes.
func (*Memory) CrashAfter ¶
CrashAfter crashes the device after n further mutating calls succeed. The crashing call applies part or none of its mutations, and every later call fails with ErrCrashed until PowerLoss. A negative n never crashes.
func (*Memory) PowerLoss ¶
PowerLoss replaces the device contents with an image a power loss could leave: every flushed mutation, and each later one kept, dropped, or for a write torn to a random subset of its sectors, as rng chooses. The device then accepts calls again.
type Read ¶
type Read struct {
// Name is the file to read.
Name string
// Offset is the byte offset of the first byte to read.
Offset int64
// Data receives len(Data) bytes.
Data []byte
}
Read is one positional read.
type Write ¶
type Write struct {
// Name is the file to write, created when absent.
Name string
// Offset is the byte offset of the first written byte. Writing past the
// end extends the file, zero filling any gap.
Offset int64
// Data holds the bytes to write. The device does not retain it.
Data []byte
}
Write is one positional write.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package devicetest checks a device.Device against its contract, so native tests and browser fixtures run the same checks on every implementation.
|
Package devicetest checks a device.Device against its contract, so native tests and browser fixtures run the same checks on every implementation. |
|
Package device_opfs implements device.Device on an OPFS directory with sync access handles, which only a dedicated worker can open.
|
Package device_opfs implements device.Device on an OPFS directory with sync access handles, which only a dedicated worker can open. |