World Conquest Chronicles

World Conquest Chronicles

go-cache, v1.2

The library that implements an in-memory cache with garbage collection in two modes: total (based on a full scan) and partial (based on expiration in Redis).

Implementation of partial garbage collection (based on expiration in Redis) and of independent running of garbage collection.

Change Log

  • implementation of garbage collection:
    • independent implementation of garbage collection running;
    • implementation of partial garbage collection (based on expiration in Redis).

Features

  • implementation of an in-memory cache:
    • operations:
      • getting a value by a key:
        • signaling a reason for the absence of a key - missed or expired;
      • getting a value by a key with deletion of expired values:
        • signaling a reason for the absence of a key - missed or expired;
      • setting a key-value pair with a specified time to live:
        • support of key-value pairs without a set time to live (persistent);
      • deletion;
  • implementation of garbage collection:
    • independent implementation of garbage collection running:
      • support interruption via a context;
      • support specification of a running period;
    • implementation of total garbage collection (based on a full scan);
    • implementation of partial garbage collection (based on expiration in Redis).

Examples

cache.NewCache():

package main

import (
    "context"
    "fmt"
    "hash/fnv"
    "io"
    "time"

    cache "github.com/thewizardplusplus/go-cache"
    "github.com/thewizardplusplus/go-cache/gc"
    hashmap "github.com/thewizardplusplus/go-hashmap"
)

type StringKey string

func (key StringKey) Hash() int {
    hash := fnv.New32()
    io.WriteString(hash, string(key))

    return int(hash.Sum32())
}

func (key StringKey) Equals(other interface{}) bool {
    return key == other.(StringKey)
}

func main() {
    storage := hashmap.NewConcurrentHashMap()
    gcObj := gc.NewPartialGC(storage, time.Now)
    go gc.Run(context.Background(), gcObj, time.Millisecond)

    timeZones := cache.NewCache(storage, time.Now)
    timeZones.Set(StringKey("EST"), -5*60*60, 100*time.Millisecond)
    timeZones.Set(StringKey("CST"), -6*60*60, 100*time.Millisecond)
    timeZones.Set(StringKey("MST"), -7*60*60, 100*time.Millisecond)

    estOffset, err := timeZones.Get(StringKey("EST"))
    fmt.Println(estOffset, err)

    time.Sleep(200 * time.Millisecond)

    estOffset, err = timeZones.Get(StringKey("EST"))
    fmt.Println(estOffset, err)

    // Output:
    // -18000 <nil>
    // <nil> key missed
}

Benchmarks

With the partial GC:

BenchmarkCacheGetting_withPartialGC/Get-8            5000000          3766 ns/op         489 B/op         34 allocs/op
BenchmarkCacheGetting_withPartialGC/GetWithGC-8      2000000          7805 ns/op         877 B/op         57 allocs/op

Repository

Link: https://github.com/thewizardplusplus/go-cache/tree/v1.2.

Content: code.

License: MIT.