diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2026-01-21 15:21:05 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2026-01-22 11:23:54 +0000 |
| commit | c1de3220482e317729f83e4e7d32fc30d46ec1e7 (patch) | |
| tree | 6f23f38b17aa1ac9fd0f3cacc41658165095da2e /pkg/codesearch | |
| parent | 084b5c918c53c4e2eeb51664f3d403095f59f25d (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.go | 8 | ||||
| -rw-r--r-- | pkg/codesearch/database.go | 108 |
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) } } } |
