2025-12-31 15:45:25 +00:00
|
|
|
package node
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"bytes"
|
|
|
|
|
"encoding/json"
|
|
|
|
|
"sync"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// bufferPool provides reusable byte buffers for JSON encoding.
|
|
|
|
|
// This reduces allocation overhead in hot paths like message serialization.
|
|
|
|
|
var bufferPool = sync.Pool{
|
|
|
|
|
New: func() interface{} {
|
|
|
|
|
return bytes.NewBuffer(make([]byte, 0, 1024))
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-02 10:02:11 +01:00
|
|
|
// buffer := getBuffer()
|
|
|
|
|
// defer putBuffer(buffer)
|
2025-12-31 15:45:25 +00:00
|
|
|
func getBuffer() *bytes.Buffer {
|
2026-04-02 10:02:11 +01:00
|
|
|
buffer := bufferPool.Get().(*bytes.Buffer)
|
|
|
|
|
buffer.Reset()
|
|
|
|
|
return buffer
|
2025-12-31 15:45:25 +00:00
|
|
|
}
|
|
|
|
|
|
2026-04-02 10:02:11 +01:00
|
|
|
// putBuffer(buffer) // always called via defer after getBuffer()
|
|
|
|
|
func putBuffer(buffer *bytes.Buffer) {
|
2025-12-31 15:45:25 +00:00
|
|
|
// Don't pool buffers that grew too large (>64KB)
|
2026-04-02 10:02:11 +01:00
|
|
|
if buffer.Cap() <= 65536 {
|
|
|
|
|
bufferPool.Put(buffer)
|
2025-12-31 15:45:25 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-02 07:59:37 +01:00
|
|
|
// data, err := MarshalJSON(msg)
|
|
|
|
|
// if err != nil { return nil, err }
|
2025-12-31 15:45:25 +00:00
|
|
|
func MarshalJSON(v interface{}) ([]byte, error) {
|
2026-04-02 10:02:11 +01:00
|
|
|
buffer := getBuffer()
|
|
|
|
|
defer putBuffer(buffer)
|
2025-12-31 15:45:25 +00:00
|
|
|
|
2026-04-02 10:02:11 +01:00
|
|
|
encoder := json.NewEncoder(buffer)
|
2025-12-31 15:45:25 +00:00
|
|
|
// Don't escape HTML characters (matches json.Marshal behavior for these use cases)
|
2026-04-02 10:02:11 +01:00
|
|
|
encoder.SetEscapeHTML(false)
|
|
|
|
|
if err := encoder.Encode(v); err != nil {
|
2025-12-31 15:45:25 +00:00
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// json.Encoder.Encode adds a newline; remove it to match json.Marshal
|
2026-04-02 10:02:11 +01:00
|
|
|
data := buffer.Bytes()
|
2025-12-31 15:45:25 +00:00
|
|
|
if len(data) > 0 && data[len(data)-1] == '\n' {
|
|
|
|
|
data = data[:len(data)-1]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Return a copy since the buffer will be reused
|
|
|
|
|
result := make([]byte, len(data))
|
|
|
|
|
copy(result, data)
|
|
|
|
|
return result, nil
|
|
|
|
|
}
|