framecache

package
v0.10.0 Latest Latest
Warning

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

Go to latest
Published: Jun 4, 2026 License: MIT Imports: 1 Imported by: 0

Documentation

Overview

Package framecache provides decoded-frame cache implementations for seekable readers.

A Cache used by seekable.Reader need not be safe for concurrent use; the reader serializes access.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Cache

type Cache interface {
	// Get returns the frame for frameID, if present. The returned slice must not
	// be modified and may alias data passed to Put.
	Get(frameID int64) ([]byte, bool)

	// Put stores data for frameID, replacing any existing value. The caller must
	// not modify data after Put returns.
	Put(frameID int64, data []byte)

	// Clear removes all cached frames.
	Clear()
}

Cache stores decoded frames by seek-table frame ID.

Example (CustomReplacementPolicy)
package main

import (
	"fmt"

	"github.com/SaveTheRbtz/zstd-seekable-format-go/pkg/framecache"
)

type clockCache struct {
	maxFrames int
	hand      int
	items     map[int64]int
	slots     []clockSlot
}

type clockSlot struct {
	frameID int64
	data    []byte
	used    bool
}

var _ framecache.Cache = (*clockCache)(nil)

func newClockCache(maxFrames int) *clockCache {
	return &clockCache{
		maxFrames: maxFrames,
		items:     make(map[int64]int),
	}
}

func (c *clockCache) Get(frameID int64) ([]byte, bool) {
	index, ok := c.items[frameID]
	if !ok {
		return nil, false
	}
	c.slots[index].used = true
	return c.slots[index].data, true
}

func (c *clockCache) Put(frameID int64, data []byte) {
	if c.maxFrames <= 0 {
		return
	}

	if index, ok := c.items[frameID]; ok {
		c.slots[index].data = data
		c.slots[index].used = true
		return
	}

	if len(c.slots) < c.maxFrames {
		c.items[frameID] = len(c.slots)
		c.slots = append(c.slots, clockSlot{frameID: frameID, data: data})
		return
	}

	for {
		slot := &c.slots[c.hand]
		if slot.used {
			slot.used = false
			c.advance()
			continue
		}

		delete(c.items, slot.frameID)
		*slot = clockSlot{frameID: frameID, data: data}
		c.items[frameID] = c.hand
		c.advance()
		return
	}
}

func (c *clockCache) Clear() {
	c.hand = 0
	c.items = make(map[int64]int)
	c.slots = nil
}

func (c *clockCache) advance() {
	c.hand = (c.hand + 1) % len(c.slots)
}

func main() {
	cache := newClockCache(2)

	first := int64(1)
	second := int64(2)
	third := int64(3)

	cache.Put(first, []byte("first"))
	cache.Put(second, []byte("second"))

	// Touch first so the clock cache gives it a second chance and evicts second.
	_, _ = cache.Get(first)
	cache.Put(third, []byte("third"))

	printFrame("first", cache, first)
	printFrame("second", cache, second)
	printFrame("third", cache, third)

}

func printFrame(label string, cache framecache.Cache, frameID int64) {
	data, ok := cache.Get(frameID)
	if !ok {
		fmt.Println(label + ": miss")
		return
	}
	fmt.Println(label + ": " + string(data))
}
Output:
first: first
second: miss
third: third

type FIFO

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

FIFO is a decoded-frame cache using first-in, first-out replacement.

Calls to Get do not affect eviction order.

func NewFIFO

func NewFIFO(limits Limits) *FIFO

NewFIFO returns a FIFO cache with the provided limits.

func (*FIFO) Clear

func (c *FIFO) Clear()

Clear removes all cached frames.

func (*FIFO) Get

func (c *FIFO) Get(frameID int64) ([]byte, bool)

Get returns the frame stored for frameID, if any.

func (*FIFO) Put

func (c *FIFO) Put(frameID int64, data []byte)

Put stores data for frameID as a new FIFO insertion, replacing any existing entry.

type LRU

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

LRU is a decoded-frame cache that evicts the least recently used frame.

Put and successful Get calls mark frames most recently used.

func NewLRU

func NewLRU(limits Limits) *LRU

NewLRU returns an LRU cache with the provided limits.

func (*LRU) Clear

func (c *LRU) Clear()

Clear removes all cached frames.

func (*LRU) Get

func (c *LRU) Get(frameID int64) ([]byte, bool)

Get returns the frame stored for frameID, if any. On a hit, Get marks the frame most recently used.

func (*LRU) Put

func (c *LRU) Put(frameID int64, data []byte)

Put stores data for frameID, replacing any existing frame and marking it most recently used.

type Limits

type Limits struct {
	// MaxFrames caps the number of stored frames. Values <= 0 disable storage.
	MaxFrames int

	// MaxBytes caps decoded bytes stored in the cache. A zero value applies no
	// byte limit. If data passed to Put is larger than a positive MaxBytes, Put
	// does not store it and removes any existing entry for that frame ID.
	MaxBytes uint64
}

Limits configures cache capacity.

type Sieve

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

Sieve is a decoded-frame cache using the SIEVE-k replacement policy.

Hits and updates increment a per-entry counter, capped at 16. During eviction, entries with positive counters are decremented and kept; the first entry with a zero counter is evicted.

func NewSieve

func NewSieve(limits Limits) *Sieve

NewSieve returns a Sieve cache with the provided limits.

func (*Sieve) Clear

func (c *Sieve) Clear()

Clear removes all cached frames.

func (*Sieve) Get

func (c *Sieve) Get(frameID int64) ([]byte, bool)

Get returns the frame stored for frameID, if any. On a hit, Get increments the frame's counter.

func (*Sieve) Put

func (c *Sieve) Put(frameID int64, data []byte)

Put stores data for frameID, replacing any existing entry.

Jump to

Keyboard shortcuts

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