func NewACIDFiler(db Filer, wal *os.File, opts ...WALOption) (r *ACIDFiler0, err error) {
	fi, err := wal.Stat()
	if err != nil {
		return
	}
	r = &ACIDFiler0{wal: wal}
	for _, o := range opts {
		if err := o(&r.walOptions); err != nil {
			return nil, err
		}
	}
	if fi.Size() != 0 {
		if err = r.recoverDb(db); err != nil {
			return
		}
	}
	r.bwal = bufio.NewWriter(r.wal)
	r.newEpoch = true
	acidWriter := (*acidWriter0)(r)
	if r.RollbackFiler, err = NewRollbackFiler(
		db,
		func(sz int64) (err error) {
			if err = acidWriter.writePacket([]interface{}{wpt00Checkpoint, sz}); err != nil {
				return
			}
			if err = r.bwal.Flush(); err != nil {
				return
			}
			if err = r.wal.Sync(); err != nil {
				return
			}
			var wfi os.FileInfo
			if wfi, err = r.wal.Stat(); err != nil {
				return
			}
			r.peakWal = mathutil.MaxInt64(wfi.Size(), r.peakWal)
			for _, v := range r.data {
				n := len(v.b)
				if m := v.off + int64(n); m > sz {
					if n -= int(m - sz); n <= 0 {
						continue
					}
				}
				if _, err = db.WriteAt(v.b[:n], v.off); err != nil {
					return err
				}
			}
			if err = db.Truncate(sz); err != nil {
				return
			}
			if err = db.Sync(); err != nil {
				return
			}
			if !r.testHook {
				if err := r.emptyWAL(); err != nil {
					return err
				}
			}
			r.testHook = false
			r.bwal.Reset(r.wal)
			r.newEpoch = true
			return r.wal.Sync()
		},
		acidWriter,
	); err != nil {
		return
	}
	return r, nil
}
NewACIDFiler0 returns a  newly created ACIDFiler0 with WAL in wal.

If the WAL is zero sized then a previous clean shutdown of db is taken for
granted and no recovery procedure is taken.

If the WAL is of non zero size then it is checked for having a
committed/fully finished transaction not yet been reflected in db. If such
transaction exists it's committed to db. If the recovery process finishes
successfully, the WAL is truncated to the minimum WAL size and fsync'ed
prior to return from NewACIDFiler0.

opts allow to amend WAL properties.
package lldb
import (
	"bufio"
	"encoding/binary"
	"fmt"
	"io"
	"os"
	"github.com/cznic/fileutil"
	"github.com/cznic/mathutil"
)
var _ Filer = &ACIDFiler0{}  
type acidWrite struct {
	b   []byte
	off int64
}
type acidWriter0 ACIDFiler0
func (a *acidWriter0) WriteAt(b []byte, off int64) (n int, err error) {
	f := (*ACIDFiler0)(a)
	if f.newEpoch {
		f.newEpoch = false
		f.data = f.data[:0]
		if err = a.writePacket([]interface{}{wpt00Header, walTypeACIDFiler0, ""}); err != nil {
			return
		}
	}
	if err = a.writePacket([]interface{}{wpt00WriteData, b, off}); err != nil {
		return
	}
	f.data = append(f.data, acidWrite{b, off})
	return len(b), nil
}
func (a *acidWriter0) writePacket(items []interface{}) (err error) {
	f := (*ACIDFiler0)(a)
	b, err := EncodeScalars(items...)
	if err != nil {
		return
	}
	var b4 [4]byte
	binary.BigEndian.PutUint32(b4[:], uint32(len(b)))
	if _, err = f.bwal.Write(b4[:]); err != nil {
		return
	}
	if _, err = f.bwal.Write(b); err != nil {
		return
	}
	if m := (4 + len(b)) % 16; m != 0 {
		var pad [15]byte
		_, err = f.bwal.Write(pad[:16-m])
	}
	return
}
const (
	wpt00Header = iota
	wpt00WriteData
	wpt00Checkpoint
	wpt00Empty
)
const (
	walTypeACIDFiler0 = iota
)
type ACIDFiler0 struct {
	*RollbackFiler
	bwal       *bufio.Writer
	data       []acidWrite
	newEpoch   bool
	peakWal    int64  
	testHook   bool   
	wal        *os.File
	walOptions walOptions
}
type walOptions struct {
	headroom int64  
}
type WALOption func(*walOptions) error
func MinWAL(min int64) WALOption {
	min = mathutil.MaxInt64(0, min)
	if r := min % 16; r != 0 {
		min += 16 - r
	}
	return func(o *walOptions) error {
		o.headroom = min
		return nil
	}
}