From 6e123054e2ded82f04890a64eb896406f0b3d51c Mon Sep 17 00:00:00 2001 From: Simon Martens Date: Sat, 28 Dec 2024 12:34:28 +0100 Subject: [PATCH] Cache for file embedding + unsafe mebedding --- functions/embedding.go | 51 +++++++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/functions/embedding.go b/functions/embedding.go index dd0a192..c7eb90b 100644 --- a/functions/embedding.go +++ b/functions/embedding.go @@ -4,22 +4,53 @@ import ( "html/template" "io" "io/fs" + "sync" ) -// TODO: this needs to be cached, FS reads are expensive +var embed_cache sync.Map + +// INFO: We initialize the cache in both functions, which is only valid if both of these get +// called in the same context, eg. when creating a template engine. func EmbedSafe(fs fs.FS) func(string) template.HTML { + embed_cache.Clear() return func(path string) template.HTML { - f, err := fs.Open(path) + val, err := getFileData(fs, path) if err != nil { - return "" + return template.HTML("") } - defer f.Close() - data, err := io.ReadAll(f) - if err != nil { - return "" - } - - return template.HTML(data) + return template.HTML(val) } } + +func EmbedUnsafe(fs fs.FS) func(string) string { + embed_cache.Clear() + return func(path string) string { + val, err := getFileData(fs, path) + if err != nil { + return "" + } + + return string(val) + } +} + +func getFileData(fs fs.FS, path string) ([]byte, error) { + if val, ok := embed_cache.Load(path); ok { + return val.([]byte), nil + } + + f, err := fs.Open(path) + if err != nil { + return nil, err + } + defer f.Close() + + data, err := io.ReadAll(f) + if err != nil { + return nil, err + } + + embed_cache.Store(path, data) + return data, nil +}