/store

File backed element store with caching and async writes

Primary LanguageGoMIT LicenseMIT

store

-- import "github.com/sebcat/store"

concurrency-safe file-backed element store

- Asynchronous writes (errors reported on next action)
- Optional cache with LRU eviction on either
  store insertion or store retrieval

To avoid a lot of casting from store.Element on Store#Get, you should probably write a wrapper around this element store for each type you intend to use it for.

Pull requests welcome

Usage

var (
	ErrAlreadyExists = errors.New("element already exists in store")
	ErrDoesNotExist  = errors.New("element not present in store")
)

type Cache

type Cache interface {
	// update (insert, promote) an element in the cache
	Cache(Element)

	// retrieve an Element from the cache, or nil if non-existant
	Get(id ElementID) Element
}

type CacheMode

type CacheMode int

Tells the store when to pass an element to the cache

const (
	CacheOnGet CacheMode = (1 << 0)
	CacheOnPut           = (1 << 1)
)

type Element

type Element interface {
	// load an element from a reader
	Load(io.Reader) error

	// store an element to a writer
	Store(io.Writer) error

	// must return a file-system safe ID
	// the two first letters of ID will be
	// used to create directories and the
	// complete ID string will be used as
	// a file name
	ID() ElementID
}

type ElementID

type ElementID uint64

func (*ElementID) FromString

func (id *ElementID) FromString(str string) error

func (ElementID) String

func (id ElementID) String() string

type LRUCache

type LRUCache struct {
}

cache with LRU eviction policy

func NewLRUCache

func NewLRUCache(size int) *LRUCache

create a new cache with room for 'size' elements

func (*LRUCache) Cache

func (l *LRUCache) Cache(el Element)

update (insert, promote) an element in the cache

func (*LRUCache) Get

func (l *LRUCache) Get(id ElementID) Element

retrieve an element from the cache, or nil if the element is not in cache

type Store

type Store struct {
}

func New

func New(path string) (*Store, error)

func (*Store) Get

func (s *Store) Get(element Element) (Element, error)

retrieve an Element either from cache or from disk. If retrieved from cache, the cache Element will be returned. If retrieved from disk, the Element passed to Get will be loaded with the data from disk. Therefor, this function should always be called like:

var el = SomeElement{ID: someID}
ret, err := s.Get(&el)

func (*Store) Has

func (s *Store) Has(id ElementID) bool

func (*Store) Put

func (s *Store) Put(el Element) error

func (*Store) Remove

func (s *Store) Remove() error

func (*Store) SetCache

func (s *Store) SetCache(c Cache, mode CacheMode)

func (*Store) Sync

func (s *Store) Sync()