Documentation ¶
Overview ¶
Package cache is library that allows one to easily cache results of presumably expensive (or slow) computations.
Example, you may have a line like this:
var lotsOfData = LoadOverTheInternet("https://.....")
Instead of every time any cell is run in GoNB having to load the data, you can do the following:
var lotsOfData = cache.Cache("my_data", func() *Data { return LoadOverTheInternet("https://.....") })
This will save the results of `LoadOverTheInternet` in the first call, and re-use it later.
A few considerations to keep in mind ¶
- Serialization/Deserialization: it uses `encoding/gob` by default, but alternatively if the type implements the cache.Serializable interface, it is used instead.
- Where/How to save it: the default is to create a temporary subdirectory (under `/tmp` by default) and store/re-read from there. But alternatively a new Storage object can be created which can store info anywhere.
- Error handling: Storage by default panics if an error occur when loading or saving cached results, but it can be ignored and fallback to regenerate the value. If the function being cached returns an error, see CacheErr.
- Concurrency: Storage can work concurrently for different keys but has no safety checks (mutex) for the same key, and concurrent access to the same key leads to undefined behavior.
Example where one uses a hidden subdirectory in the current subdirectory as storage.
var ( myCache = cache.MustNewHidden() lotsOfData = cache.CacheWith(myCache, "my_data", func() *Data { return LoadOverTheInternet("https://.....") }) )
Example: if in a GoNB notebook one wants to reset the data to force it to be re-generated, one can write a small cell like:
%% cache.ResetKey("my_data")
This will reset the value associated with the `my_data` key, so next execution it will be generated again.
Index ¶
Constants ¶
const HiddenCacheSubdirectory = ".gonb_cache"
HiddenCacheSubdirectory is the then name of the subdirectory used by NewHidden.
Variables ¶
var Default = MustNewInTmp()
Default caching storage, created in a temporary directory with NewInTmp -- so it gets cleaned up whenever the system is rebooted.
Functions ¶
func AssertNoError ¶
func AssertNoError(err error)
AssertNoError will `log.Fatal` if err is not nil.
func Cache ¶
Cache first checks if a value for `key` has already been saved at previous time, in which case it is deserialized and returned. if not, `fn` is called, its result is first saved using `key` and then returned.
The special case when `key` is empty ("") will not use any cache, and `fn` will always be called
It uses Default for caching, it's equivalent to calling `CacheWith(Default, key, fn)`.
func CacheWith ¶
CacheWith first checks if a value for `key` has already been saved at previous time, in which case it is deserialized and returned. if not, `fn` is called, its result is first saved using `key` and then returned.
The special case when `key` is empty ("") will not use any cache, and `fn` will always be called
The saving and loading is implemented by the given Storage object.
Types ¶
type Serializable ¶
type Serializable interface { // CacheSerialize should serialize the contents of the object to the writer. Used by the // `cache` package. CacheSerialize(writer io.Writer) error // CacheDeserialize should deserialize the object from the given `io.Reader`. It should // return either the same object or a new one of the same type with the deserialized content. // // In particular, it should work well with pointers: when one pass a nil pointer -- it should // return a pointer to the newly allocated content. CacheDeserialize(reader io.Reader) (any, error) }
Serializable interface defines a serialization/deserialization interface. It allows custom serialization if `encoding.gob` won't work for caching.
type Storage ¶
type Storage struct {
// contains filtered or unexported fields
}
Storage provides the storage for the caching functionality.
See New, NewInTmp and NewHidden functions to create a new Storage object, or use the pre-built Default.
Concurrency: Storage can work concurrently for different keys but has no safety checks (mutex) for the same key, and concurrent access to the same key leads to undefined behavior.
func MustNew ¶
MustNew is similar to New, but will log.Fatal if New fails to create the Storage for any reasons.
func MustNewHidden ¶
func MustNewHidden() *Storage
MustNewHidden is similar to NewHidden, but will log.Fatal if it fails to create the Storage for any reasons.
func MustNewInTmp ¶
func MustNewInTmp() *Storage
MustNewInTmp is similar to NewInTmp, but will log.Fatal if it fails to create the Storage for any reasons.
func New ¶
New creates a new Storage object in the given directory. Directory is created if it doesn't yet exist.
func NewHidden ¶
NewHidden crates a Storage object with the name `.gonb_cache` (HiddenCacheSubdirectory) in the current directory.
func NewInTmp ¶
NewInTmp creates a Storage object using a temporary directory whose name is a hash of the current directory -- so it will use the same if run on the same location every time.
The temporary directory is created under `os.TempDir()`.
func (*Storage) Reader ¶
Reader returns a file reader from the storage for the given key.
Return os.ErrNotExist if key does not exist in storage.