Skip to content

Repository files navigation

ExpiryMap logo

GitHub Release Go Reference ci OpenSSF Scorecard

ExpiryMap is a generic, concurrency-safe Go map whose entries clean up after the set expiry delay. It has no external dependencies and uses only the standard library.

Every Set gives an entry a fresh lease on life, and a background goroutine periodically sweeps out everything older than the expiry delay. The result is cache-like TTL behaviour with a plain map API — no external dependencies, standard library only.

Why ExpiryMap?

Expired entries are actively removed by the background sweeper, whether or not you ever touch them again. Memory is reclaimed on its own, and Len() and Iterate() always reflect exactly what is still alive — no manual eviction, no bookkeeping on your side.

Features

  • The map key can be any generic comparable type
  • The map value can be any generic type
  • The map is safe for concurrent use
  • The expiry delay is specified as a time.Duration value

Installation

go get github.com/TheoBrigitte/expirymap

Requires Go 1.26 or later.

Methods

  • New(expiryDelay, gargabeCleanInterval time.Duration) *Map[K, V] - creates a new Map and starts its garbage cleaner
  • Get(key K) (V, bool) - returns the value for a key, and whether it was found
  • Set(key K, data V) - sets the value for a key and resets its expiry time
  • Delete(key K) - removes a single entry
  • Len() int - returns the number of entries in the map
  • Iterate() iter.Seq2[K, V] - returns an iterator over all entries in the map
  • Clear() - removes all entries from the map
  • Stop() - stops the background goroutine that removes expired entries

Examples

package main

import (
	"fmt"
	"time"

	"github.com/TheoBrigitte/expirymap"
)

func main() {
	// Define a key and a value.
	key := 1
	value := []string{"foo", "bar", "baz"}

	// Create a new expiry map of type map[int][]string
	// with an expiry delay of 1ns and a garbage collection interval of 1ms.
	m := expirymap.New[int, []string](time.Nanosecond, time.Millisecond)
	defer m.Stop()

	// Set 1=[foo bar baz] in the map.
	m.Set(key, value)

	fmt.Println(m.Get(1))            // [foo bar baz] true
	time.Sleep(time.Millisecond * 2) // Wait for the entry to expire.
	fmt.Println(m.Get(1))            // [] false
}

source example/simple/simple.go

Iterating over the entries with a for ... range loop:

package main

import (
	"fmt"
	"time"

	"github.com/TheoBrigitte/expirymap"
)

func main() {
	// Create a new map[int]string with an expiry delay of 5s and a garbage collection interval of 1s.
	m := expirymap.New[int, string](time.Second*5, time.Second)
	defer m.Stop()

	// Set 1=foo, 2=bar, 3=baz in the map.
	m.Set(1, "foo")
	m.Set(2, "bar")
	m.Set(3, "baz")

	// Iterate over the map and print the key and value.
	for k, v := range m.Iterate() {
		fmt.Println(k, v)
	}
}

source example/iterator/iterator.go

Documentation

Full API reference is available on pkg.go.dev.

License

MIT

About

Golang expirable map package

Topics

Resources

Security policy

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages