github.com/erda-project/erda-infra@v1.0.10-0.20240327085753-f3a249292aeb/pkg/parallel-writer/buffer.go (about) 1 // Copyright (c) 2021 Terminus, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package writer 16 17 import ( 18 "github.com/recallsong/go-utils/errorx" 19 ) 20 21 // Buffer . 22 type Buffer struct { 23 w Writer 24 buf []interface{} 25 maxSize int 26 } 27 28 // NewBuffer . 29 func NewBuffer(w Writer, max int) *Buffer { 30 return &Buffer{ 31 w: w, 32 buf: make([]interface{}, 0, max), 33 maxSize: max, 34 } 35 } 36 37 // Write . 38 func (b *Buffer) Write(data interface{}) error { 39 if len(b.buf)+1 > b.maxSize { 40 err := b.Flush() 41 if err != nil { 42 return err 43 } 44 } 45 b.buf = append(b.buf, data) 46 return nil 47 } 48 49 // WriteN returns the number of buffers written to the data. 50 // if a Flush error occurs, the error will be returned 51 func (b *Buffer) WriteN(data ...interface{}) (int, error) { 52 alen := len(b.buf) 53 blen := len(data) 54 if alen+blen < b.maxSize { 55 b.buf = append(b.buf, data...) 56 return blen, nil 57 } 58 writes := 0 59 if alen >= b.maxSize { 60 // never reached 61 err := b.Flush() 62 if err != nil { 63 return 0, nil 64 } 65 } else if alen > 0 { 66 writes = b.maxSize - alen 67 b.buf = append(b.buf, data[0:writes]...) 68 err := b.Flush() 69 if err != nil { 70 return writes, err 71 } 72 data = data[writes:] 73 blen -= writes 74 } 75 for blen > b.maxSize { 76 b.buf = append(b.buf, data[0:b.maxSize]...) 77 writes += b.maxSize 78 err := b.Flush() 79 if err != nil { 80 return writes, err 81 } 82 data = data[b.maxSize:] 83 blen -= b.maxSize 84 } 85 if blen > 0 { 86 b.buf = append(b.buf, data...) 87 writes += blen 88 } 89 return writes, nil 90 } 91 92 // Flush . 93 func (b *Buffer) Flush() error { 94 l := len(b.buf) 95 if l > 0 { 96 n, err := b.w.WriteN(b.buf...) 97 b.buf = b.buf[0 : l-n] 98 if err != nil { 99 return err 100 } 101 } 102 return nil 103 } 104 105 // Size . 106 func (b *Buffer) Size() int { 107 return len(b.buf) 108 } 109 110 // Data . 111 func (b *Buffer) Data() []interface{} { 112 return b.buf 113 } 114 115 // Close . 116 func (b *Buffer) Close() error { 117 return errorx.NewMultiError(b.Flush(), b.w.Close()).MaybeUnwrap() 118 }