Copy creates and returns a copy of the current log line.
()
| 236 | |
| 237 | // Copy creates and returns a copy of the current log line. |
| 238 | func (l *LogLine) Copy() Record { |
| 239 | // Copy metadata. |
| 240 | md := make(Metadata) |
| 241 | for k, v := range l.meta { |
| 242 | md[k] = v |
| 243 | } |
| 244 | |
| 245 | cpy := &LogLine{ |
| 246 | cache: l.cache, |
| 247 | meta: md, |
| 248 | FieldSeparator: l.FieldSeparator, |
| 249 | } |
| 250 | |
| 251 | if l.wcnt != 0 { |
| 252 | // If the log line has been modified, benchmarks have proven that it's |
| 253 | // more efficient to serialize and reparse to perform a copy (both in |
| 254 | // terms of time and allocation). Also, different benchmarks have shown |
| 255 | // that pre-allocating 120% of the original log line length in order to |
| 256 | // account for the potentially added fields is reasonable. |
| 257 | cpylen := len(l.data) + len(l.data)/5 |
| 258 | text := l.ToText(make([]byte, 0, cpylen)) |
| 259 | cpy.Parse(text, md) |
| 260 | |
| 261 | // Copy custom fields if necessary. |
| 262 | for i := LogLineNumFields; i < LogLineNumFields+NumFieldsBaker; i++ { |
| 263 | if fbuf := l.Get(i); fbuf != nil { |
| 264 | fcpy := make([]byte, len(fbuf)) |
| 265 | copy(fcpy, fbuf) |
| 266 | cpy.Set(i, fcpy) |
| 267 | } |
| 268 | } |
| 269 | return cpy |
| 270 | } |
| 271 | |
| 272 | // If the log line hasn't been modified it's more efficient to recreate it |
| 273 | // from scratch and copying data (log line internal buffer). |
| 274 | if l.data != nil { |
| 275 | cpy.data = make([]byte, len(l.data)) |
| 276 | copy(cpy.data, l.data) |
| 277 | cpy.idx = l.idx |
| 278 | } |
| 279 | return cpy |
| 280 | } |