Documentation
¶
Overview ¶
Package segcache provides a segment-aligned disk cache for Usenet file data. Unlike the VFS cache which operates on 8MB chunks, the segment cache uses Usenet message IDs as cache keys (each ~750KB), matching the actual download granularity and enabling cross-file deduplication.
Index ¶
- type Config
- type Manager
- type ManagerConfig
- type SegmentCache
- func (c *SegmentCache) Cleanup()
- func (c *SegmentCache) Evict()
- func (c *SegmentCache) Get(messageID string) ([]byte, bool)
- func (c *SegmentCache) Has(messageID string) bool
- func (c *SegmentCache) ItemCount() int
- func (c *SegmentCache) LoadCatalog()
- func (c *SegmentCache) Put(messageID string, data []byte) error
- func (c *SegmentCache) SaveCatalog() error
- func (c *SegmentCache) TotalSize() int64
- type Source
- type StatsSnapshot
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager owns a SegmentCache and runs background maintenance goroutines for cleanup and catalog flushing.
func NewManager ¶
func NewManager(cfg ManagerConfig, logger *slog.Logger) (*Manager, error)
NewManager creates a Manager and loads any existing on-disk catalog.
func (*Manager) Cache ¶
func (m *Manager) Cache() *SegmentCache
Cache returns the underlying SegmentCache for use as a usenet.SegmentStore.
func (*Manager) GetStats ¶
func (m *Manager) GetStats() StatsSnapshot
GetStats returns a point-in-time snapshot of cache statistics.
type ManagerConfig ¶
type ManagerConfig struct {
Enabled bool
CachePath string
MaxSizeBytes int64
ExpiryDuration time.Duration
}
ManagerConfig holds the full segment-cache configuration.
func DefaultManagerConfig ¶
func DefaultManagerConfig() ManagerConfig
DefaultManagerConfig returns a ManagerConfig with sensible defaults.
func (ManagerConfig) WithDefaults ¶
func (cfg ManagerConfig) WithDefaults() ManagerConfig
WithDefaults returns a copy with zero values replaced by defaults.
type SegmentCache ¶
type SegmentCache struct {
// contains filtered or unexported fields
}
SegmentCache stores decoded segment bytes on disk, keyed by Usenet message ID. The in-memory catalog (map[messageID]*cacheEntry) enables O(1) Has() without disk I/O. Actual data is stored in per-segment files named by sha256(messageID).
func NewSegmentCache ¶
func NewSegmentCache(cfg Config, logger *slog.Logger) (*SegmentCache, error)
NewSegmentCache creates a new segment cache. It does NOT load any existing catalog; call LoadCatalog to hydrate from disk. Manager.Start runs that load in a background goroutine so the per-segment stat loop does not block boot.
func (*SegmentCache) Cleanup ¶
func (c *SegmentCache) Cleanup()
Cleanup removes entries that have not been accessed within ExpiryDuration.
func (*SegmentCache) Evict ¶
func (c *SegmentCache) Evict()
Evict removes the oldest entries (by LastAccess) until total size is within MaxSizeBytes.
func (*SegmentCache) Get ¶
func (c *SegmentCache) Get(messageID string) ([]byte, bool)
Get returns the decoded segment bytes. Returns (nil, false) on miss.
func (*SegmentCache) Has ¶
func (c *SegmentCache) Has(messageID string) bool
Has reports whether the segment is present in the cache (no disk I/O).
func (*SegmentCache) ItemCount ¶
func (c *SegmentCache) ItemCount() int
ItemCount returns the number of cached segments.
func (*SegmentCache) LoadCatalog ¶ added in v0.3.0
func (c *SegmentCache) LoadCatalog()
LoadCatalog hydrates the in-memory catalog from catalog.json on disk, statting each .seg file and dropping entries whose data is missing. Put is gated off (see the loading flag) for the duration, so the load can assign the map wholesale without racing a concurrent writer. Sets the gate on entry and clears it on exit.
func (*SegmentCache) Put ¶
func (c *SegmentCache) Put(messageID string, data []byte) error
Put stores segment bytes atomically (temp-write + rename).
func (*SegmentCache) SaveCatalog ¶
func (c *SegmentCache) SaveCatalog() error
SaveCatalog flushes the in-memory catalog to disk (catalog.json) atomically. It is a no-op when the catalog has not changed since the last flush.
func (*SegmentCache) TotalSize ¶
func (c *SegmentCache) TotalSize() int64
TotalSize returns the total bytes occupied by cached segments.
type Source ¶ added in v0.3.0
type Source struct {
// contains filtered or unexported fields
}
Source is a thin wrapper around an atomic Manager pointer that resolves the active SegmentStore on demand. It is the single value threaded through the application instead of passing raw atomic pointers and getter closures.
func NewSource ¶ added in v0.3.0
func NewSource(getCfg config.ConfigGetter) *Source
NewSource creates a Source. getCfg must not be nil.
func (*Source) Manager ¶ added in v0.3.0
Manager returns the current manager for stats access. May be nil.
func (*Source) Store ¶ added in v0.3.0
func (s *Source) Store() usenet.SegmentStore
Store resolves the current SegmentStore. Returns nil if the cache is disabled in config or no manager has been loaded yet. Call once at file-open time and pass the result to UsenetReader.