Skip to content

Commit 6bfa1ba

Browse files
author
Gusted
committed
Move back to data structure
- Uses less memory by creating for each language a map.
1 parent 957207b commit 6bfa1ba

File tree

1 file changed

+54
-19
lines changed

1 file changed

+54
-19
lines changed

modules/translation/i18n/i18n.go

+54-19
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,22 @@ type locale struct {
3030

3131
type LocaleStore struct {
3232
// After initializing has finished, these fields are read-only.
33-
langNames []string
34-
langDescs []string
35-
langOffsets []int
36-
offsetToTranslationMap []map[string]string
37-
localeMap map[string]*locale
38-
defaultLang string
33+
langNames []string
34+
langDescs []string
35+
36+
langOffsets []int
37+
translationKeys []string
38+
keyToOffset map[string]int
39+
translationValues []string
40+
41+
localeMap map[string]*locale
42+
43+
defaultLang string
44+
defaultLangKeysLen int
3945
}
4046

4147
func NewLocaleStore() *LocaleStore {
42-
return &LocaleStore{localeMap: make(map[string]*locale)}
48+
return &LocaleStore{localeMap: make(map[string]*locale), keyToOffset: make(map[string]int)}
4349
}
4450

4551
// AddLocaleByIni adds locale by ini into the store
@@ -63,15 +69,44 @@ func (ls *LocaleStore) AddLocaleByIni(langName, langDesc string, localeFile inte
6369
// For development, live-reload of the translation files is important.
6470
// For production, we can do some expensive work and then make the querying fast.
6571
if setting.IsProd {
66-
keyToValue := map[string]string{}
67-
// Go trough all keys and store key->value into a map.
68-
for _, section := range iniFile.Sections() {
69-
for _, key := range section.Keys() {
70-
keyToValue[strings.TrimPrefix(section.Name()+"."+key.Name(), "DEFAULT.")] = key.Value()
72+
// If the language is the default language, then we go trough all keys. These keys
73+
// will become the keys that we consider to support and take into account while going
74+
// trough querying translation keys.
75+
if langName == ls.defaultLang {
76+
idx := 0
77+
// Store all key, value into two slices.
78+
for _, section := range iniFile.Sections() {
79+
for _, key := range section.Keys() {
80+
ls.translationKeys = append(ls.translationKeys, section.Name()+"#"+key.Name())
81+
ls.translationValues = append(ls.translationValues, key.Value())
82+
83+
ls.keyToOffset[strings.TrimPrefix(section.Name()+"."+key.Name(), "DEFAULT.")] = idx
84+
idx++
85+
}
86+
}
87+
88+
ls.defaultLangKeysLen = len(ls.translationKeys)
89+
} else {
90+
// Go trough all the keys that the defaultLang has and append it to translationValues.
91+
// If the lang doesn't have a value for the translation, use the defaultLang's one.
92+
for i := 0; i < ls.defaultLangKeysLen; i++ {
93+
splitted := strings.SplitN(ls.translationKeys[i], "#", 2)
94+
// TODO: optimize for repeated sequential access of section.
95+
section, err := iniFile.GetSection(splitted[0])
96+
if err != nil {
97+
// Section not found? Use the defaultLang's value for this translation key.
98+
ls.translationValues = append(ls.translationValues, ls.translationValues[i])
99+
continue
100+
}
101+
key, err := section.GetKey(splitted[1])
102+
if err != nil {
103+
// Key not found? Use the defaultLang's value for this translation key.
104+
ls.translationValues = append(ls.translationValues, ls.translationValues[i])
105+
continue
106+
}
107+
ls.translationValues = append(ls.translationValues, key.Value())
71108
}
72109
}
73-
// Append the key->value to the offsetToTranslationMap variable.
74-
ls.offsetToTranslationMap = append(ls.offsetToTranslationMap, keyToValue)
75110

76111
// Help Go's GC.
77112
iniFile = nil
@@ -175,12 +210,12 @@ func Tr(lang, trKey string, trArgs ...interface{}) string {
175210
}
176211

177212
func TrOffset(offset int, trKey string, trArgs ...interface{}) string {
178-
languageTranslationMap := DefaultLocales.offsetToTranslationMap[offset]
179-
trMsg, ok := languageTranslationMap[trKey]
180-
if !ok {
181-
return trKey
182-
}
213+
// Get the offset of the translation key.
214+
keyOffset := DefaultLocales.keyToOffset[trKey]
215+
// Now adjust to use the language's translation of the key.
216+
keyOffset += offset * DefaultLocales.defaultLangKeysLen
183217

218+
trMsg := DefaultLocales.translationValues[keyOffset]
184219
if len(trArgs) > 0 {
185220
fmtArgs := make([]interface{}, 0, len(trArgs))
186221
for _, arg := range trArgs {

0 commit comments

Comments
 (0)