Implemented string interning for static data
This commit is contained in:
parent
178d543f8f
commit
09ec8d8446
4 changed files with 117 additions and 39 deletions
45
src/build/data/Data.go
Normal file
45
src/build/data/Data.go
Normal file
|
@ -0,0 +1,45 @@
|
|||
package data
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// Data saves slices of bytes referenced by labels.
|
||||
type Data map[string][]byte
|
||||
|
||||
// Finalize returns the final raw data slice and a map of labels with their respective indices.
|
||||
// It will try to reuse existing data whenever possible.
|
||||
func (data Data) Finalize() ([]byte, map[string]int32) {
|
||||
var (
|
||||
final []byte
|
||||
keys = make([]string, 0, len(data))
|
||||
positions = make(map[string]int32, len(data))
|
||||
)
|
||||
|
||||
for key := range data {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
|
||||
sort.SliceStable(keys, func(i, j int) bool {
|
||||
return len(data[keys[i]]) > len(data[keys[j]])
|
||||
})
|
||||
|
||||
for _, key := range keys {
|
||||
raw := data[key]
|
||||
position := bytes.Index(final, raw)
|
||||
|
||||
if position != -1 {
|
||||
positions[key] = int32(position)
|
||||
} else {
|
||||
positions[key] = int32(len(final))
|
||||
final = append(final, raw...)
|
||||
}
|
||||
}
|
||||
|
||||
return final, positions
|
||||
}
|
||||
|
||||
func (data Data) Insert(label string, raw []byte) {
|
||||
data[label] = raw
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue