ybc

package
v0.0.0-...-3d48053 Latest Latest
Warning

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

Go to latest
Published: Dec 7, 2018 License: BSD-2-Clause Imports: 9 Imported by: 9

README

Go wrapper around YBC library - see https://github.com/valyala/ybc .

The wrapper has the following features:

  * it is intended for creating extremly fast in-process blob caches,
    which can efficiently cache virtually unlimited number of items.

  * it knows how to deal with huge items (i.e. videos, audios, images)
    and caches exceeding available RAM sizes by multiple orders of magnitude.

  * it supports persistent caches surviving application restarts.

  * it is optimized for both HDDs and SSDs.

  * it is optimized for speed.

------------------------
How to build and use it?

$ go get -u github.com/valyala/ybc/bindings/go/ybc

Then import it into your program:

import "github.com/valyala/ybc/bindings/go/ybc"

Documentation can be generated by:

$ go doc github.com/valyala/ybc/bindings/go/ybc

or read at https://godoc.org/github.com/valyala/ybc/bindings/go/ybc

Documentation

Overview

Package ybc provides Go wrapper around YBC library - see https://github.com/valyala/ybc .

YBC is intended for creating extremly fast in-process blob caches, which can efficiently cache virtually unlimited number of items.

YBC knows how to deal with huge items (i.e. videos, audios, images) and caches exceeding available RAM sizes by multiple orders of magnitude.

YBC supports persistent caches surviving application restarts.

YBC is optimized for both HDDs and SSDs.

Index

Constants

View Source
const (
	// Disables periodic data syncing if assigned to Config.SyncInterval.
	ConfigDisableSync = time.Duration(-1)
)

Variables

View Source
var (
	ErrNoSpace       = errors.New("ybc: not enough space in the cache")
	ErrCacheMiss     = errors.New("ybc: the item is not found in the cache")
	ErrOpenFailed    = errors.New("ybc: cannot open the cache")
	ErrOutOfRange    = errors.New("ybc: out of range offset")
	ErrPartialCommit = errors.New("ybc: partial commit")
	ErrWouldBlock    = errors.New("ybc: the operation would block")
)
View Source
var (
	// Maximum time to live for cached items.
	//
	// Use this value when adding items, which must live in the cache as long
	// as possible.
	MaxTtl = time.Hour * 24 * 365 * 100
)

Functions

This section is empty.

Types

type Cache

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

Cache handler.

It is optimized for working with large objects (up to 2Gb each). The number of large objects doesn't matter.

Consider using SimpleCache for storing small objects (up to 1Kb). It has better performance scalability on multi-CPU system.

func (*Cache) AppendGet

func (cache *Cache) AppendGet(dst, key []byte) ([]byte, error)

AppendGet appends value associated with the given key to dst and returns the appended dst (which may be newly allocated)

func (*Cache) Clear

func (cache *Cache) Clear()

Instantly removes all the cache contents.

This method is very fast - its' speed doesn't depend on the number of items stored in the cache and on the size of the cache.

func (*Cache) Close

func (cache *Cache) Close() error

Closes the cache.

All opened caches must be closed with this call! Do not close the same cache more than once!

func (*Cache) Delete

func (cache *Cache) Delete(key []byte) bool

Deletes value associated with the given key from the cache.

Returns true on success, false if there was no such value in the cache.

func (*Cache) Get

func (cache *Cache) Get(key []byte) (value []byte, err error)

Returns value associated with the given key from the cache.

Sets err to ErrCacheMiss on cache miss.

Do not use this method for obtaining big values from the cache such as video files - use Cache.GetItem() instead.

func (*Cache) GetDe

func (cache *Cache) GetDe(key []byte, graceDuration time.Duration) (value []byte, err error)

Returns value associated with the given key from the cache using automatic protection against dogpile effect during graceDuration interval.

graceDuration is the expected time required for creating the item if it is missing in the cache, i.e. if GetDe() sets err to ErrCacheMiss. If the caller found missing item with GetDe() call, it should try creating the item and storing it into the cache during graceDuration interval.

Since Cache.GetDe() is slower than Cache.Get(), use it only for items vulnerable to dogpile effect.

Do not use this method for obtaining big values from the cache such as video files - use Cache.GetDeItem() instead.

func (*Cache) GetDeAsync

func (cache *Cache) GetDeAsync(key []byte, graceDuration time.Duration) (value []byte, err error)

The same as Cache.GetDe(), but sets err to ErrWouldBlock instead of waiting for the value affected by dogpile effect.

Do not use this method for obtaining big values from the cache such as video files - use Cache.GetDeAsyncItem() instead.

func (*Cache) GetDeAsyncItem

func (cache *Cache) GetDeAsyncItem(key []byte, graceDuration time.Duration) (item *Item, err error)

The same as Cache.GetDeAsync(), but returns item instead of item's value.

The returned item must be closed with item.Close() call!

Use this method instead of Cache.GetDeAsync() for obtaining big values from the cache such as video files.

func (*Cache) GetDeItem

func (cache *Cache) GetDeItem(key []byte, graceDuration time.Duration) (item *Item, err error)

The same as Cache.GetDe(), but returns item instead of item's value.

The returned item must be closed with item.Close() call!

Use this method instead of Cache.GetDe() for obtaining big values from the cache such as video files.

func (*Cache) GetItem

func (cache *Cache) GetItem(key []byte) (item *Item, err error)

The same as Cache.Get(), but returns item instead of item's value.

Sets err to ErrCacheMiss on cache miss.

The returned item must be closed with item.Close() call!

Use this method instead of Cache.Get() for obtaining big values from the cache such as video files.

func (*Cache) NewSetTxn

func (cache *Cache) NewSetTxn(key []byte, valueSize int, ttl time.Duration) (txn *SetTxn, err error)

Starts new 'set transaction' for storing an item in the cache with the given valueSize size, the given ttl and the given key.

Returned txn must be finished with txn.Commit*() or txn.Rollback() calls.

Use this method instead of Cache.Set() for storing big items in the cache such as video files.

func (*Cache) Set

func (cache *Cache) Set(key []byte, value []byte, ttl time.Duration) error

Stores value with the given key and the given ttl in the cache.

Do not use this method for storing big values in the cache such as video files - use Cache.NewSetTxn() instead.

func (*Cache) SetItem

func (cache *Cache) SetItem(key []byte, value []byte, ttl time.Duration) (item *Item, err error)

The same as Cache.Set(), but additionally returns item object associated with just addded item.

The returned item must be closed with item.Close() call!

type Cacher

type Cacher interface {
	SimpleCacher
	GetDe(key []byte, graceDuration time.Duration) (value []byte, err error)
	GetDeAsync(key []byte, graceDuration time.Duration) (value []byte, err error)
	SetItem(key []byte, value []byte, ttl time.Duration) (item *Item, err error)
	GetItem(key []byte) (item *Item, err error)
	GetDeItem(key []byte, graceDuration time.Duration) (item *Item, err error)
	GetDeAsyncItem(key []byte, graceDuration time.Duration) (item *Item, err error)
	NewSetTxn(key []byte, valueSize int, ttl time.Duration) (txn *SetTxn, err error)
}

Cache and Cluster implement this interface

type Cluster

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

Cluster of caches.

func (*Cluster) AppendGet

func (cluster *Cluster) AppendGet(dst, key []byte) ([]byte, error)

See Cache.AppendGet()

func (*Cluster) Clear

func (cluster *Cluster) Clear()

See Cache.Clear()

func (*Cluster) Close

func (cluster *Cluster) Close() error

Closes the cluster.

Each opened cluster must be closed only once!

func (*Cluster) Delete

func (cluster *Cluster) Delete(key []byte) bool

See Cache.Delete()

func (*Cluster) Get

func (cluster *Cluster) Get(key []byte) (value []byte, err error)

See Cache.Get()

func (*Cluster) GetDe

func (cluster *Cluster) GetDe(key []byte, graceDuration time.Duration) (value []byte, err error)

See Cache.GetDe()

func (*Cluster) GetDeAsync

func (cluster *Cluster) GetDeAsync(key []byte, graceDuration time.Duration) (value []byte, err error)

See Cache.GetDeAsync()

func (*Cluster) GetDeAsyncItem

func (cluster *Cluster) GetDeAsyncItem(key []byte, graceDuration time.Duration) (item *Item, err error)

See Cache.GetDeAsyncItem()

func (*Cluster) GetDeItem

func (cluster *Cluster) GetDeItem(key []byte, graceDuration time.Duration) (item *Item, err error)

See Cache.GetDeItem()

func (*Cluster) GetItem

func (cluster *Cluster) GetItem(key []byte) (item *Item, err error)

See Cache.GetItem()

func (*Cluster) NewSetTxn

func (cluster *Cluster) NewSetTxn(key []byte, valueSize int, ttl time.Duration) (txn *SetTxn, err error)

See Cache.NewSetTxn()

func (*Cluster) Set

func (cluster *Cluster) Set(key []byte, value []byte, ttl time.Duration) error

See Cache.Set()

func (*Cluster) SetItem

func (cluster *Cluster) SetItem(key []byte, value []byte, ttl time.Duration) (item *Item, err error)

See Cache.SetItem()

type ClusterConfig

type ClusterConfig []*Config

Configuration required for opening a Cluster.

func (ClusterConfig) OpenCluster

func (cfg ClusterConfig) OpenCluster(force bool) (cluster *Cluster, err error)

Opens a cluster of caches.

Tries fixing the following errors if force is set to true:

  • creating missing index and data files;
  • adjusting invalid sizes for index and data files.

Cluster of caches may work faster than a single Cache only if the following conditions are met:

  • The total size of frequently accessed items in the cluster exceeds available RAM size.
  • Backing files for distinct caches in the cluster are located on distinct physical storages.

The returned cluster must be closed with cluster.Close() call!

Do not open the same cluster more than once at the same time!

func (ClusterConfig) RemoveCluster

func (cfg ClusterConfig) RemoveCluster()

Removes all files associated with the cluster.

type Config

type Config struct {
	// The maximum number of items the cache can store.
	MaxItemsCount SizeT

	// Cache size (in bytes).
	DataFileSize SizeT

	// Path to index file for the cache.
	//
	// Set this field if you want cache surviving application restarts.
	// The size of index file is proportional to Config.MaxItemsCount.
	//
	// Leave this field empty if you want temporary cache, which is
	// destroyed on application exit.
	IndexFile string

	// Path to data file for the cache.
	//
	// Set this field if you want cache surviving application restarts.
	// The size of data file is equivalent to Config.DataFileSize.
	//
	// Leave this field empty if you want temporary cache, which is
	// destroyed on application exit.
	DataFile string

	// The expected number of hot items in the cache.
	//
	// Setting HotItemsCount to non-zero value enables 'hot items'
	// optimization. This optimization can improve performance for huge
	// caches containing many rarely accessed items (aka 'cold items') and
	// a relatively small number of frequently accessed items
	// (aka 'hot items').
	//
	// Leave this field empty (set to 0) in the following cases:
	//   * if your cache contains less than 1M items.
	//   * if the number of cold items in your cache is comparable to
	//     or smaller than the number of hot items.
	//   * if you are unsure :)
	HotItemsCount SizeT

	// The expected size of hot data in the cache (in bytes).
	//
	// Setting HotDataSize to non-zero value enables 'hot data'
	// optimization. This optimization can improve performance for caches
	// containing many small items, where only a small part of these items
	// are frequently accessed (aka 'hot items'). Setting HotDataSize
	// to value close to summary size of hot items in the cache may improve
	// cache performance.
	//
	// Leave this field empty (set to 0) in the following cases:
	//   * if your cache contains only big items with sizes exceeding 64Kb
	//     (for instance, videos, music files, images, etc.).
	//   * if the number of cold items in your cache is comparable to
	//     or smaller than the number of hot items.
	//   * if you are unsure :)
	HotDataSize SizeT

	// The number of buckets in the hashtable used for tracking items
	// affected by dogpile effect.
	//
	// Tune this value only if you plan using dogpile effect-aware
	// functions. This value should be close to the average number
	// of distinct pending items concurrently affected by dogpile effect.
	//
	// Leave this field empty (set to 0) if you are in doubt.
	//
	// Read more about dogpile effect
	// at https://www.google.com/search?q=dogpile+effect .
	DeHashtableSize int

	// Interval for cache syncing to data file.
	//
	// Items added to the cache are synced to data file with this interval.
	// Non-synced cache items may be lost after the program crash or
	// the operating system crash.
	//
	// Setting SyncInterval to ConfigDisableSync disables data syncing.
	// Even if syncing is disabled, all cache items are persisted
	// on Cache.Close() call.
	//
	// Leave this field empty (set to 0) if you are in doubt.
	SyncInterval time.Duration
}

Cache configuration.

func (*Config) OpenCache

func (cfg *Config) OpenCache(force bool) (cache *Cache, err error)

Opens Cache.

If force is true, then tries fixing the following non-critical errors instead of returning ErrOpenFailed:

  • creates missing index or data files.
  • fixes incorrect sizes for index or data files.

Do not open the same cache more than once at the same time!

The returned cache must be closed with cache.Close() call! Prefer using defer for closing opened caches:

cache, err := config.OpenCache(true)
if err != nil {
  log.Fatalf("Error when opening the cache: [%s]", err)
}
defer cache.Close()

func (*Config) OpenSimpleCache

func (cfg *Config) OpenSimpleCache(force bool) (sc *SimpleCache, err error)

Opens SimpleCache.

Consider using Cache instead of SimpleCache if you plan storing objects in the cache bigger than a few Kb.

If force is true, then tries fixing the following non-critical errors instead of returning ErrOpenFailed:

  • creates missing index or data files.
  • fixes incorrect sizes for index or data files.

Do not open the same cache more than once at the same time!

The returned cache must be closed with cache.Close() call! Prefer using defer for closing opened caches:

sc, err := config.OpenSimpleCache(true)
if err != nil {
  log.Fatalf("Error when opening the cache: [%s]", err)
}
defer sc.Close()

func (*Config) RemoveCache

func (cfg *Config) RemoveCache()

Removes cache files from filesystem.

type Item

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

Cache item.

func (*Item) Append

func (item *Item) Append(dst []byte) []byte

Append appends the item's value to dst and returns the result (which may be newly allocated)

func (*Item) Available

func (item *Item) Available() int

Returns the number of bytes remaining to read from the item.

func (*Item) Close

func (item *Item) Close() error

Closes the item.

Every opened item must be closed only once!

func (*Item) Peek

func (item *Item) Peek() []byte

Peek returns item contents.

The returned contents is valid until item is closed with Close. Use Value for obtaining item contents valid after Close.

func (*Item) Read

func (item *Item) Read(p []byte) (n int, err error)

io.Reader interface implementation

func (*Item) ReadAt

func (item *Item) ReadAt(p []byte, offset int64) (n int, err error)

io.ReaderAt interface implementation

func (*Item) ReadByte

func (item *Item) ReadByte() (c byte, err error)

io.ByteReader interface implementation

func (*Item) Seek

func (item *Item) Seek(offset int64, whence int) (ret int64, err error)

io.Seeker interface implementation

func (*Item) Size

func (item *Item) Size() int

Returns the size of value associated with the item.

func (*Item) Ttl

func (item *Item) Ttl() time.Duration

Returns remaining ttl for the item.

func (*Item) Value

func (item *Item) Value() []byte

Returns value associated with the item.

Do not use this method for obtaining big values such as video files - use Peek or io.* interface implementations provided by the Item instead.

func (*Item) WriteTo

func (item *Item) WriteTo(w io.Writer) (n int64, err error)

io.WriterTo interface implementation

type SetTxn

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

'set transaction' handler. It is used for efficient storage of big items in the cache such as video files.

func (*SetTxn) Commit

func (txn *SetTxn) Commit() (err error)

Commits the transaction.

The item appears atomically in the cache after the commit.

func (*SetTxn) CommitItem

func (txn *SetTxn) CommitItem() (item *Item, err error)

The same as SetTxn.Commit(), but additionally returns commited item.

The returned item must be closed with item.Close() call!

func (*SetTxn) CommitItemTruncated

func (txn *SetTxn) CommitItemTruncated() (item *Item, err error)

The same as SetTxn.CommitTruncated(), but additionally returns commited item.

The returned item must be closed with item.Close() call!

func (*SetTxn) CommitTruncated

func (txn *SetTxn) CommitTruncated() error

Commits the truncated transaction.

Truncated transaction is partially filled transaction. I.e. its' size is smaller than valueSize passed to Cache.NewSetTxn()

func (*SetTxn) ReadFrom

func (txn *SetTxn) ReadFrom(r io.Reader) (n int64, err error)

io.ReaderFrom interface implementation

func (*SetTxn) Rollback

func (txn *SetTxn) Rollback()

Rolls back the transaction.

func (*SetTxn) Write

func (txn *SetTxn) Write(p []byte) (n int, err error)

io.Writer interface implementation

type SimpleCache

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

Simple Cache handler.

This is a cache with simplified API comparing to Cache API. SimpleCache is optimized for working with small objects (up to 1Kb each). The number of small objects doesn't matter. Its' performance scales better on multi-CPU systems comparing to Cache.

Consider using Cache instead of SimpleCache for storing large objects such as images, audio and video files, since SimpleCache has much higher overhead when working with large objects.

Note that objects stored via SimpleCache cannot be read via Cache and vice versa.

func (*SimpleCache) AppendGet

func (sc *SimpleCache) AppendGet(dst, key []byte) ([]byte, error)

AppendGet appends value associated with the given key to dst and returns the appended dst (which may be newly allocated)

func (*SimpleCache) Clear

func (sc *SimpleCache) Clear()

Clears the cache, i.e. removes all the items stored in the cache.

func (*SimpleCache) Close

func (sc *SimpleCache) Close() error

Closes the cache.

All opened caches must be closed with this call! Do not close the same cache more than once.

func (*SimpleCache) Delete

func (sc *SimpleCache) Delete(key []byte) bool

Deletes an item associated with the given key.

Returns true if the given item has been deleted. Returns false if there were no item with such key in the cache.

func (*SimpleCache) Get

func (sc *SimpleCache) Get(key []byte) (value []byte, err error)

Returns value associated with the given key

func (*SimpleCache) Set

func (sc *SimpleCache) Set(key, value []byte, ttl time.Duration) error

Stores the given (key, value) pair with the given ttl in the cache.

type SimpleCacher

type SimpleCacher interface {
	Set(key []byte, value []byte, ttl time.Duration) error
	Get(key []byte) (value []byte, err error)
	AppendGet(dst, key []byte) ([]byte, error)
	Delete(key []byte) bool
	Clear()
	Close() error
}

SimpleCache, Cache and Cluster implement this interface

type SizeT

type SizeT uintptr

Type used in Config for setting big numbers, which may exceed int capacity.

Though the hack with SizeT raises the maximum cache size from 2^31-1 to 2^63-1, it doesn't help with the maximum cache item size. Ybc uses byte slices for represening cache items. So the maximum cache item size is limited by the maximum size of a slice. Currently this limit is set to 2^31-1 - the maximum value, which can be stored in int type on all platforms.

TODO(valyala): substitute SizeT by int after sizeof(int) will become 8 on 64-bit architectures. Currently amd64's sizeof(int) = 4. See http://golang.org/doc/go_faq.html#q_int_sizes for details.

Jump to

Keyboard shortcuts

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