From 850d0ff0e2203e3139e4423d73418a58eef1370e Mon Sep 17 00:00:00 2001 From: davidlion Date: Thu, 31 Oct 2024 12:21:51 -0400 Subject: [PATCH] Simplify writer by relying on the io.Writer for everything. --- ir/ir.go | 2 ++ ir/serializer.go | 13 ++++----- ir/writer.go | 64 +++++++------------------------------------- ir/writeread_test.go | 10 +++---- 4 files changed, 24 insertions(+), 65 deletions(-) diff --git a/ir/ir.go b/ir/ir.go index f7da79a..b55aec8 100644 --- a/ir/ir.go +++ b/ir/ir.go @@ -43,3 +43,5 @@ type LogMessage[T EightByteEncoding | FourByteEncoding] struct { type LogMessageView[T EightByteEncoding | FourByteEncoding] struct { LogMessage[T] } + +const FfiSuccess = 0 diff --git a/ir/serializer.go b/ir/serializer.go index f6e9773..eef9acc 100644 --- a/ir/serializer.go +++ b/ir/serializer.go @@ -7,6 +7,7 @@ package ir import "C" import ( + "syscall" "unsafe" "github.com/y-scope/clp-ffi-go/ffi" @@ -38,7 +39,7 @@ func EightByteSerializer() (Serializer, BufView, error) { if err := IrError(C.ir_serializer_eight_byte_create( &irs.cptr, &irView, - )); Success != err { + )); FfiSuccess != err { return nil, nil, err } return &irs, unsafe.Slice((*byte)(irView.m_data), irView.m_size), nil @@ -56,7 +57,7 @@ func FourByteSerializer() (Serializer, BufView, error) { if err := IrError(C.ir_serializer_four_byte_create( &irs.cptr, &irView, - )); Success != err { + )); FfiSuccess != err { return nil, nil, err } return &irs, unsafe.Slice((*byte)(irView.m_data), irView.m_size), nil @@ -158,23 +159,23 @@ func serializeMsgPackBytes( msgPackBytes []byte, ) (BufView, error) { var irView C.ByteSpan - var err error + var err syscall.Errno switch irs := serializer.(type) { case *eightByteSerializer: - err = IrError(C.ir_serializer_eight_byte_serialize_log_event( + err = syscall.Errno(C.ir_serializer_eight_byte_serialize_log_event( irs.cptr, newCByteSpan(msgPackBytes), &irView, )) case *fourByteSerializer: - err = IrError(C.ir_serializer_four_byte_serialize_log_event( + err = syscall.Errno(C.ir_serializer_four_byte_serialize_log_event( irs.cptr, newCByteSpan(msgPackBytes), &irView, )) } - if Success != err { + if FfiSuccess != err { return nil, err } return unsafe.Slice((*byte)(irView.m_data), irView.m_size), nil diff --git a/ir/writer.go b/ir/writer.go index e903c24..30f399d 100644 --- a/ir/writer.go +++ b/ir/writer.go @@ -1,7 +1,6 @@ package ir import ( - "bytes" "fmt" "io" @@ -13,17 +12,12 @@ import ( // the arguments used. Close must be called to free the underlying memory and // failure to do so will result in a memory leak. To write a complete IR stream // Close must be called before the final WriteTo call. +// buffer in ioWriter if necessary type Writer struct { Serializer - buf bytes.Buffer ioWriter io.Writer } -// Returns [NewWriterSize] with a FourByteEncoding Serializer using a buffer size of 1MB. -func NewWriter(ioWriter io.Writer) (*Writer, error) { - return NewWriterSize[FourByteEncoding](ioWriter, 1024*1024) -} - // NewWriterSize creates a new [Writer] with a [Serializer] based on T, and // writes a CLP IR preamble. The preamble is stored inside the Writer's internal // buffer to be written out later. The size parameter denotes the initial buffer @@ -31,13 +25,10 @@ func NewWriter(ioWriter io.Writer) (*Writer, error) { // - success: valid [*Writer], nil // - error: nil [*Writer], invalid type error or an error propagated from // [FourByteSerializer], [EightByteSerializer], or [bytes.Buffer.Write] -func NewWriterSize[T EightByteEncoding | FourByteEncoding]( +func NewWriter[T EightByteEncoding | FourByteEncoding]( ioWriter io.Writer, - size int, ) (*Writer, error) { var irw Writer - irw.buf.Grow(size) - var irView BufView var err error var t T @@ -52,10 +43,11 @@ func NewWriterSize[T EightByteEncoding | FourByteEncoding]( if nil != err { return nil, err } - _, err = irw.buf.Write(irView) + _, err = ioWriter.Write(irView) if nil != err { return nil, err } + irw.ioWriter = ioWriter return &irw, nil } @@ -63,34 +55,13 @@ func NewWriterSize[T EightByteEncoding | FourByteEncoding]( // underlying C++ allocated memory used by the serializer. Failure to call Close // will result in a memory leak. func (writer *Writer) Close() error { - writer.buf.WriteByte(0x0) + _, err := writer.ioWriter.Write([]byte{0x0}) + if nil != err { + return err + } return writer.Serializer.Close() } -// CloseTo is a combination of [Close] and [WriteTo]. It will completely close -// the Writer (and underlying serializer) and write the data out to the -// io.Writer. -// Returns: -// - success: number of bytes written, nil -// - error: number of bytes written, error propagated from [WriteTo] -func (writer *Writer) CloseTo(w io.Writer) (int64, error) { - writer.Close() - return writer.WriteTo(w) -} - -// Bytes returns a slice of the Writer's internal buffer. The slice is valid for -// use only until the next buffer modification (that is, only until the next -// call to Write, WriteTo, or Reset). -func (writer *Writer) Bytes() []byte { - return writer.buf.Bytes() -} - -// Reset resets the buffer to be empty, but it retains the underlying storage -// for use by future writes. -func (writer *Writer) Reset() { - writer.buf.Reset() -} - // Write uses [SerializeLogEvent] to serialize the provided log event to CLP IR // and then stores it in the internal buffer. Returns: // - success: number of bytes written, nil @@ -106,7 +77,7 @@ func (writer *Writer) WriteLogEvent(logEvent ffi.LogEvent) (int, error) { // Write can fail in the future, we should either: // 1. fix the issue and retry the write // 2. store irView and provide a retry API (allowing the user to fix the issue and retry) - n, err := writer.buf.Write(irView) + n, err := writer.ioWriter.Write(irView) if nil != err { return n, err } @@ -128,24 +99,9 @@ func (writer *Writer) WriteMsgPackBytes(msgPackBytes []byte) (int, error) { // Write can fail in the future, we should either: // 1. fix the issue and retry the write // 2. store irView and provide a retry API (allowing the user to fix the issue and retry) - n, err := writer.buf.Write(irView) + n, err := writer.ioWriter.Write(irView) if nil != err { return n, err } return n, nil } - -// WriteTo writes data to w until the buffer is drained or an error occurs. If -// no error occurs the buffer is reset. On an error the user is expected to use -// [writer.Bytes] and [writer.Reset] to manually handle the buffer's contents before -// continuing. Returns: -// - success: number of bytes written, nil -// - error: number of bytes written, error propagated from -// [bytes.Buffer.WriteTo] -func (writer *Writer) WriteTo(w io.Writer) (int64, error) { - n, err := writer.buf.WriteTo(w) - if nil == err { - writer.buf.Reset() - } - return n, err -} diff --git a/ir/writeread_test.go b/ir/writeread_test.go index 3e815d8..2d7814d 100644 --- a/ir/writeread_test.go +++ b/ir/writeread_test.go @@ -28,9 +28,9 @@ func testWriteReadLogMessages( } events = append(events, event) } - _, err := irWriter.CloseTo(ioWriter) + err := irWriter.Close() if nil != err { - t.Fatalf("ir.Writer.CloseTo failed: %v", err) + t.Fatalf("ir.Writer.Close failed: %v", err) } ioWriter.Close() @@ -57,14 +57,14 @@ func openIrWriter( var err error switch args.encoding { case eightByteEncoding: - irWriter, err = NewWriterSize[EightByteEncoding](writer, 1024*1024) + irWriter, err = NewWriter[EightByteEncoding](writer) case fourByteEncoding: - irWriter, err = NewWriterSize[FourByteEncoding](writer, 1024*1024) + irWriter, err = NewWriter[FourByteEncoding](writer) default: t.Fatalf("unsupported encoding: %v", args.encoding) } if nil != err { - t.Fatalf("NewWriterSize failed: %v", err) + t.Fatalf("NewWriter failed: %v", err) } return irWriter }