github.com/weaviate/weaviate@v1.24.6/adapters/repos/db/vector/hnsw/bufiowriter.go (about) 1 // _ _ 2 // __ _____ __ ___ ___ __ _| |_ ___ 3 // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \ 4 // \ V V / __/ (_| |\ V /| | (_| | || __/ 5 // \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___| 6 // 7 // Copyright © 2016 - 2024 Weaviate B.V. All rights reserved. 8 // 9 // CONTACT: hello@weaviate.io 10 // 11 12 package hnsw 13 14 import ( 15 "io" 16 "os" 17 "unicode/utf8" 18 ) 19 20 const ( 21 defaultBufSize = 4096 22 ) 23 24 // bufWriter implements buffering for an *os.File object. 25 // If an error occurs writing to a bufWriter, no more data will be 26 // accepted and all subsequent writes, and Flush, will return the error. 27 // After all data has been written, the client should call the 28 // Flush method to guarantee all data has been forwarded to 29 // the underlying *os.File. 30 type bufWriter struct { 31 err error 32 buf []byte 33 n int 34 wr *os.File 35 } 36 37 // NewWriterSize returns a new Writer whose buffer has at least the specified 38 // size. If the argument *os.File is already a Writer with large enough 39 // size, it returns the underlying Writer. 40 func NewWriterSize(w *os.File, size int) *bufWriter { 41 if size <= 0 { 42 size = defaultBufSize 43 } 44 return &bufWriter{ 45 buf: make([]byte, size), 46 wr: w, 47 } 48 } 49 50 // NewWriter returns a new Writer whose buffer has the default size. 51 func NewWriter(w *os.File) *bufWriter { 52 return NewWriterSize(w, defaultBufSize) 53 } 54 55 // Size returns the size of the underlying buffer in bytes. 56 func (b *bufWriter) Size() int { return len(b.buf) } 57 58 // Reset discards any unflushed buffered data, clears any error, and 59 // resets b to write its output to w. 60 func (b *bufWriter) Reset(w *os.File) { 61 b.err = nil 62 b.n = 0 63 b.wr = w 64 } 65 66 // Flush writes any buffered data to the underlying *os.File. 67 func (b *bufWriter) Flush() error { 68 if b.err != nil { 69 return b.err 70 } 71 if b.n == 0 { 72 return nil 73 } 74 n, err := b.wr.Write(b.buf[0:b.n]) 75 if n < b.n && err == nil { 76 err = io.ErrShortWrite 77 } 78 if err != nil { 79 if n > 0 && n < b.n { 80 copy(b.buf[0:b.n-n], b.buf[n:b.n]) 81 } 82 b.n -= n 83 b.err = err 84 return err 85 } 86 b.n = 0 87 return nil 88 } 89 90 // Available returns how many bytes are unused in the buffer. 91 func (b *bufWriter) Available() int { return len(b.buf) - b.n } 92 93 // Buffered returns the number of bytes that have been written into the current buffer. 94 func (b *bufWriter) Buffered() int { return b.n } 95 96 // Write writes the contents of p into the buffer. 97 // It returns the number of bytes written. 98 // If nn < len(p), it also returns an error explaining 99 // why the write is short. 100 func (b *bufWriter) Write(p []byte) (nn int, err error) { 101 for len(p) > b.Available() && b.err == nil { 102 var n int 103 if b.Buffered() == 0 { 104 // Large write, empty buffer. 105 // Write directly from p to avoid copy. 106 n, b.err = b.wr.Write(p) 107 } else { 108 n = copy(b.buf[b.n:], p) 109 b.n += n 110 b.Flush() 111 } 112 nn += n 113 p = p[n:] 114 } 115 if b.err != nil { 116 return nn, b.err 117 } 118 n := copy(b.buf[b.n:], p) 119 b.n += n 120 nn += n 121 return nn, nil 122 } 123 124 // WriteByte writes a single byte. 125 func (b *bufWriter) WriteByte(c byte) error { 126 if b.err != nil { 127 return b.err 128 } 129 if b.Available() <= 0 && b.Flush() != nil { 130 return b.err 131 } 132 b.buf[b.n] = c 133 b.n++ 134 return nil 135 } 136 137 // WriteRune writes a single Unicode code point, returning 138 // the number of bytes written and any error. 139 func (b *bufWriter) WriteRune(r rune) (size int, err error) { 140 if r < utf8.RuneSelf { 141 err = b.WriteByte(byte(r)) 142 if err != nil { 143 return 0, err 144 } 145 return 1, nil 146 } 147 if b.err != nil { 148 return 0, b.err 149 } 150 n := b.Available() 151 if n < utf8.UTFMax { 152 if b.Flush(); b.err != nil { 153 return 0, b.err 154 } 155 n = b.Available() 156 if n < utf8.UTFMax { 157 // Can only happen if buffer is silly small. 158 return b.WriteString(string(r)) 159 } 160 } 161 size = utf8.EncodeRune(b.buf[b.n:], r) 162 b.n += size 163 return size, nil 164 } 165 166 // WriteString writes a string. 167 // It returns the number of bytes written. 168 // If the count is less than len(s), it also returns an error explaining 169 // why the write is short. 170 func (b *bufWriter) WriteString(s string) (int, error) { 171 nn := 0 172 for len(s) > b.Available() && b.err == nil { 173 n := copy(b.buf[b.n:], s) 174 b.n += n 175 nn += n 176 s = s[n:] 177 b.Flush() 178 } 179 if b.err != nil { 180 return nn, b.err 181 } 182 n := copy(b.buf[b.n:], s) 183 b.n += n 184 nn += n 185 return nn, nil 186 }