44 "context"
55 "errors"
66 "fmt"
7+ "io"
78 "sync"
89 "time"
910
@@ -118,8 +119,8 @@ func (p *ConcurrentPatriciaHashed) foldNibble(ctx context.Context, nib int) erro
118119}
119120
120121func (p * ConcurrentPatriciaHashed ) unfoldRoot (ctx context.Context , ctxFactory TrieContextFactory ) error {
121- if p .root .trace {
122- fmt .Printf ( "=============ROOT unfold============\n " )
122+ if p .root .traceW != nil {
123+ fmt .Fprintf ( p . root . traceW , "=============ROOT unfold============\n " )
123124 }
124125 // if p.root.rootPresent && p.root.root.hashedExtLen == 0 { // if root has no extension, we have to unfold
125126 zero := []byte {0 }
@@ -133,8 +134,8 @@ func (p *ConcurrentPatriciaHashed) unfoldRoot(ctx context.Context, ctxFactory Tr
133134 }
134135 // }
135136
136- if p .root .trace {
137- fmt .Printf ( "=========END=ROOT unfold============\n " )
137+ if p .root .traceW != nil {
138+ fmt .Fprintf ( p . root . traceW , "=========END=ROOT unfold============\n " )
138139 }
139140
140141 for i := range p .mounts {
@@ -159,36 +160,41 @@ func (p *ConcurrentPatriciaHashed) Close() {
159160 }
160161}
161162
162- func (p * ConcurrentPatriciaHashed ) SetTrace (b bool ) {
163- p .root .SetTrace (b )
164- for i := range p .mounts {
165- p .mounts [i ].SetTrace (b )
166- }
163+ // syncWriter wraps an io.Writer with a mutex for goroutine-safe writes.
164+ // Used by ConcurrentPatriciaHashed to protect concurrent fmt.Fprintf calls
165+ // from root and mount goroutines writing to the same underlying writer.
166+ type syncWriter struct {
167+ mu sync.Mutex
168+ w io.Writer
167169}
168- func (p * ConcurrentPatriciaHashed ) SetTraceDomain (b bool ) {
169- p .root .SetTraceDomain (b )
170- for i := range p .mounts {
171- p .mounts [i ].SetTraceDomain (b )
172- }
170+
171+ func (sw * syncWriter ) Write (p []byte ) (n int , err error ) {
172+ sw .mu .Lock ()
173+ n , err = sw .w .Write (p )
174+ sw .mu .Unlock ()
175+ return
173176}
174177
175- func (p * ConcurrentPatriciaHashed ) GetCapture (truncate bool ) []string {
176- capture := p .root .GetCapture (truncate )
177- if truncate {
178+ func (p * ConcurrentPatriciaHashed ) SetTraceWriter (w io.Writer ) {
179+ if w != nil {
180+ sw := & syncWriter {w : w }
181+ p .root .SetTraceWriter (sw )
178182 for i := range p .mounts {
179- p .mounts [i ].SetCapture (nil )
183+ p .mounts [i ].SetTraceWriter (sw )
184+ }
185+ } else {
186+ p .root .SetTraceWriter (nil )
187+ for i := range p .mounts {
188+ p .mounts [i ].SetTraceWriter (nil )
180189 }
181190 }
182- return capture
183191}
184-
185- func (p * ConcurrentPatriciaHashed ) SetCapture (capture []string ) {
186- p .root .SetCapture (capture )
192+ func (p * ConcurrentPatriciaHashed ) SetTraceDomain (b bool ) {
193+ p .root .SetTraceDomain (b )
187194 for i := range p .mounts {
188- p .mounts [i ].SetCapture ( capture )
195+ p .mounts [i ].SetTraceDomain ( b )
189196 }
190197}
191-
192198func (p * ConcurrentPatriciaHashed ) EnableCsvMetrics (filePathPrefix string ) {
193199 p .root .EnableCsvMetrics (filePathPrefix )
194200 for i := range p .mounts {
@@ -199,10 +205,18 @@ func (p *ConcurrentPatriciaHashed) EnableCsvMetrics(filePathPrefix string) {
199205}
200206
201207// pass -1 to enable trace just for root trie
202- func (p * ConcurrentPatriciaHashed ) SetParticularTrace (b bool , n int ) {
203- p .root .SetTrace (b )
204- if n < len (p .mounts ) && n >= 0 {
205- p .mounts [n ].SetTrace (b )
208+ func (p * ConcurrentPatriciaHashed ) SetParticularTrace (w io.Writer , n int ) {
209+ if w != nil {
210+ sw := & syncWriter {w : w }
211+ p .root .SetTraceWriter (sw )
212+ if n < len (p .mounts ) && n >= 0 {
213+ p .mounts [n ].SetTraceWriter (sw )
214+ }
215+ } else {
216+ p .root .SetTraceWriter (nil )
217+ if n < len (p .mounts ) && n >= 0 {
218+ p .mounts [n ].SetTraceWriter (nil )
219+ }
206220 }
207221}
208222
@@ -245,8 +259,8 @@ func (t *Updates) ParallelHashSort(ctx context.Context, pph *ConcurrentPatriciaH
245259 cnt := 0
246260 err := nib .Load (nil , "" , func (hashedKey , plainKey []byte , table etl.CurrentTableReader , next etl.LoadNextFunc ) error {
247261 cnt ++
248- if phnib .trace {
249- fmt .Printf ( "\n %x) %d plainKey [%x] hashedKey [%x] currentKey [%x]\n " , ni , cnt , plainKey , hashedKey , phnib .currentKey [:phnib .currentKeyLen ])
262+ if phnib .traceW != nil {
263+ fmt .Fprintf ( phnib . traceW , "\n %x) %d plainKey [%x] hashedKey [%x] currentKey [%x]\n " , ni , cnt , plainKey , hashedKey , phnib .currentKey [:phnib .currentKeyLen ])
250264 }
251265 if err := phnib .followAndUpdate (hashedKey , plainKey , nil ); err != nil {
252266 return fmt .Errorf ("followAndUpdate[%x]: %w" , ni , err )
@@ -259,8 +273,8 @@ func (t *Updates) ParallelHashSort(ctx context.Context, pph *ConcurrentPatriciaH
259273 if cnt == 0 {
260274 return nil
261275 }
262- if pph .mounts [ni ].trace {
263- fmt .Printf ( "ConcurrentTrie: folding [%2x] keys %d maxDepth %d\n " , ni , cnt , phnib .depths [0 ])
276+ if pph .mounts [ni ].traceW != nil {
277+ fmt .Fprintf ( pph . mounts [ ni ]. traceW , "ConcurrentTrie: folding [%2x] keys %d maxDepth %d\n " , ni , cnt , phnib .depths [0 ])
264278 }
265279 return pph .foldNibble (gctx , ni )
266280 })
@@ -269,8 +283,8 @@ func (t *Updates) ParallelHashSort(ctx context.Context, pph *ConcurrentPatriciaH
269283 return nil , err
270284 }
271285
272- if pph .root .trace {
273- fmt .Printf ( "======= folding ROOT trie =========\n " )
286+ if pph .root .traceW != nil {
287+ fmt .Fprintf ( pph . root . traceW , "======= folding ROOT trie =========\n " )
274288 }
275289 // TODO zero active rows could be a clue to some invalid cases
276290 if pph .root .activeRows == 0 {
@@ -289,8 +303,8 @@ func (t *Updates) ParallelHashSort(ctx context.Context, pph *ConcurrentPatriciaH
289303 if err != nil {
290304 return nil , err
291305 }
292- if pph .root .trace {
293- fmt .Printf ( "======= folding root done =========\n " )
306+ if pph .root .traceW != nil {
307+ fmt .Fprintf ( pph . root . traceW , "======= folding root done =========\n " )
294308 }
295309 // have to reset trie since we do not do any unfolding
296310 return rootHash , nil
0 commit comments