writeaheadlog

package
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 1, 2020 License: Apache-2.0 Imports: 15 Imported by: 6

Documentation

Index

Examples

Constants

View Source
const (
	// PageSize is the size of a page in Wal logfile
	PageSize = 4096
)

Variables

This section is empty.

Functions

func New

func New(path string) (*Wal, []*Transaction, error)

New create a new Wal file with the path as logfile

Types

type Operation

type Operation struct {
	Name string
	Data []byte
}

Operation is a single operation defined by a name and data

type Transaction

type Transaction struct {
	ID         uint64      // Each transaction is assigned a unique id
	Operations []Operation // Each transaction is composed of a list of Operations

	InitComplete chan struct{}
	InitErr      error
	// contains filtered or unexported fields
}

Transaction is a batch of Operations to be committed as a whole

func (*Transaction) Append

func (t *Transaction) Append(ops []Operation) <-chan error

Append appends additional updates to a transaction

func (*Transaction) Commit

func (t *Transaction) Commit() <-chan error

Commit returns a error channel which will block until commit finished. The content is error nil if no error in commit, and error if there is an error

func (*Transaction) Release

func (t *Transaction) Release() error

Release informs the WAL that it is safe to reuse t's pages.

type Wal

type Wal struct {
	// contains filtered or unexported fields
}

Wal is a golang implementation of write-ahead-log to perform ACID transactions

Example
testDir := tempDir("ExampleWal")
_ = os.Mkdir(testDir, 0777)
// create a new wal
wal, txns, err := New(filepath.Join(testDir, "test.wal"))
if len(txns) != 0 {
	fmt.Printf("Unexpected transaction number. Got %d, Expect %d\n", len(txns), 0)
	return
}
if err != nil {
	fmt.Printf("Cannot new wal: %v\n", err)
	return
}
// struct to be modified
p := person{name: "jacky"}
newName := "wyx"
op := Operation{
	Name: "person_rename",
	Data: []byte(newName),
}
t, err := wal.NewTransaction([]Operation{op})
fmt.Println("Add a new transaction")
if err != nil {
	fmt.Printf("new transaction error: %v\n", err)
	return
}
p.name = newName
<-t.InitComplete
if t.InitErr != nil {
	fmt.Println(t.InitErr)
	return
}
commitDone := t.Commit()
if err := <-commitDone; err != nil {
	fmt.Println("error commit")
	return
}
err = wal.Close()
fmt.Printf("Close: %v\n", err)

// reopen
recoveredWal, recoveredTxn, err := New(filepath.Join(testDir, "test.wal"))
if err != nil {
	fmt.Println("reopen wal error:", err)
	return
}
if len(recoveredTxn) != 1 {
	fmt.Printf("expected recovered txn 1, got %d\n", len(recoveredTxn))
	return
}
for _, txn := range recoveredTxn {
	for _, op := range txn.Operations {
		p.name = string(op.Data)
		err := p.saveToDisk(filepath.Join(testDir, "jacky_person.dat"))
		if err != nil {
			fmt.Printf("failed save to disk: %v", err)
			return
		}
	}
	txn.Release()
}
err = recoveredWal.Close()
if err != nil {
	fmt.Printf("wal doesn't close clean: %v", err)
}
Output:

Add a new transaction
Close: wal closed with 1 unfinished transactions

func (*Wal) Close

func (w *Wal) Close() error

Close close the Wal. Return error if there are still unfinished transactions

func (*Wal) CloseIncomplete

func (w *Wal) CloseIncomplete() (int64, error)

CloseIncomplete close the Wal. Return number of unfinished transactions, and an error for closing the logfile.

func (*Wal) NewTransaction

func (w *Wal) NewTransaction(ops []Operation) (*Transaction, error)

NewTransaction create a new transaction. Start a thread to write the Operations to disk.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL