cof

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Apr 2, 2026 License: MIT Imports: 5 Imported by: 0

README

cof

A lightweight, generic, thread-safe in-memory key-value cache for Go with TTL-based expiration and automatic background cleanup.

Features

  • Generic -- store any value type via Go generics
  • Thread-safe -- all operations are protected by a sync.RWMutex
  • TTL expiration -- default TTL per cache, per-item override with PutWithTTL
  • Automatic cleanup -- background goroutine periodically removes expired entries
  • Lazy expiration -- Get, Pop, Has, Len, and Keys never return expired items even between cleanups

Install

go get github.com/leonidasdeim/cof

Requires Go 1.23+.

Quick start

package main

import (
    "fmt"
    "time"

    "github.com/leonidasdeim/cof"
)

func main() {
    c, err := cof.Init[string](
        cof.TTL(5 * time.Minute),
        cof.CleanInterval(1 * time.Minute),
    )
    if err != nil {
        panic(err)
    }
    defer c.Stop()

    c.Put("greeting", "hello, world!")

    v, ok := c.Get("greeting")
    fmt.Println(v, ok) // hello, world! true
}

API

Creating a cache
c, err := cof.Init[ValueType](opts ...cof.Option)
Options
Option Default Description
cof.TTL(d) 15 min Default TTL for entries. Pass 0 to disable expiration.
cof.CleanInterval(d) 1 min How often the cleaner runs. Pass 0 to disable background cleanup.
Operations
Method Description
Put(key, value) Insert/update with the default TTL
PutWithTTL(key, value, ttl) Insert/update with a custom TTL (0 = no expiry)
Get(key) (T, bool) Retrieve a value; returns false if missing or expired
Pop(key) (T, bool) Retrieve and delete; returns false if missing or expired
Delete(key) Remove an entry
Has(key) bool Check existence (expired entries return false)
Len() int Count of live entries
Keys() []string Sorted slice of live keys
Clear() Remove all entries (keeps the cleaner running)
Stop() Remove all entries and stop the background goroutine

License

MIT

Documentation

Overview

Package cof provides a lightweight, generic, thread-safe in-memory key-value cache with TTL-based expiration and automatic cleanup.

Index

Examples

Constants

View Source
const (
	// OFF disables time-based behaviour (TTL or cleanup interval).
	OFF = 0
)

Variables

View Source
var (
	ErrInvalidTTL           = errors.New("cof: TTL must be non-negative")
	ErrInvalidCleanInterval = errors.New("cof: clean interval must be non-negative")
)

Errors returned by Init when the supplied options are invalid.

Functions

This section is empty.

Types

type C

type C[T any] struct {
	// contains filtered or unexported fields
}

C is a generic, thread-safe in-memory cache whose values are of type T. Create one with Init and stop it with [Stop] when it is no longer needed.

func Init

func Init[T any](opts ...Option) (*C[T], error)

Init creates a new cache and starts a background cleanup goroutine (unless the clean interval is set to OFF). Call C.Stop to release resources when the cache is no longer needed.

Example
package main

import (
	"fmt"
	"time"

	"github.com/leonidasdeim/cof"
)

func main() {
	c, err := cof.Init[string](cof.TTL(5*time.Minute), cof.CleanInterval(1*time.Minute))
	if err != nil {
		panic(err)
	}
	defer c.Stop()

	c.Put("greeting", "hello, world!")
	v, ok := c.Get("greeting")
	fmt.Println(v, ok)
}
Output:
hello, world! true

func (*C[T]) Clear added in v0.2.0

func (c *C[T]) Clear()

Clear removes all entries from the cache without stopping the cleanup goroutine.

Example
package main

import (
	"fmt"

	"github.com/leonidasdeim/cof"
)

func main() {
	c, _ := cof.Init[string]()
	defer c.Stop()

	c.Put("a", "1")
	c.Put("b", "2")
	c.Clear()
	fmt.Println(c.Len())
}
Output:
0

func (*C[T]) Delete added in v0.2.0

func (c *C[T]) Delete(k string)

Delete removes the entry for key k. It is a no-op if the key does not exist.

Example
package main

import (
	"fmt"

	"github.com/leonidasdeim/cof"
)

func main() {
	c, _ := cof.Init[string]()
	defer c.Stop()

	c.Put("k", "v")
	c.Delete("k")

	_, ok := c.Get("k")
	fmt.Println(ok)
}
Output:
false

func (*C[T]) Get

func (c *C[T]) Get(k string) (T, bool)

Get retrieves the value for key k and returns (value, true). If the key does not exist or is expired it returns the zero value and false.

func (*C[T]) Has added in v0.2.0

func (c *C[T]) Has(k string) bool

Has reports whether the cache contains a live (non-expired) entry for key k.

Example
package main

import (
	"fmt"

	"github.com/leonidasdeim/cof"
)

func main() {
	c, _ := cof.Init[string]()
	defer c.Stop()

	fmt.Println(c.Has("k"))
	c.Put("k", "v")
	fmt.Println(c.Has("k"))
}
Output:
false
true

func (*C[T]) Keys added in v0.2.0

func (c *C[T]) Keys() []string

Keys returns the keys of all live (non-expired) entries. The order is non-deterministic.

Example
package main

import (
	"fmt"

	"github.com/leonidasdeim/cof"
)

func main() {
	c, _ := cof.Init[string]()
	defer c.Stop()

	c.Put("banana", "b")
	c.Put("apple", "a")
	fmt.Println(c.Keys())
}
Output:
[apple banana]

func (*C[T]) Len added in v0.2.0

func (c *C[T]) Len() int

Len returns the number of live (non-expired) entries currently in the cache. Note: this is O(n) because it must skip expired-but-not-yet-cleaned entries.

Example
package main

import (
	"fmt"

	"github.com/leonidasdeim/cof"
)

func main() {
	c, _ := cof.Init[string]()
	defer c.Stop()

	c.Put("a", "1")
	c.Put("b", "2")
	fmt.Println(c.Len())
}
Output:
2

func (*C[T]) Pop

func (c *C[T]) Pop(k string) (T, bool)

Pop retrieves the value for key k, removes the entry, and returns (value, true). If the key does not exist or is expired it returns the zero value and false.

Example
package main

import (
	"fmt"

	"github.com/leonidasdeim/cof"
)

func main() {
	c, _ := cof.Init[string]()
	defer c.Stop()

	c.Put("token", "abc123")
	v, ok := c.Pop("token")
	fmt.Println(v, ok)

	_, ok = c.Get("token")
	fmt.Println(ok)
}
Output:
abc123 true
false

func (*C[T]) Put

func (c *C[T]) Put(k string, v T)

Put inserts or updates a key with the cache's default TTL.

Example
package main

import (
	"fmt"

	"github.com/leonidasdeim/cof"
)

func main() {
	c, _ := cof.Init[int]()
	defer c.Stop()

	c.Put("answer", 42)
	v, _ := c.Get("answer")
	fmt.Println(v)
}
Output:
42

func (*C[T]) PutWithTTL added in v0.2.0

func (c *C[T]) PutWithTTL(k string, v T, ttl time.Duration)

PutWithTTL inserts or updates a key with a custom TTL that overrides the cache default. Pass 0 to store the item without expiration.

Example
package main

import (
	"fmt"
	"time"

	"github.com/leonidasdeim/cof"
)

func main() {
	c, _ := cof.Init[string](cof.TTL(1 * time.Hour))
	defer c.Stop()

	// This specific entry expires in 100ms, overriding the 1h default.
	c.PutWithTTL("flash", "gone soon", 100*time.Millisecond)

	v, ok := c.Get("flash")
	fmt.Println(v, ok)
}
Output:
gone soon true

func (*C[T]) Stop

func (c *C[T]) Stop()

Stop halts the background cleanup goroutine and removes all entries. After Stop is called the cache must not be reused.

type Option added in v0.2.0

type Option func(o *options)

Option configures the cache created by Init.

func CleanInterval

func CleanInterval(ci time.Duration) Option

CleanInterval sets how often the background goroutine removes expired entries. Pass 0 to disable automatic cleanup. Default: 1 minute.

func TTL

func TTL(ttl time.Duration) Option

TTL sets the default time-to-live for every entry written with C.Put. Pass 0 to keep entries forever (no expiration). Default: 15 minutes.

Jump to

Keyboard shortcuts

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