1
0
forked from rosa/hakurei

internal/pkg: move IR primitives out of cache

These are memory management and caching primitives. Having them as part of Cache is cumbersome and requires a temporary directory that is never used. This change isolates them from Cache to enable independent use.

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
2026-04-17 00:50:17 +09:00
parent 823575acac
commit 0ff7ab915b
2 changed files with 62 additions and 41 deletions

View File

@@ -559,10 +559,8 @@ type Cache struct {
// Immutable job count, when applicable.
jobs int
// Artifact to [unique.Handle] of identifier cache.
artifact sync.Map
// Identifier free list, must not be accessed directly.
identPool sync.Pool
// Must not be exposed directly.
irCache
// Synchronises access to dirChecksum.
checksumMu sync.RWMutex
@@ -594,24 +592,24 @@ type Cache struct {
type extIdent [wordSize + len(ID{})]byte
// getIdentBuf returns the address of an extIdent for Ident.
func (c *Cache) getIdentBuf() *extIdent { return c.identPool.Get().(*extIdent) }
func (ic *irCache) getIdentBuf() *extIdent { return ic.identPool.Get().(*extIdent) }
// putIdentBuf adds buf to identPool.
func (c *Cache) putIdentBuf(buf *extIdent) { c.identPool.Put(buf) }
func (ic *irCache) putIdentBuf(buf *extIdent) { ic.identPool.Put(buf) }
// storeIdent adds an [Artifact] to the artifact cache.
func (c *Cache) storeIdent(a Artifact, buf *extIdent) unique.Handle[ID] {
func (ic *irCache) storeIdent(a Artifact, buf *extIdent) unique.Handle[ID] {
idu := unique.Make(ID(buf[wordSize:]))
c.artifact.Store(a, idu)
ic.artifact.Store(a, idu)
return idu
}
// Ident returns the identifier of an [Artifact].
func (c *Cache) Ident(a Artifact) unique.Handle[ID] {
buf, idu := c.unsafeIdent(a, false)
func (ic *irCache) Ident(a Artifact) unique.Handle[ID] {
buf, idu := ic.unsafeIdent(a, false)
if buf != nil {
idu = c.storeIdent(a, buf)
c.putIdentBuf(buf)
idu = ic.storeIdent(a, buf)
ic.putIdentBuf(buf)
}
return idu
}
@@ -619,17 +617,17 @@ func (c *Cache) Ident(a Artifact) unique.Handle[ID] {
// unsafeIdent implements Ident but returns the underlying buffer for a newly
// computed identifier. Callers must return this buffer to identPool. encodeKind
// is only a hint, kind may still be encoded in the buffer.
func (c *Cache) unsafeIdent(a Artifact, encodeKind bool) (
func (ic *irCache) unsafeIdent(a Artifact, encodeKind bool) (
buf *extIdent,
idu unique.Handle[ID],
) {
if id, ok := c.artifact.Load(a); ok {
if id, ok := ic.artifact.Load(a); ok {
idu = id.(unique.Handle[ID])
return
}
if ki, ok := a.(KnownIdent); ok {
buf = c.getIdentBuf()
buf = ic.getIdentBuf()
if encodeKind {
binary.LittleEndian.PutUint64(buf[:], uint64(a.Kind()))
}
@@ -637,9 +635,9 @@ func (c *Cache) unsafeIdent(a Artifact, encodeKind bool) (
return
}
buf = c.getIdentBuf()
buf = ic.getIdentBuf()
h := sha512.New384()
if err := c.Encode(h, a); err != nil {
if err := ic.Encode(h, a); err != nil {
// unreachable
panic(err)
}
@@ -1876,7 +1874,7 @@ func open(
msg: msg,
base: base,
identPool: sync.Pool{New: func() any { return new(extIdent) }},
irCache: zeroIRCache(),
ident: make(map[unique.Handle[ID]]unique.Handle[Checksum]),
identErr: make(map[unique.Handle[ID]]error),