github.com/Kintar/etxt@v0.0.0-20221224033739-2fc69f000137/ecache/cache_entry.go (about) 1 package ecache 2 3 import "sync/atomic" 4 import _ "unsafe" 5 6 //go:linkname systemMonoNanoTime runtime.nanotime 7 8 //go:noescape 9 func systemMonoNanoTime() int64 10 11 // A cached mask with additional information to estimate how 12 // much the entry is being used. Cache implementers may use this 13 // type to make their life easier. 14 type CachedMaskEntry struct { 15 Mask GlyphMask // Read-only. 16 ByteSize uint32 // Read-only. 17 CreationInstant uint32 // see CacheEntryInstant. Read-only. 18 // Won't be consistent after reboots. I 19 // don't know why would anyone try to 20 // save a cache, but I've seen worse. 21 accessCount uint32 // number of times the entry has been accessed 22 } 23 24 // Must be called after accessing an entry in order to keep the 25 // Hotness() heuristic making sense. Concurrent-safe. 26 func (self *CachedMaskEntry) IncreaseAccessCount() { 27 atomic.AddUint32(&self.accessCount, 1) 28 } 29 30 // A measure of "bytes accessed per time". Coldest entries 31 // (smallest values) are candidates for eviction. Concurrent-safe. 32 func (self *CachedMaskEntry) Hotness(instant uint32) uint32 { 33 const ConstEvictionCost = 1000 // additional threshold and pad 34 bytesHit := self.ByteSize * atomic.LoadUint32(&self.accessCount) 35 elapsed := instant - self.CreationInstant 36 if elapsed == 0 { 37 elapsed = 1 38 } 39 return (ConstEvictionCost + bytesHit) / elapsed 40 } 41 42 // A time instant related to the system's monotonic nano time, but with 43 // some arbitrary downscaling applied (close to converting nanoseconds 44 // to hundredth's of seconds). 45 func CacheEntryInstant() uint32 { 46 return uint32(systemMonoNanoTime() >> 27) 47 } 48 49 // Creates a new cached mask entry for the given GlyphMask. 50 func NewCachedMaskEntry(mask GlyphMask) (*CachedMaskEntry, uint32) { 51 instant := CacheEntryInstant() 52 return &CachedMaskEntry{ 53 Mask: mask, 54 ByteSize: GlyphMaskByteSize(mask), 55 CreationInstant: instant, 56 accessCount: 1, 57 }, instant 58 }