tiempo

package module
v0.0.0-...-22ea668 Latest Latest
Warning

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

Go to latest
Published: Dec 4, 2024 License: MIT Imports: 13 Imported by: 0

README

Tiempo

Overview

Tiempo (or 'Time' in English) is a simple, fast and lightweight time-series database designed to handle efficient write and query operations. It uses a Write-Ahead Log (WAL) for data durability and periodic compaction to optimize storage. It provides basic functionality to store time-series data, query it by time range, and delete or compact data as needed.

Note that Tiempo is not intended for production use. If you're looking for a mature time-series database or a wrapper, take a look at InfluxDB and their official wrapper, Influx Go Client, or the alternative Prometheus, or others. I just coded Tiempo on my Sunday morning XD.

However, Tiempo is fully functional for your hobby projects, as it offers basic features for a time-series database.

Key Features

  • Write-Ahead Log (WAL): Ensures data durability by appending records to a log.
  • Snappy Compression: Compresses data to save storage space.
  • Compaction: Periodically compacts the database to optimize storage.
  • Querying: Allows querying by timestamp range with filtering support.
  • Metrics: Provides database metrics such as write counts, read counts, and storage size.
  • Soft and Hard Deletion: Supports soft (marking for deletion) and hard (removing from storage) deletions.

Quick Start

Creating a Database

To create a new Tiempo instance, use the NewTiempoDB function. You can specify the path to the WAL file and optional configuration options like the maximum WAL size or compaction period.

import (
	"log"
	"github.com/ezrantn/tiempo"
)

func main() {
	db, err := tiempo.NewTiempoDB("/path/to/walfile")
	if err != nil {
		log.Fatalf("Failed to create database: %v", err)
	}
	defer db.Close()
}

You can also configure the database with options like maximum WAL size and compaction period:

db, err := tiempo.NewTiempoDB(
	"/path/to/walfile",
	tiempo.WithMaxWALSize(200 * 1024 * 1024),
	tiempo.WithCompactionPeriod(30 * time.Minute),
)
Writing Data

To write data to the database, use the Write method. A Record consists of a timestamp, value, and optional tags.

record := tiempo.Record{
	Timestamp: time.Now().Unix(),
	Value:     123.45,
	Tags:      map[string]string{"sensor": "temperature", "location": "office"},
}

err := db.Write(record)
if err != nil {
	log.Fatalf("Failed to write record: %v", err)
}
Querying Data

To query data, use the Query method. You can specify a time range (start and end) and apply filters. The method returns a slice of records that match the query.

start := time.Now().Add(-1 * time.Hour).Unix()
end := time.Now().Unix()

results, err := db.Query(start, end, func(r tiempo.Record) bool {
	return r.Tags["sensor"] == "temperature"
})
if err != nil {
	log.Fatalf("Failed to query records: %v", err)
}

for _, record := range results {
	fmt.Printf("Timestamp: %d, Value: %f, Tags: %v\n", record.Timestamp, record.Value, record.Tags)
}
Deleting Data

You can delete data by specifying a time range and whether to perform a hard or soft delete.

start := time.Now().Add(-1 * time.Hour).Unix()
end := time.Now().Unix()

// Soft delete records in the given time range
err := db.Delete(start, end, false)
if err != nil {
	log.Fatalf("Failed to delete records: %v", err)
}

// Hard delete records in the given time range
err = db.Delete(start, end, true)
if err != nil {
	log.Fatalf("Failed to hard delete records: %v", err)
}
Compaction

Tiempo automatically performs compaction periodically to optimize storage usage. You can also trigger a manual compaction:

// Trigger a manual compaction
err := db.Compact()
if err != nil {
	log.Fatalf("Failed to compact database: %v", err)
}

Compaction helps keep the database efficient by removing deleted records and reducing the overall storage footprint.

Metrics

Tiempo provides metrics about database usage, including total writes, queries, compactions, storage, and write/query latency.

You can retrieve these metrics using the GetMetrics method:

metrics := db.GetMetrics()
fmt.Printf("Total Writes: %d, Total Queries: %d\n", metrics.WritesTotal, metrics.QueriesTotal)

This can help you monitor the health and performance of the database.

Closing the Database

To safely close the database and ensure all data is flushed, use the Close method:

err := db.Close()
if err != nil {
	log.Fatalf("Failed to close database: %v", err)
}

Installation

You can install Tiempo by running:

go get github.com/ezrantn/tiempo

License

This tool is open-source and available under the MIT License.

Contributions

Contributions are welcome! Please feel free to submit a pull request.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type DatabaseOption

type DatabaseOption func(*TiempoDB)

func WithCompactionPeriod

func WithCompactionPeriod(period time.Duration) DatabaseOption

func WithMaxWALSize

func WithMaxWALSize(maxSize int64) DatabaseOption

type Metrics

type Metrics struct {
	WritesTotal     uint64
	WriteErrorTotal uint64
	WriteLatencyNs  uint64

	QueriesTotal    uint64
	QueryErrorTotal uint64
	QueryLatencyNs  uint64

	CompactionsTotal     uint64
	LastCompactionTimeNs int64

	RecordsStored   uint64
	CurrentStorageB uint64
	PeakStorageB    uint64
}

type Record

type Record struct {
	Timestamp int64             `json:"timestamp"`
	Value     float64           `json:"value"`
	Tags      map[string]string `json:"tags"`
	DeletedAt int64             `json:"deleted_at:omitempty"`
}

Record represents a single time-series data point.

type TiempoDB

type TiempoDB struct {
	// contains filtered or unexported fields
}

func NewTiempoDB

func NewTiempoDB(walPath string, opts ...DatabaseOption) (*TiempoDB, error)

func (*TiempoDB) Close

func (db *TiempoDB) Close() error

func (*TiempoDB) Compact

func (db *TiempoDB) Compact() error

Compact performs database compaction

func (*TiempoDB) Delete

func (db *TiempoDB) Delete(start, end int64, hardDelete bool) error

Delete removes records within the specified time range

func (*TiempoDB) GetMetrics

func (db *TiempoDB) GetMetrics() Metrics

GetMetrics returns a snapshot of current database metrics

func (*TiempoDB) Query

func (db *TiempoDB) Query(start, end int64, filters ...func(Record) bool) ([]Record, error)

func (*TiempoDB) Recover

func (db *TiempoDB) Recover() error

Recover replays the WAL file to restore the database state

func (*TiempoDB) Write

func (db *TiempoDB) Write(record Record) error

Write appends a new record to the database

Jump to

Keyboard shortcuts

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