@@ -3,8 +3,9 @@ package main
33import (
44 "encoding/csv"
55 "fmt"
6- "os "
6+ "io "
77 "reflect"
8+ "sort"
89 "strings"
910
1011 "github.com/samber/lo"
@@ -47,6 +48,13 @@ func collect() []DocContent {
4748 return result
4849}
4950
51+ func quoteIfNeeded (s string ) string {
52+ if strings .ContainsAny (s , "[],{}" ) {
53+ return fmt .Sprintf ("\" %s\" " , s )
54+ }
55+ return s
56+ }
57+
5058func collectRecursive (params * paramtable.ComponentParam , data * []DocContent , val * reflect.Value ) {
5159 if val .Kind () != reflect .Struct {
5260 return
@@ -63,27 +71,34 @@ func collectRecursive(params *paramtable.ComponentParam, data *[]DocContent, val
6371 log .Debug ("got key" , zap .String ("key" , item .Key ), zap .Any ("value" , defaultValue ), zap .String ("variable" , val .Type ().Field (j ).Name ))
6472 * data = append (* data , DocContent {item .Key , defaultValue , item .Version , refreshable , item .Export , item .Doc })
6573 for _ , fk := range item .FallbackKeys {
74+ defaultValue = params .GetWithDefault (fk , item .DefaultValue )
6675 log .Debug ("got fallback key" , zap .String ("key" , fk ), zap .Any ("value" , defaultValue ), zap .String ("variable" , val .Type ().Field (j ).Name ))
6776 * data = append (* data , DocContent {fk , defaultValue , item .Version , refreshable , item .Export , item .Doc })
6877 }
6978 } else if t == "paramtable.ParamGroup" {
7079 item := subVal .Interface ().(paramtable.ParamGroup )
7180 log .Debug ("got key" , zap .String ("key" , item .KeyPrefix ), zap .String ("variable" , val .Type ().Field (j ).Name ))
7281 refreshable := tag .Get ("refreshable" )
73- * data = append (* data , DocContent {item .KeyPrefix , "" , item .Version , refreshable , item .Export , item .Doc })
82+
83+ // Sort group items to stablize the output order
84+ m := item .GetValue ()
85+ keys := make ([]string , 0 , len (m ))
86+ for k := range m {
87+ keys = append (keys , k )
88+ }
89+ sort .Strings (keys )
90+ for _ , key := range keys {
91+ value := m [key ]
92+ log .Debug ("got group entry" , zap .String ("key" , key ), zap .String ("value" , value ))
93+ * data = append (* data , DocContent {fmt .Sprintf ("%s%s" , item .KeyPrefix , key ), quoteIfNeeded (value ), item .Version , refreshable , item .Export , "" })
94+ }
7495 } else {
7596 collectRecursive (params , data , & subVal )
7697 }
7798 }
7899}
79100
80- func WriteCsv () {
81- f , err := os .Create ("configs.csv" )
82- defer f .Close ()
83- if err != nil {
84- log .Error ("create file failed" , zap .Error (err ))
85- os .Exit (- 2 )
86- }
101+ func WriteCsv (f io.Writer ) {
87102 w := csv .NewWriter (f )
88103 w .Write ([]string {"key" , "defaultValue" , "sinceVersion" , "refreshable" , "exportToUser" , "comment" })
89104
@@ -101,7 +116,7 @@ type YamlGroup struct {
101116}
102117
103118type YamlMarshaller struct {
104- writer * os. File
119+ writer io. Writer
105120 groups []YamlGroup
106121 data []DocContent
107122}
@@ -142,19 +157,19 @@ func (m *YamlMarshaller) writeYamlRecursive(data []DocContent, level int) {
142157 isDisabled := slices .Contains (disabledGroups , strings .Split (content .key , "." )[0 ])
143158 if strings .Count (content .key , "." ) == level {
144159 if isDisabled {
145- m . writer . WriteString ("# " )
160+ io . WriteString (m . writer , "# " )
146161 }
147162 m .writeContent (key , content .defaultValue , content .comment , level )
148163 continue
149164 }
150165 extra , ok := extraHeaders [key ]
151166 if ok {
152- m . writer . WriteString (extra + "\n " )
167+ io . WriteString (m . writer , extra + "\n " )
153168 }
154169 if isDisabled {
155- m . writer . WriteString ("# " )
170+ io . WriteString (m . writer , "# " )
156171 }
157- m . writer . WriteString (fmt .Sprintf ("%s%s:\n " , strings .Repeat (" " , level * 2 ), key ))
172+ io . WriteString (m . writer , fmt .Sprintf ("%s%s:\n " , strings .Repeat (" " , level * 2 ), key ))
158173 m .writeYamlRecursive (contents , level + 1 )
159174 }
160175}
@@ -163,27 +178,20 @@ func (m *YamlMarshaller) writeContent(key, value, comment string, level int) {
163178 if strings .Contains (comment , "\n " ) {
164179 multilines := strings .Split (comment , "\n " )
165180 for _ , line := range multilines {
166- m . writer . WriteString (fmt .Sprintf ("%s# %s\n " , strings .Repeat (" " , level * 2 ), line ))
181+ io . WriteString (m . writer , fmt .Sprintf ("%s# %s\n " , strings .Repeat (" " , level * 2 ), line ))
167182 }
168- m . writer . WriteString (fmt .Sprintf ("%s%s: %s\n " , strings .Repeat (" " , level * 2 ), key , value ))
183+ io . WriteString (m . writer , fmt .Sprintf ("%s%s: %s\n " , strings .Repeat (" " , level * 2 ), key , value ))
169184 } else if comment != "" {
170- m . writer . WriteString (fmt .Sprintf ("%s%s: %s # %s\n " , strings .Repeat (" " , level * 2 ), key , value , comment ))
185+ io . WriteString (m . writer , fmt .Sprintf ("%s%s: %s # %s\n " , strings .Repeat (" " , level * 2 ), key , value , comment ))
171186 } else {
172- m . writer . WriteString (fmt .Sprintf ("%s%s: %s\n " , strings .Repeat (" " , level * 2 ), key , value ))
187+ io . WriteString (m . writer , fmt .Sprintf ("%s%s: %s\n " , strings .Repeat (" " , level * 2 ), key , value ))
173188 }
174189}
175190
176- func WriteYaml () {
177- f , err := os .Create ("milvus.yaml" )
178- defer f .Close ()
179- if err != nil {
180- log .Error ("create file failed" , zap .Error (err ))
181- os .Exit (- 2 )
182- }
183-
191+ func WriteYaml (w io.Writer ) {
184192 result := collect ()
185193
186- f .WriteString (`# Licensed to the LF AI & Data foundation under one
194+ io .WriteString (w , `# Licensed to the LF AI & Data foundation under one
187195# or more contributor license agreements. See the NOTICE file
188196# distributed with this work for additional information
189197# regarding copyright ownership. The ASF licenses this file
@@ -207,6 +215,13 @@ func WriteYaml() {
207215 {
208216 name : "metastore" ,
209217 },
218+ {
219+ name : "tikv" ,
220+ header : `
221+ # Related configuration of tikv, used to store Milvus metadata.
222+ # Notice that when TiKV is enabled for metastore, you still need to have etcd for service discovery.
223+ # TiKV is a good option when the metadata size requires better horizontal scalability.` ,
224+ },
210225 {
211226 name : "localStorage" ,
212227 },
@@ -215,15 +230,19 @@ func WriteYaml() {
215230 header : `
216231# Related configuration of MinIO/S3/GCS or any other service supports S3 API, which is responsible for data persistence for Milvus.
217232# We refer to the storage service as MinIO/S3 in the following description for simplicity.` ,
233+ },
234+ {
235+ name : "mq" ,
236+ header : `
237+ # Milvus supports four MQ: rocksmq(based on RockDB), natsmq(embedded nats-server), Pulsar and Kafka.
238+ # You can change your mq by setting mq.type field.
239+ # If you don't set mq.type field as default, there is a note about enabling priority if we config multiple mq in this file.
240+ # 1. standalone(local) mode: rocksmq(default) > natsmq > Pulsar > Kafka
241+ # 2. cluster mode: Pulsar(default) > Kafka (rocksmq and natsmq is unsupported in cluster mode)` ,
218242 },
219243 {
220244 name : "pulsar" ,
221245 header : `
222- # Milvus supports three MQ: rocksmq(based on RockDB), Pulsar and Kafka, which should be reserved in config what you use.
223- # There is a note about enabling priority if we config multiple mq in this file
224- # 1. standalone(local) mode: rocksmq(default) > Pulsar > Kafka
225- # 2. cluster mode: Pulsar(default) > Kafka (rocksmq is unsupported)
226-
227246# Related configuration of pulsar, used to manage Milvus logs of recent mutation operations, output streaming log, and provide log publish-subscribe services.` ,
228247 },
229248 {
@@ -234,6 +253,12 @@ func WriteYaml() {
234253 {
235254 name : "rocksmq" ,
236255 },
256+ {
257+ name : "natsmq" ,
258+ header : `
259+ # natsmq configuration.
260+ # more detail: https://docs.nats.io/running-a-nats-service/configuration` ,
261+ },
237262 {
238263 name : "rootCoord" ,
239264 header : "\n # Related configuration of rootCoord, used to handle data definition language (DDL) and data control language (DCL) requests" ,
@@ -294,8 +319,18 @@ func WriteYaml() {
294319 {
295320 name : "trace" ,
296321 },
322+ {
323+ name : "gpu" ,
324+ header : `
325+ #when using GPU indexing, Milvus will utilize a memory pool to avoid frequent memory allocation and deallocation.
326+ #here, you can set the size of the memory occupied by the memory pool, with the unit being MB.
327+ #note that there is a possibility of Milvus crashing when the actual memory demand exceeds the value set by maxMemSize.
328+ #if initMemSize and MaxMemSize both set zero,
329+ #milvus will automatically initialize half of the available GPU memory,
330+ #maxMemSize will the whole available GPU memory.` ,
331+ },
297332 }
298- marshller := YamlMarshaller {f , groups , result }
333+ marshller := YamlMarshaller {w , groups , result }
299334 marshller .writeYamlRecursive (lo .Filter (result , func (d DocContent , _ int ) bool {
300335 return d .exportToUser
301336 }), 0 )
0 commit comments