all repos

clerk @ 4ba8053f16f04927c6459c7b7ee1bddc49586d4e

missing tooling for ledger/hledger
1 files changed, 10 insertions(+), 7 deletions(-)
journal: loader: use ring buffer for cache
Author: Oleksandr Smirnov olexsmir@gmail.com
Committed at: 2026-09-30 17:11:47 +0300
Authored at: 2026-09-26 21:03:12 +0300
Change ID: vuuoxqvvomkoqvyuqrqmwxrnykrwoqst
Parent: 23d0a0d
M journal/loader.go
···
        2
        2
         

      
        3
        3
         import (

      
        4
        4
         	"bytes"

      
        
        5
        +	"container/ring"

      
        5
        6
         	"fmt"

      
        6
        7
         	"io/fs"

      
        7
        8
         	"os"

      ···
        66
        67
         	mu           sync.RWMutex

      
        67
        68
         	contentCache map[string][]byte // canonical path: normalised content

      
        68
        69
         	parseCache   map[parseKey]parseEntry

      
        
        70
        +	parseRing    *ring.Ring // holds parseCache keys oldest first, so overflow evicts the east recently stored one.

      
        69
        71
         

      
        70
        72
         	// ContentProvider, when set, is consulted before any disk read. It returns

      
        71
        73
         	// the file's authoritative content and ok=true, or ok=false to fall back to

      ···
        77
        79
         	return &Loader{

      
        78
        80
         		contentCache: make(map[string][]byte),

      
        79
        81
         		parseCache:   make(map[parseKey]parseEntry),

      
        
        82
        +		parseRing:    ring.New(parseCacheMax),

      
        80
        83
         	}

      
        81
        84
         }

      
        82
        85
         

      ···
        338
        341
         

      
        339
        342
         func (l *Loader) parseStore(key parseKey, entry parseEntry) {

      
        340
        343
         	l.mu.Lock()

      
        341
        
        -	l.parseCache[key] = entry

      
        342
        
        -	if len(l.parseCache) > parseCacheMax {

      
        343
        
        -		for k := range l.parseCache {

      
        344
        
        -			delete(l.parseCache, k)

      
        345
        
        -			break

      
        346
        
        -		}

      
        
        344
        +	defer l.mu.Unlock()

      
        
        345
        +	old, full := l.parseRing.Value.(parseKey)

      
        
        346
        +	l.parseRing.Value = key

      
        
        347
        +	l.parseRing = l.parseRing.Next()

      
        
        348
        +	if full {

      
        
        349
        +		delete(l.parseCache, old)

      
        347
        350
         	}

      
        348
        
        -	l.mu.Unlock()

      
        
        351
        +	l.parseCache[key] = entry

      
        349
        352
         }