timeseries

package module
v0.0.4 Latest Latest
Warning

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

Go to latest
Published: Dec 31, 2025 License: MIT Imports: 9 Imported by: 0

README

timeseries

A simple Go library for storing timeseries data on the filesystem. Data is CBOR encoded and organized by time into a directory structure like year/month/day/hour.cbor. Each hour file can hold multiple entries.

Disclaimer

This is just a fun litle time series storage, not really meant for production use.

Install

go get github.com/zveinn/timeseries

Usage

package main

import (
    "time"
    "github.com/zveinn/timeseries"
)

type Metric struct {
    Name  string
    Value float64
}

func main() {
    // init a client with a storage path
    client, err := timeseries.Init[Metric](timeseries.Options{
        Path: "./data",
    })
    if err != nil {
        panic(err)
    }

    // store some data
    client.Store(time.Now(), Metric{Name: "cpu", Value: 45.2})
    client.Store(time.Now(), Metric{Name: "memory", Value: 78.5})

    // get data for a time range (returns pointers)
    from := time.Now().Add(-time.Hour)
    to := time.Now()
    results, err := client.Get(from, to)

    // iterate over data with a callback (return true to continue, false to stop)
    var cpuMetrics []Metric
    client.Find(from, to, func(t time.Time, data Metric) bool {
        if data.Name == "cpu" && data.Value > 50.0 {
            cpuMetrics = append(cpuMetrics, data)
        }
        return true // continue iterating
    })

    // early stop: find first metric above threshold
    var found *Metric
    client.Find(from, to, func(t time.Time, data Metric) bool {
        if data.Value > 90.0 {
            found = &data
            return false // stop iteration
        }
        return true
    })

    // delete data in a time range
    client.Delete(from, to)
}

API

  • Init[T any](opts Options) (*Client[T], error) - create a new client, walks the directory to build a cache of existing files
  • Store(date time.Time, data T) error - store data at a given time
  • Get(from, to time.Time) ([]*T, error) - get all data in a time range
  • Find(from, to time.Time, fn func(time.Time, T) bool) error - iterate over data in a time range; callback returns true to continue or false to stop early
  • Delete(from, to time.Time) error - delete all hour files in a time range

Benchmarks

Benchmarks run with 100,000 items (1 item per minute, ~69 days of data stored across ~1,667 hourly files).

goos: linux
goarch: amd64
pkg: github.com/zveinn/timeseries
cpu: AMD Ryzen 7 7840HS w/ Radeon 780M Graphics
BenchmarkA_Store-16            	       1	1022884720 ns/op	64124800 B/op	 1300513 allocs/op
BenchmarkB_Get-16              	      15	  79179142 ns/op	22050478 B/op	  420072 allocs/op
BenchmarkC1_Find_1Minute-16    	   29797	     40341 ns/op	    8637 B/op	     193 allocs/op
BenchmarkC2_Find_1Hour-16      	   28078	     41584 ns/op	   10527 B/op	     252 allocs/op
BenchmarkC3_Find_1Day-16       	    1152	   1025923 ns/op	  252657 B/op	    6048 allocs/op
BenchmarkC4_Find_1Week-16      	     168	   7089725 ns/op	 1768585 B/op	   42337 allocs/op
BenchmarkC5_Find_1Month-16     	      38	  30561462 ns/op	 7579674 B/op	  181446 allocs/op
BenchmarkC6_Find_Full-16       	      15	  70822510 ns/op	17546298 B/op	  420019 allocs/op
BenchmarkD_GetSubset-16        	     159	   7448360 ns/op	 2068287 B/op	   42084 allocs/op
BenchmarkE_CacheLookup-16      	     376	   3143373 ns/op	       0 B/op	       0 allocs/op
BenchmarkF_CacheInit-16        	     223	   5185070 ns/op	  925247 B/op	   17713 allocs/op

Run benchmarks with:

go test -bench=. -benchmem

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

type Client[T any] struct {
	Cache map[int]*[12][31][24]struct{}
	Opts  Options
}

func Init

func Init[T any](opts Options) (client *Client[T], err error)

func (*Client[T]) Delete

func (c *Client[T]) Delete(from time.Time, to time.Time) error

func (*Client[T]) Find

func (c *Client[T]) Find(from time.Time, to time.Time, fn func(t time.Time, data T) bool) error

func (*Client[T]) Get

func (c *Client[T]) Get(from time.Time, to time.Time) ([]*T, error)

func (*Client[T]) Store

func (c *Client[T]) Store(date time.Time, data T) error

type Entry

type Entry[T any] struct {
	Time time.Time
	Data T
}

type Options

type Options struct {
	Debug       bool
	PrintMemory bool
	Path        string
}

Jump to

Keyboard shortcuts

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