Documentation
¶
Overview ¶
Package externalsort provides bounded external sorting for fixed-size records encrypted at rest in owner-only temporary storage.
Example ¶
package main
import (
"bytes"
"context"
"fmt"
"os"
externalsort "github.com/faustbrian/go-external-sort"
)
func main() {
parent, err := os.MkdirTemp("", "external-sort-example-")
if err != nil {
panic(err)
}
defer func() {
if err := os.RemoveAll(parent); err != nil {
panic(err)
}
}()
factory, err := externalsort.NewFactory(externalsort.Config{
ParentDirectory: parent,
RecordBytes: 2,
ChunkRecords: 2,
MaximumRecords: 3,
})
if err != nil {
panic(err)
}
store, err := factory.Open(
context.Background(),
bytes.Repeat([]byte{1}, externalsort.AES256KeyBytes),
)
if store != nil {
defer func() {
if err := store.Close(); err != nil {
panic(err)
}
}()
}
if err != nil {
panic(err)
}
for _, record := range [][]byte{{3, 3}, {1, 1}, {2, 2}} {
if err := store.Add(context.Background(), record); err != nil {
panic(err)
}
}
if err := store.ForEachSorted(
context.Background(),
func(record []byte) error {
fmt.Printf("%x\n", record)
return nil
},
); err != nil {
panic(err)
}
}
Output: 0101 0202 0303
Index ¶
- Constants
- Variables
- type Config
- type Factory
- type Store
- func (store *Store) Add(ctx context.Context, record []byte) error
- func (store *Store) Close() error
- func (store *Store) ForEachSorted(ctx context.Context, yield func([]byte) error) (result error)
- func (Store) GoString() string
- func (Store) LogValue() slog.Value
- func (Store) MarshalJSON() ([]byte, error)
- func (Store) String() string
Examples ¶
Constants ¶
const ( // AES256KeyBytes is the exact key size accepted by Factory.Open. AES256KeyBytes = 32 // MaximumMergeFiles is the hard upper bound for one merge fan-in. MaximumMergeFiles = 64 // MaximumRecordBytes bounds one fixed-size record. MaximumRecordBytes = 1 << 20 // MaximumChunkRecords bounds the number of records held in memory. MaximumChunkRecords = 1_000_000 // MaximumChunkBytes bounds the contiguous in-memory sort buffer. MaximumChunkBytes = 256 << 20 )
Variables ¶
var ( ErrInvalidConfiguration = errors.New( "external sort configuration is invalid", ) ErrUnsafeParent = errors.New( "external sort parent is not an owner-only directory", ) ErrInvalidKey = errors.New("external sort key is invalid") ErrInvalidRecord = errors.New("external sort record is invalid") ErrRecordLimit = errors.New("external sort record limit reached") ErrConcurrentUse = errors.New("external sort store is already in use") ErrClosed = errors.New("external sort store is closed") ErrFinalized = errors.New("external sort store is finalized") ErrEntropy = errors.New("external sort entropy failed") ErrStorage = errors.New("external sort storage failed") ErrCorrupt = errors.New("external sort chunk is corrupt") )
Functions ¶
This section is empty.
Types ¶
type Config ¶
Config declares every storage and memory bound before temporary storage is opened. MaximumRecords divided into ChunkRecords MUST fit one merge of at most MaximumMergeFiles.
type Factory ¶
type Factory struct {
// contains filtered or unexported fields
}
Factory validates a reusable external-sort storage policy. Factory is safe for concurrent use. Each Store permits one active lifecycle operation.
func NewFactory ¶
NewFactory validates bounds and requires an existing non-symlink parent whose group and other permission bits are clear.
func (Factory) GoString ¶
GoString prevents configuration and temporary paths from entering debug representations.
func (Factory) MarshalJSON ¶
MarshalJSON prevents configuration and temporary paths from entering JSON.
func (*Factory) Open ¶
Open creates one owner-only temporary work directory. The caller provides an AES-256 key for immediate cipher construction. The caller MUST call Close whenever Open returns a non-nil Store, including together with an error; an error result can carry ownership of construction residue whose first removal attempt failed.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store owns encrypted temporary chunks for one sort. Overlapping or reentrant lifecycle calls return ErrConcurrentUse. A record passed to the ForEachSorted callback is valid only until that callback returns.
func (*Store) Add ¶
Add copies one record into the bounded in-memory chunk. A failed Add does not retain the supplied record and may be retried unless temporary cleanup fails, in which case only Close is accepted.
func (*Store) Close ¶
Close clears in-memory records and removes the complete work directory. It is idempotent. A storage failure leaves the store closable so cleanup can be retried, but no other operation is accepted after closing begins.
func (*Store) ForEachSorted ¶
ForEachSorted finalizes input and yields every record in ascending byte order. Duplicate records are preserved. Once pending input is spilled, the store remains finalized even when merge iteration, authentication, cancellation, or the callback fails.
func (Store) GoString ¶
GoString prevents records, cipher state, and temporary paths from entering debug representations.
func (Store) LogValue ¶
LogValue prevents records, cipher state, and temporary paths from entering slog.
func (Store) MarshalJSON ¶
MarshalJSON prevents records, cipher state, and temporary paths from entering JSON.