Alex Meijer vor 1 Woche
Ursprung
Commit
486b3e3a74
2 geänderte Dateien mit 66 neuen und 1 gelöschten Zeilen
  1. 5 1
      core/pkg/opencost/opencost_codecs.go
  2. 61 0
      core/pkg/opencost/opencost_codecs_test.go

+ 5 - 1
core/pkg/opencost/opencost_codecs.go

@@ -23,6 +23,7 @@ import (
 	"unsafe"
 
 	util "github.com/opencost/opencost/core/pkg/util"
+	"github.com/opencost/opencost/core/pkg/util/stringutil"
 )
 
 const (
@@ -541,7 +542,10 @@ func (fstr *FileStringTableReader) At(index int) string {
 
 	// cast the allocated bytes to a string in-place, as we
 	// were the ones that allocated the bytes
-	return unsafe.String(unsafe.SliceData(b), len(b))
+	pinned := unsafe.String(unsafe.SliceData(b), len(b))
+	return stringutil.BankFunc(pinned, func() string {
+		return string(b)
+	})
 }
 
 // Len returns the total number of strings loaded in the string table.

+ 61 - 0
core/pkg/opencost/opencost_codecs_test.go

@@ -3,8 +3,11 @@ package opencost
 import (
 	"bytes"
 	"io"
+	"os"
 	"testing"
 	"time"
+
+	"github.com/opencost/opencost/core/pkg/util/stringutil"
 )
 
 type UnmarshalFunc func(BingenUnmarshalable, []byte) error
@@ -828,3 +831,61 @@ func TestOpencostBingenFileStringTableEnabledWithReader(t *testing.T) {
 
 	RunAllOpencostBingenCodecTests(t, UnmarshalBingenReader)
 }
+
+type passthroughStringBank struct{}
+
+func (b *passthroughStringBank) LoadOrStore(key, value string) (string, bool) {
+	return value, false
+}
+
+func (b *passthroughStringBank) LoadOrStoreFunc(key string, f func() string) (string, bool) {
+	return f(), false
+}
+
+func (b *passthroughStringBank) Clear() {}
+
+type markerStringBank struct{}
+
+func (b *markerStringBank) LoadOrStore(key, value string) (string, bool) {
+	return "MARKER:" + value, false
+}
+
+func (b *markerStringBank) LoadOrStoreFunc(key string, f func() string) (string, bool) {
+	return "MARKER:" + f(), false
+}
+
+func (b *markerStringBank) Clear() {}
+
+func TestFileStringTableReaderAt_UsesStringBank(t *testing.T) {
+	orig := stringutil.GetStringBank()
+	stringutil.UpdateStringBank(&passthroughStringBank{})
+	defer stringutil.UpdateStringBank(orig)
+
+	tmp, err := os.CreateTemp("", "opencost-bgst-test-*")
+	if err != nil {
+		t.Fatalf("create temp file: %v", err)
+	}
+	defer os.Remove(tmp.Name())
+	defer tmp.Close()
+
+	if _, err := tmp.Write([]byte("hello")); err != nil {
+		t.Fatalf("write temp data: %v", err)
+	}
+
+	reader := &FileStringTableReader{
+		f: tmp,
+		refs: []fileStringRef{
+			{off: 0, length: 5},
+		},
+	}
+	defer reader.Close()
+
+	if got := reader.At(0); got != "hello" {
+		t.Fatalf("baseline string mismatch, got %q", got)
+	}
+
+	stringutil.UpdateStringBank(&markerStringBank{})
+	if got := reader.At(0); got != "MARKER:hello" {
+		t.Fatalf("expected banked marker value, got %q", got)
+	}
+}