func Open(path string, opts ...DiskOption) (*Diskstore, error) {
	disk := &Diskstore{
		path:     path,
		maxage:   24 * time.Hour,
		maxsize:  1 << 30,
		stop:     make(chan struct{}),
		wg:       sync.WaitGroup{},
		warm:     make(chan struct{}),
		readymu:  sync.RWMutex{},
		ready:    make(map[uint64]file),
		ticker:   time.NewTicker(5 * time.Minute),
		now:      time.Now,
		debug:    nil,
		compress: false,
	}
	for _, opt := range opts {
		if err := opt(disk); err != nil {
			return nil, err
		}
	}
	if err := disk.init(); err != nil {
		return nil, err
	}
	disk.wg.Add(1)
	go disk.warmup()
	if disk.ticker != nil {
		disk.wg.Add(1)
		go disk.sweeper()
	}
	return disk, nil
}
Open opens a new disk storage.

It is up to the caller to ensure that the given path will
not be changed by different processes, the diskstore doesn't
implement any filesystem level locking.
package antcache
import (
	"context"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"sort"
	"strconv"
	"sync"
	"time"
	"github.com/golang/snappy"
)
type file struct {
	key   uint64
	path  string
	mtime time.Time
	size  int64
}
type DiskOption func(*Diskstore) error
func Maxage(age time.Duration) DiskOption {
	return func(ds *Diskstore) error {
		ds.maxage = age
		return nil
	}
}
func Maxsize(size int64) DiskOption {
	return func(ds *Diskstore) error {
		ds.maxsize = size
		return nil
	}
}
func SweepEvery(d time.Duration) DiskOption {
	return func(ds *Diskstore) error {
		if d > 0 {
			ds.ticker = time.NewTicker(d)
		} else {
			ds.ticker.Stop()
			ds.ticker = nil
		}
		return nil
	}
}
func Compress() DiskOption {
	return func(ds *Diskstore) error {
		ds.compress = true
		return nil
	}
}
type DebugFunc func(format string, args ...interface{})
func Debug(f DebugFunc) DiskOption {
	return func(ds *Diskstore) error {
		ds.debug = f
		return nil
	}
}
type Diskstore struct {
	path     string
	dir      *os.File
	maxage   time.Duration
	maxsize  int64
	stop     chan struct{}
	warm     chan struct{}
	wg       sync.WaitGroup
	ticker   *time.Ticker
	readymu  sync.RWMutex
	ready    map[uint64]file
	now      func() time.Time
	debug    DebugFunc
	compress bool
}