aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/codesearch
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2026-01-21 15:21:05 +0100
committerDmitry Vyukov <dvyukov@google.com>2026-01-22 11:23:54 +0000
commitc1de3220482e317729f83e4e7d32fc30d46ec1e7 (patch)
tree6f23f38b17aa1ac9fd0f3cacc41658165095da2e /pkg/codesearch
parent084b5c918c53c4e2eeb51664f3d403095f59f25d (diff)
pkg/codesearch: reduce memory consumption more
Use uint8 enums instead of strings to store entity/reference kind. String is 16 bytes and is slower to work with.
Diffstat (limited to 'pkg/codesearch')
-rw-r--r--pkg/codesearch/codesearch.go8
-rw-r--r--pkg/codesearch/database.go108
2 files changed, 104 insertions, 12 deletions
diff --git a/pkg/codesearch/codesearch.go b/pkg/codesearch/codesearch.go
index 051cad3c5..08018a403 100644
--- a/pkg/codesearch/codesearch.go
+++ b/pkg/codesearch/codesearch.go
@@ -206,7 +206,7 @@ func (index *Index) FileIndex(file string) ([]Entity, error) {
for _, def := range index.db.Definitions {
if def.Body.File == file {
entities = append(entities, Entity{
- Kind: def.Kind,
+ Kind: def.Kind.String(),
Name: def.Name,
})
}
@@ -243,7 +243,7 @@ func (index *Index) definitionSource(contextFile, name string, comment, includeL
}
return &EntityInfo{
File: def.Body.File,
- Kind: def.Kind,
+ Kind: def.Kind.String(),
Body: src,
}, nil
}
@@ -299,9 +299,9 @@ func (index *Index) FindReferences(contextFile, name, srcPrefix string, contextL
}
}
results = append(results, ReferenceInfo{
- ReferencingEntityKind: def.Kind,
+ ReferencingEntityKind: def.Kind.String(),
ReferencingEntityName: def.Name,
- ReferenceKind: ref.Kind,
+ ReferenceKind: ref.Kind.String(),
SourceFile: def.Body.File,
SourceLine: ref.Line,
SourceSnippet: snippet,
diff --git a/pkg/codesearch/database.go b/pkg/codesearch/database.go
index dbea6632c..eed853aaf 100644
--- a/pkg/codesearch/database.go
+++ b/pkg/codesearch/database.go
@@ -4,6 +4,7 @@
package codesearch
import (
+ "bytes"
"fmt"
"maps"
"slices"
@@ -23,7 +24,7 @@ type Database struct {
}
type Definition struct {
- Kind string `json:"kind,omitempty"`
+ Kind EntityKind `json:"kind,omitempty"`
Name string `json:"name,omitempty"`
Type string `json:"type,omitempty"`
IsStatic bool `json:"is_static,omitempty"`
@@ -33,10 +34,10 @@ type Definition struct {
}
type Reference struct {
- Kind string `json:"kind,omitempty"`
- EntityKind string `json:"entity_kind,omitempty"`
- Name string `json:"name,omitempty"`
- Line int `json:"line,omitempty"`
+ Kind RefKind `json:"kind,omitempty"`
+ EntityKind EntityKind `json:"entity_kind,omitempty"`
+ Name string `json:"name,omitempty"`
+ Line int `json:"line,omitempty"`
}
type LineRange struct {
@@ -45,6 +46,100 @@ type LineRange struct {
EndLine int `json:"end_line,omitempty"`
}
+type EntityKind uint8
+
+const (
+ entityKindInvalid EntityKind = iota
+ EntityKindFunction
+ EntityKindStruct
+ EntityKindUnion
+ EntityKindVariable
+ EntityKindMacro
+ EntityKindEnum
+ EntityKindTypedef
+ entityKindLast
+)
+
+var entityKindNames = [...]string{
+ EntityKindFunction: "function",
+ EntityKindStruct: "struct",
+ EntityKindUnion: "union",
+ EntityKindVariable: "variable",
+ EntityKindMacro: "macro",
+ EntityKindEnum: "enum",
+ EntityKindTypedef: "typedef",
+}
+
+var entityKindBytes = func() [entityKindLast][]byte {
+ var ret [entityKindLast][]byte
+ for k, v := range entityKindNames {
+ ret[k] = []byte("\"" + v + "\"")
+ }
+ return ret
+}()
+
+func (v *EntityKind) String() string {
+ return entityKindNames[*v]
+}
+
+func (v *EntityKind) MarshalJSON() ([]byte, error) {
+ return entityKindBytes[*v], nil
+}
+
+func (v *EntityKind) UnmarshalJSON(data []byte) error {
+ *v = entityKindInvalid
+ for k, val := range entityKindBytes {
+ if bytes.Equal(data, val) {
+ *v = EntityKind(k)
+ break
+ }
+ }
+ return nil
+}
+
+type RefKind uint8
+
+const (
+ refKindInvalid RefKind = iota
+ RefKindUses
+ RefKindCall
+ RefKindTakesAddr
+ refKindLast
+)
+
+var refKindNames = [...]string{
+ RefKindUses: "uses",
+ RefKindCall: "calls",
+ RefKindTakesAddr: "takes-address-of",
+}
+
+var refKindBytes = func() [refKindLast][]byte {
+ var ret [refKindLast][]byte
+ for k, v := range refKindNames {
+ ret[k] = []byte("\"" + v + "\"")
+ }
+ return ret
+}()
+
+func (v *RefKind) String() string {
+ return refKindNames[*v]
+}
+
+func (v *RefKind) MarshalJSON() ([]byte, error) {
+ return refKindBytes[*v], nil
+}
+
+func (v *RefKind) UnmarshalJSON(data []byte) error {
+ *v = refKindInvalid
+ for k, val := range refKindBytes {
+ if bytes.Equal(data, val) {
+ *v = RefKind(k)
+ break
+ }
+ }
+ return nil
+}
+
// DatabaseFormatHash contains a hash uniquely identifying format of the database.
// In covers both structure and semantics of the data, and is supposed to be used
// for caching of the database files.
@@ -76,15 +171,12 @@ func (db *Database) Merge(other *Database, v *clangtool.Verifier) {
if def.Comment.File != "" {
v.LineRange(def.Comment.File, def.Comment.StartLine, def.Comment.EndLine)
}
- db.intern(&def.Kind)
db.intern(&def.Name)
db.intern(&def.Type)
db.intern(&def.Body.File)
db.intern(&def.Comment.File)
for _, ref := range def.Refs {
- db.intern(&ref.Kind)
db.intern(&ref.Name)
- db.intern(&ref.EntityKind)
}
}
}